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 |
|
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 |
|||
13 Jan 2009, 09:07 |
|
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. |
|||
13 Jan 2009, 10:38 |
|
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 |
|||
13 Jan 2009, 10:56 |
|
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? |
|||
13 Jan 2009, 12:34 |
|
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. |
|||
13 Jan 2009, 14:22 |
|
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. |
|||
13 Jan 2009, 18:47 |
|
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. 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, 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? |
|||
13 Jan 2009, 22:27 |
|
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 _________________ "Don't belong. Never join. Think for yourself. Peace." – Victor Stone. |
|||
14 Jan 2009, 09:02 |
|
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. |
|||
15 Jan 2009, 01:44 |
|
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.
|
|||
15 Jan 2009, 02:31 |
|
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. Oh and I think there's a program called autohotkey that can do it to. |
|||
15 Jan 2009, 04:57 |
|
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.
|
|||
15 Jan 2009, 05:34 |
|
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.
|
|||
15 Jan 2009, 07:11 |
|
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… |
|||
15 Jan 2009, 08:57 |
|
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. 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.. 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… 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.. |
|||
15 Jan 2009, 09:49 |
|
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 ). DispatchMessage() will drop any keyboard messages to inactive window, that's the problem. Good 'ole message loop… |
|||
15 Jan 2009, 21:36 |
|
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?
|
|||
16 Jan 2009, 08:30 |
|
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 ). 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. |
|||
16 Jan 2009, 09:38 |
|
Azu 16 Jan 2009, 10:02
baldr wrote: Azu, 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? |
|||
16 Jan 2009, 10:02 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.