Welcome to MSDN Blogs Sign in | Join | Help

You can't simulate keyboard input with PostMessage

Some people attempt to simulate keyboard input to an application by posting keyboard input messages, but this is not reliable for many reasons.

First of all, keyboard input is a more complicated matter than those who imprinted on the English keyboard realize. Languages with accent marks have dead keys, Far East languages have a variety of Input Method Editors, and I have no idea how complex script languages handle input. There's more to typing a character than just pressing a key.

Second, even if you manage to post the input messages into the target window's queue, that doesn't update the keyboard shift states. When the code behind the window calls the GetKeyState function or the GetAsyncKeyState function, it's going to see the "real" shift state and not the fake state that your posted messages have generated.

The SendInput function was designed for injecting input into Windows. If you use that function, then at least the shift states will be reported correctly. (I can't help you with the complex input problem, though.)

Published Monday, May 30, 2005 7:00 AM by oldnewthing
Filed under:

Comments

# re: You can't simulate keyboard input with PostMessage

Monday, May 30, 2005 9:28 AM by Hasani
I currently use keybd_event. Is it still better to use SendInput in my case?

# re: You can't simulate keyboard input with PostMessage

Monday, May 30, 2005 10:32 AM by Phil Weber
What about keybd_event?

# re: You can't simulate keyboard input with PostMessage

Monday, May 30, 2005 10:45 AM by Toma Bussarov
I'm looking at the documentation about SendInput() and feel that something is missing. How do specify the target program or window to send the input? - no param of SendInput, no member in INPUT structure ... is it only used to send input to my-self?

# re: You can't simulate keyboard input with PostMessage

Monday, May 30, 2005 11:20 AM by waleri
Toma, you don't

SendInput() simulate keyboard/mouse event at lowest possible level. When you press a key on keyboard, you alse have no control where this click will go. You should make required window to have focus in order to receive keyboard events from SendInput()

# re: You can't simulate keyboard input with PostMessage

Monday, May 30, 2005 1:33 PM by David Candy
I have no idea how a computer works in any language but EN-AUS (I believe EN-US is a copy of EN-AU). I do troubleshoot foreign input. THERE IS NO DOCUMENTATION (apart from translating Edit/Copy/Paste for the UI - semi-relevent).

# re: You can't simulate keyboard input with PostMessage

Monday, May 30, 2005 1:49 PM by new thing
MS should really depracate all these Win32 horrors. It's obvious when talking about computers that people and developers want to automate tasks including those the original developer did not see that anyone would like to automate a task such as trying all possible permutations of passwords or making it look like to the computer that its the user who is initiating the delete partition command or clicking all those adds in the explorer. Why did MS not see this need?

# re: You can't simulate keyboard input with PostMessage

Monday, May 30, 2005 3:51 PM by Mihai
new thing:
"did not see that anyone would like to automate a task such as trying all possible permutations of passwords or making it look like to the computer that its the user who is initiating the delete partition command or clicking all those adds in the explorer."
There are way better ways to achieve this.
You have automation using COM, and Active Accessibility. The adds in Explorer are also accessible with the Explorer automation. Sending a mouse click is easy, finding them is difficult.
Many things can be achieved quite easy. You can SetWindowText, instead of sending one character at a time. You can send WM_COMMAND with IDOK instead of clicking the OK button.
The main problem with this is that the methods are not generic enough.

I am not saying it is easy, but is not as difficult as you think.

# re: You can't simulate keyboard input with PostMessage

Monday, May 30, 2005 5:57 PM by Michael S. Kaplan
I'll post about some of those complex input problems, tomorrow. :-)

# When complex scripts are not too complex

Tuesday, May 31, 2005 1:01 AM by Sorting It All Out
Raymond Chen did a post yesterday entitled You can't simulate keyboard input with PostMessage.
He did...

# re: You can't simulate keyboard input with PostMessage

Tuesday, May 31, 2005 10:13 AM by M W Grossmann
Where can I find more information on the handling of complex scripts such as Arabic? Is there aything public?

Also, is there no way to bypass GetKeyState or is this too deep in the basic functionality? There's SetKeyboardState which I'd expect would be able to force a state.

Cheers,
mwg
(E-Mail: sqeeze my full name together and point it in the direction of gmail)

# re: You can't simulate keyboard input with PostMessage

Tuesday, May 31, 2005 10:50 AM by Mike Weiss
Since someone asked, this is what I've done:

To send keyboard input to another process using SendInput() you'll have to
use AttachThreadInput(,,TRUE) using the main thread id of the target app AND
your app's thread id (I used GetWindowThreadProcessId()). Now input normally
going to your app now goes to another including stuff sent using
SendInput(). MAKE SURE you unattach using AttachThreadInput(,,FALSE) when
you're done.

# re: You can't simulate keyboard input with PostMessage

Tuesday, May 31, 2005 11:32 AM by oldnewthing
Attaching input queues has far-ranging consequences. Make sure you know what you're doing.

# re: You can't simulate keyboard input with PostMessage

Wednesday, June 01, 2005 10:38 AM by toomuchwin32
Other issues with using PostMessage to simulate keyboard (or mouse for that matter) activity are:

Keyboard and Mouse hooks will not get called. These hooks only get called for "real" mouse and keyboard input (keybd_event, mouse_event and SendInput are all alternate ways of generating "real" keyboard and mouse input).

The queue state (obtained using the GetQueueStatus API) will not reflect the correct state.

If you are waiting using the MsgWaitForMultipleObjects API and have specified QS_KEY or QS_MOUSE as your wake mask, you will NEVER be woken up.

Basically a posted message of WM_KEYxxx or WM_MOUSExxx is just that, a posted message. It will be treated as one by Windows. Of course, you will still be able to fool most applications using PostMessage because most applications simply call PeekMessage or GetMessage and use the resultant message.

# re: You can't simulate keyboard input with PostMessage

Saturday, June 04, 2005 5:14 AM by Jonathan
I have input problems when using VNC (a freeware Remote Desktop replacement). I can't type hebrew into the remote computer, even if both that computer's keyboard and mine are set to Hebrew.

And of course, my and the remote computer's keyboards can get out of sync - if he's initially in Hebrew and I'm in English, pressing Alt-Shift will just reverse both. It's more fun when I have 3 languages and he has 2...

# Generating tooltip text dynamically

Thursday, June 29, 2006 10:00 AM by The Old New Thing
Using the TTN_GETDISPINFO notification.
New Comments to this post are disabled
 
Page view tracker