flat assembler
Message board for the users of flat assembler.

Index > Windows > PostMessage sending different letter depending on window?

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 13 Jan 2009, 09:02
This sends "e" over and over
Code:
include 'J:\fasmw16727\INCLUDE\win32ax.inc'
text:
invoke FindWindow,0,"World of Warcraft"
test eax,eax
jz err2
mov edi,eax
post:   invoke PostMessage,edi,256,"a",0
        test eax,eax
        jz err
        invoke PostMessage,edi,257,"a",0
        invoke Sleep,1000
        jmp post
err:    invoke MessageBox,0,"Can't post message","Err",0
        xor esp,esp
err2:   invoke MessageBox,0,"Window not found","Err",0
        xor esp,esp
.end text    


But this sends "s" instead
Code:
include 'J:\fasmw16727\INCLUDE\win32ax.inc'
text:
invoke FindWindow,0,"Untitled - Notepad"
test eax,eax
jz err2
invoke GetDlgItem,eax,0x0000000F
test eax,eax
jz err2
mov edi,eax
post:   invoke PostMessage,edi,256,"a",0
        test eax,eax
        jz err
        invoke PostMessage,edi,257,"a",0
        invoke Sleep,1000
        jmp post
err:    invoke MessageBox,0,"Can't post message","Err",0
        xor esp,esp
err2:   invoke MessageBox,0,"Window not found","Err",0
        xor esp,esp
.end text    


Can somebody please explain to me why this is? Or at least tell me what to search for to find out? Nothing I've tried has come up with any useful documentation on this..



P.S. is there a way around needing to use GetDlgItem on some windows? When I focus them myself and start typing, it goes into the edit box.. but if I take the GetDlgItem out in my notepad example, nothing is sent. I'd like it if my program could send text to any arbitrary window without me having to write custom code for each window.. but actually focusing them isn't an option since with full screen windows it takes a long time to focus them and then give focus back to whatever was up before..

Whew that was a long P.S.. Sorry about that lol. Didn't want to flood this forum with a new topic for each little question when they are related though. =Þ


Last edited by Azu on 13 Jan 2009, 09:12; edited 1 time in total
Post 13 Jan 2009, 09:02
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20445
Location: In your JS exploiting you and your system
revolution 13 Jan 2009, 09:07
You should really show your message retrieval loop to show the problem. But I think you will find that you are sending the address of the string "a" and when you examine the last byte of the address you get whatever the code pointer happens to be.

Try this:
Code:
invoke PostMessage,edi,256,0x61,0    
Just replace the string "a" with the constant 0x61 (ASCII lower case a).
Post 13 Jan 2009, 09:07
View user's profile Send private message Visit poster's website Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 13 Jan 2009, 10:38
Thanks, I tried that and now it sends the same thing each time.

Now it sends two 1s: "11".

This also sends an 11
Code:
include 'J:\fasmw16727\INCLUDE\win32ax.inc'
a dw "a",0
text:
invoke FindWindow,0,"Untitled - Notepad"
test eax,eax 
jz err2 
invoke GetDlgItem,eax,0x0000000F
test eax,eax 
jz err2
mov edi,eax
post:   invoke PostMessage,edi,256,[a],0
        test eax,eax 
        jz err 
        invoke PostMessage,edi,257,[a],0
        invoke Sleep,1000 
        jmp post 
err:    invoke MessageBox,0,"Can't post message","Err",0 
        xor esp,esp 
err2:   invoke MessageBox,0,"Window not found","Err",0 
        xor esp,esp 
.end text    


How do I send an "a"?


BTW I don't understand this
Quote:
You should really show your message retrieval loop to show the problem.


I posted the entire contents of my test file. I'm not sure exactly what you are asking for. I am trying to find a way to send messages to windows based on their name. Not receive anything.
Post 13 Jan 2009, 10:38
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20445
Location: In your JS exploiting you and your system
revolution 13 Jan 2009, 10:56
Okay, I see that 256 is WM_KEYDOWN and 257 is WM_KEYUP. You should ideally use symbolic constants to avoid confusion.

So looking at the MS documentation iParam is the lKeyData and wParam id the nVirtKey. So you must follow the virtual key layout.

Code:
invoke PostMessage,edi,WM_KEYDOWN,VK_A,1
...
invoke PostMessage,edi,WM_KEYUP,VK_A,1    
I'll leave it to you to find out the VK_A constant. hint: it is 0x41.
Post 13 Jan 2009, 10:56
View user's profile Send private message Visit poster's website Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 13 Jan 2009, 12:34
Thank you

VK_A = h41 = 65 = a


One more problem though sorry.. to some programs, it sends a single a, and to others, it sends two.

If I take out the keydown or the keyup, for example, it sends a single a to notepad. But to other windows E.G. WoW it doesn't work.

Would it be possible to make it just send a single character, all the time? I can't create a special exception for every single program that exists.. I need to have it just work the same always.. I tried putting different numbers in the last parameter but it doesn't seem to do anything.. and I also can't figure out why I need to do the GetDlgItem with different values with different programs, and sometimes not have it at all..

Am I using the wrong function all together? Or am I just not using it right?
Post 13 Jan 2009, 12:34
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20445
Location: In your JS exploiting you and your system
revolution 13 Jan 2009, 14:22
You should ideally use keybd_event to send keystrokes to windows. Look up the MS documentation for it.

Plus, if you still want to use WM_KEYUP/DOWN then you should also use the proper scan code and the transition codes in the high order bits of lParam. Look up the proper MS documentation for how to use it properly.
Post 13 Jan 2009, 14:22
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 13 Jan 2009, 18:47
Azu,

May be single WM_CHAR will be enough?
Code:
        include "WIN32AX.INC"

        .code
start:  invoke  FindWindow, 0, "Untitled - Notepad"
        invoke  GetDlgItem, eax, 15
        invoke  PostMessage, eax, WM_CHAR, ('B'), 0
        ret

        .end    start    

_________________
"Don't belong. Never join. Think for yourself. Peace." – Victor Stone.
Post 13 Jan 2009, 18:47
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 13 Jan 2009, 22:27
Azu wrote:
actually focusing them isn't an option since with full screen windows it takes a long time to focus them and then give focus back to whatever was up before..

revolution wrote:
You should ideally use keybd_event to send keystrokes to windows. Look up the MS documentation for it.

Plus, if you still want to use WM_KEYUP/DOWN then you should also use the proper scan code and the transition codes in the high order bits of lParam. Look up the proper MS documentation for how to use it properly.
Last time I checked keybd_event is only capable of sending to whatever has focus. Sad
I think I might be using the wrong word, though, and that's why the confusion? What I mean by focus is using SetActiveWindow.



baldr wrote:
Azu,

May be single WM_CHAR will be enough?
Code:
        include "WIN32AX.INC"

        .code
start:  invoke  FindWindow, 0, "Untitled - Notepad"
        invoke  GetDlgItem, eax, 15
        invoke  PostMessage, eax, WM_CHAR, ('B'), 0
        ret

        .end    start    
Thanks! That fixed what it sends, perfectly.

I still can't get it to send to most windows (that need the GetDlgItem) unless I spend a lot of time googling the id of their edit control, though, and I can't put in an exception for each program that exists.. it would take to long, and I would have to keep updating it every time a new program is made.. so I need to find a way to send it to the default control like SetActiveWindow + keybd_event does. Any ideas?
Post 13 Jan 2009, 22:27
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 14 Jan 2009, 09:02
Azu,

Probably I can help you better if you outline the problem you're trying to solve…
Code:
        include "WIN32AX.INC"

        .code
start:  invoke  FindWindow, NULL, "Untitled - Notepad"
        invoke  FindWindowEx, eax, NULL, "EDIT", NULL
        invoke  PostMessage, eax, WM_CHAR, ('C'), 0
        ret

        .end    start    
This code sends character to first child edit control.

_________________
"Don't belong. Never join. Think for yourself. Peace." – Victor Stone.
Post 14 Jan 2009, 09:02
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 15 Jan 2009, 01:44
Thank you.


Basically my problem is I can't find a way to send a key to windows without actually bringing them up with SetActiveWindow (which takes way to long for minimized fullscreen windows).

I tried your solution and it works for notepad, but nothing else.

Writing a separate section of code for every single program in existence isn't an option for me. I want to make it work the same for all programs. Nothing I try works for more then one, though.
Post 15 Jan 2009, 01:44
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4071
Location: vpcmpistri
bitRAKE 15 Jan 2009, 02:31
All programs use a different set of controls, and the windows keyboard record/playback only works on the active window. I've never seen a universal way to send events to non-active windows. I would be very interested in such a discovery as long as it doesn't involve rewriting a large chunk of windows, or injecting code into another process.
Post 15 Jan 2009, 02:31
View user's profile Send private message Visit poster's website Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 15 Jan 2009, 04:57
bitRAKE wrote:
All programs use a different set of controls, and the windows keyboard record/playback only works on the active window. I've never seen a universal way to send events to non-active windows. I would be very interested in such a discovery as long as it doesn't involve rewriting a large chunk of windows, or injecting code into another process.
Thanks. I assumed it was possible since SetActiveWindow somehow finds it automatically so that keybd_event can send to it. Thought there would be a way to find it using whatever method SetActiveWindow uses to find it. I wasn't sure to find out how it works though so thought I'd ask here.

Oh and I think there's a program called autohotkey that can do it to.
Post 15 Jan 2009, 04:57
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20445
Location: In your JS exploiting you and your system
revolution 15 Jan 2009, 05:34
Two of the most difficult functions to overcome when trying to emulate keystrokes are GetAsyncKeyState and GetKeyboardState. Many games like to use these functions.
Post 15 Jan 2009, 05:34
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4071
Location: vpcmpistri
bitRAKE 15 Jan 2009, 07:11
On the AutoHotKey forum there are many specific solutions, but I don't believe the general problem has been solved. Last time I looked at the source code (C++) they were using code injection.
Post 15 Jan 2009, 07:11
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 15 Jan 2009, 08:57
bitRAKE,

Sending messages directly to [subordinate window of] inactive window can be done (at least I just had wrote simple program that use WM_SETTEXT, WM_CHAR and WM_KEYDOWN/UP to set Diablo player's name and launch single player game, starting from player name's prompt dialog). The problem, as I see it, is to determine which window will receive focus after SetActiveWindow(), right?

revolution,

You're right, and we have DirectInput also… Wink
Post 15 Jan 2009, 08:57
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 15 Jan 2009, 09:49
revolution wrote:
Two of the most difficult functions to overcome when trying to emulate keystrokes are GetAsyncKeyState and GetKeyboardState. Many games like to use these functions.
I thought the original code I posted worked for that.. for WoW anyways. I made a simple little bot to walk around a bit while it's minimized and it seems to work.

THe problem I am having is with sending keystrokes consistantly to other programs. The GetDlgItem example works for Notepad.. but I can't find the code to get it to work with Trillian..


It would be so nice if there was a way to just make it work the same for all programs or something.. instead of having to try to custom code different method for each program..

Confused

I think most of the programs don't use GetAsyncKeyState BTW.. because when I do keyup and keydown instead of wm char it sends two keystrokes.. so I think it is something else..

Or maybe I just have no clue what I'm talking about lol. If so, sorry.





baldr wrote:
we have DirectInput also… Wink

I know that I'm using the win32 API anyways, but I'd really really like to avoid all forms of DirectX for this, since that is probably even more non-portable then most win32 API functions..
Post 15 Jan 2009, 09:49
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 15 Jan 2009, 21:36
Azu,

DX is not an issue, you will not encounter DX-only programs in near future (well, almost DX-only Wink).

DispatchMessage() will drop any keyboard messages to inactive window, that's the problem. Good 'ole message loop…
Post 15 Jan 2009, 21:36
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 16 Jan 2009, 08:30
So I'd have to get rid of DispatchMessage to make this work? How do I do that, edit user32.dll?
Post 16 Jan 2009, 08:30
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 16 Jan 2009, 09:38
Azu,

This is by design. DispatchMessage() provide common code for message dispatching (i.e. determine which window gets what message from thread message queue). Your program could handle this on its own, but you seldom encounter GUI program without GetMessage()/TranslateMessage()/DispatchMessage() loop of some kind.

As I've already said, you can directly send messages to inactive window, thus bypassing message pump and DispatchMessage(). It's WndProc() will handle them as usual (provided that window procedure is not state-aware Wink). The hard part is to determine to which window you have to send them and find it in process' windows hierarchy at run-time.

_________________
"Don't belong. Never join. Think for yourself. Peace." – Victor Stone.
Post 16 Jan 2009, 09:38
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 16 Jan 2009, 10:02
baldr wrote:
Azu,

This is by design. DispatchMessage() provide common code for message dispatching (i.e. determine which window gets what message from thread message queue). Your program could handle this on its own, but you seldom encounter GUI program without GetMessage()/TranslateMessage()/DispatchMessage() loop of some kind.

As I've already said, you can directly send messages to inactive window, thus bypassing message pump and DispatchMessage(). It's WndProc() will handle them as usual (provided that window procedure is not state-aware Wink). The hard part is to determine to which window you have to send them and find it in process' windows hierarchy at run-time.



So something like this then?


invoke FindWindow,0,"Name of the window I want to send to"
invoke WndProc,eax,"a"


And this will work for all programs?
Post 16 Jan 2009, 10:02
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.