my aim is to write a file to the current cursor position, and i've managed to do it for "child" windows, but it some cases it doesn't work.. ( and in all cases it over-rites current data in the area ) so i'm hoping there is a solution...

the process i am using is setting up a hot-key, then upon execution of the hotkey, grab the x,y call ChildWindowFromPoint, then read in file, sendmessage WM_SETTEXT...


is there a way to simply send a string to the current cursor pos? is an option to use WM_CHAR ?, i tried it and it didn't do anything, below is the code bit:



invoke GetForegroundWindow
mov hwnd_tmp, eax

invoke GetCaretPos, addr pt

push dword ptr pt
push hwnd_tmp
call WindowFromPoint
mov hwnd_tmp, eax

invoke MapVirtualKey, VK_A, 0
invoke SendMessage, hwnd_tmp, WM_CHAR, VK_A, eax


i really appreciate any help...
Posted on 2003-03-27 04:55:21 by abc123
Is the control you are looking to replace the text in an edit control ? in that case use EM_REPLACESEL and other EM messages. The EditStreamCallback functions are primarily designed for using data streams in conjuction with rich edit controls as well.
Posted on 2003-03-27 05:51:46 by donkey
hmm, that worked the same as WM_SETTEXT in that it still doesn't work for the area i'm aiming at... perhaps i'm grabbing the window incorrectly...

i'm sending the message to the window i'd get from this call:



invoke GetForegroundWindow
mov hwnd_tmp, eax

invoke GetCaretPos, addr pt

push dword ptr pt
push hwnd_tmp
call ChildWindowFromPoint
mov hwnd_tmp, eax


on a similar note, i can't seem to get keybd_event to work exactly either, this is my code for that:



invoke MapVirtualKey, VK_A, 0
invoke keybd_event, VK_A, eax, 0, 0
invoke keybd_event, VK_A, eax, KEYEVENTF_KEYUP, 0


i.e. key_down event and key_up events, but it doesn't seem to work appropriately.. is that the write way to call it? ( i also tried without that call to mapVirtualKey, and where "eax", i had "0".

...
Posted on 2003-03-29 01:31:06 by abc123
Ensure the cursor is at the location you want to insert the text then do a selection replace.

Do this with the EM_REPLACESEL sent with SendMessage, set the wParam flag to the value you want and the lParam parameter is the address of the zero terminated string you want to place there.

Regards,

hutch@movsd.com
Posted on 2003-03-29 03:27:11 by hutch--

Ensure the cursor is at the location you want to insert the text then do a selection replace.

Do this with the EM_REPLACESEL sent with SendMessage, set the wParam flag to the value you want and the lParam parameter is the address of the zero terminated string you want to place there.

Regards,

hutch@movsd.com



... yes, thats what donkey said and thats what I did and it didn't work for all text areas ... as I suggested, perhaps it was a problem with the way i was getting the window, the caret was definately in the right position.
Posted on 2003-03-29 04:17:59 by abc123
abc123,

What exactly are you trying to send the text to, a window, an edit control or a rich edit control ?

The data that Donkey and I passed you was for a rich edit control and it works fine there. Let us know what you are trying to do and we may be able to help you some more.

Regards,

hutch@movsd.com
Posted on 2003-03-29 05:57:56 by hutch--
Posted on 2003-03-29 06:06:48 by Vortex

abc123,

What exactly are you trying to send the text to, a window, an edit control or a rich edit control ?

The data that Donkey and I passed you was for a rich edit control and it works fine there. Let us know what you are trying to do and we may be able to help you some more.

Regards,

hutch@movsd.com



hutch, ideally i'm trying to send text to the current caret position ( hence trying to use keybd_event ) but currently it won't send to the textpad4 editing window, i don't know what type of control it is but it doesn't seem to respond in any way to those messages...
Posted on 2003-03-29 15:55:51 by abc123
Why not just copy the text to the clipboard then send a WM_PASTE message ?
Posted on 2003-03-29 16:12:15 by donkey

Why not just copy the text to the clipboard then send a WM_PASTE message ?


i want to conserve the clipboard :) ... i guess the solution is keybd_event, but i couldn't get it to work...
Posted on 2003-03-29 16:14:49 by abc123
Good idea Donkey.

I would also suggest saving the contents of the clipboard beforehand and restoring them when you're done too.
Posted on 2003-03-29 16:14:56 by iblis

Good idea Donkey.

I would also suggest saving the contents of the clipboard beforehand and restoring them when you're done too.


hmm, that would work pretty well then.. how would i go about doing that ...
Posted on 2003-03-29 16:19:31 by abc123
infact this window doesn't even respond to WM_PASTE so i'm probably not finding it correctly..

this is the way im trying to find it:



;pt is local POINT
;hwnd_tmp is DWORD
invoke GetForegroundWindow
mov hwnd_tmp, eax

invoke GetCaretPos, addr pt

push dword ptr pt
push hwnd_tmp
call ChildWindowFromPoint
mov hwnd_tmp, eax ; supposed to now have current edit box area address...
Posted on 2003-03-29 16:25:48 by abc123
I may be wrong here as I haven't tried it but this is the way it looks to me. The GetCaretPos function returns the current position of the caret in client coordinates of the edit control. So if you had an edit control at pos 100,100 and the caret was at position 0 it would return 0,0. You attempt to get the handle of the child window using the main window as the reference window but using client coordinates from the edit child window. This would inevitably give the wrong or no window handle.
Posted on 2003-03-29 16:36:50 by donkey
mm, that does seem to be about right :)


Remarks

The caret position is always given in the client coordinates of the window that contains the caret.


so i guess then the question is how do i get the handle im looking for ? :)
Posted on 2003-03-29 16:54:15 by abc123
This is how MSDN says the Keyboard focus should be examined :
From MSDN GetFocus Function

Even if GetFocus returns NULL, another thread's queue may be associated with a window that has the keyboard focus.

Use the GetForegroundWindow function to retrieve the handle to the window with which the user is currently working. You can associate your thread's message queue with the windows owned by another thread by using the AttachThreadInput function.
Posted on 2003-03-29 16:55:26 by donkey
sorry donkey, i don't particularly know what to do with that, i'm still new to assembly... i'm using GetForegroundWindow already...

how would AttachThreadInput help ....
Posted on 2003-03-29 17:19:37 by abc123
I am assuming that you are trying to send text to a window that is not part of your program. You can't get the handle of the window that has the keyboard focus from another thread. Each thread has it's own caret position and focus states and they are asynchronous so they cannot be exchanged between threads. The reason you attach the threads is to synchronize the two threads and give both a single focus, this will allow you to use GetFocus in order to find the window handle with the keyboard focus. It goes something like this:
invoke GetForegroundWindow

mov hTempWin,eax
; obtain the pID of the external window
invoke GetWindowThreadProcessId,hTempWin,ADDR pID
; obtain your pID
invoke GetCurrentThreadId
mov mypID,eax
; synchronize and attach the threads
invoke AttachThreadInput,mypID,pID,TRUE
; Get the handle of the control the user is typing in
invoke GetFocus
mov editWin,eax
; Do what you want to

; detach the threads when you're done
invoke AttachThreadInput,mypID,pID,FALSE
This will allow you to find the edit control handle from a window that is not one of your own. You have only to do this if GetFocus returns NULL, that indicates that the keyboard is focused outside of your application.
Posted on 2003-03-29 17:31:40 by donkey
okay, its still giving the same results ( not pasting into textpad, but most other windows ) the process im using is:



invoke GetForegroundWindow
mov hwnd_tmp, eax

invoke GetWindowThreadProcessId, hwnd_tmp, addr exPID
mov exPID, eax ; note this addition, without it it did not work at all for other windows

invoke GetCurrentThreadId
mov myPID, eax

invoke AttachThreadInput, myPID, exPID, TRUE

invoke GetFocus
mov hwnd_tmp, eax

invoke SendMessage, hwnd_tmp, WM_PASTE, NULL, NULL

invoke AttachThreadInput, myPID, exPID, FALSE
Posted on 2003-03-29 18:27:56 by abc123
Yeah, you're right the GetWindowThreadProcessId returns the process ID in pID and the thread ID in eax. As for why it's not working I have no idea. Maybe somebody else can figure that one out.
Posted on 2003-03-29 19:06:14 by donkey