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.)

Comments (15)
  1. Hasani says:

    I currently use keybd_event. Is it still better to use SendInput in my case?

  2. Phil Weber says:

    What about keybd_event?

  3. Toma Bussarov says:

    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?

  4. waleri says:

    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()

  5. David Candy says:

    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).

  6. new thing says:

    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?

  7. Mihai says:

    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.

  8. michkap says:

    I’ll post about some of those complex input problems, tomorrow. :-)

  9. Raymond Chen did a post yesterday entitled You can’t simulate keyboard input with PostMessage.

    He did…

  10. M W Grossmann says:

    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.



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

  11. Mike Weiss says:

    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.

  12. oldnewthing says:

    Attaching input queues has far-ranging consequences. Make sure you know what you’re doing.

  13. toomuchwin32 says:

    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.

  14. Jonathan says:

    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…

  15. Using the TTN_GETDISPINFO notification.

Comments are closed.