You can’t simulate keyboard input with PostMessage, revisited

If it didn't go through the input system, it only looks like input as much as the app allows itself to be fooled. The post You can’t simulate keyboard input with PostMessage, revisited appeared first on The Old New Thing.

Mar 21, 2025 - 18:28
 0
You can’t simulate keyboard input with PostMessage, revisited

A customer was trying to manipulate another program, so they tried posting messages to it. They found that input didn’t work reliably because the program had its own WH_KEYBOARD hook, and the posted messages weren’t triggering the hook, so the program saw input come in the message queue with no corresponding WH_KEYBOARD hook, and things got out of sync and didn’t work right. What’s going on?

What’s going on is that you can’t simulate keyboard input with PostMessage. Posting input messages is like prank calling the program. “Hello, this is (giggle) the input system? Yeah, and um (covers handset, whispers what should I say? back into handset), yeah the user hit the um, the Enter key? When? Um, like (other person whispers in their ear) 5 seconds ago? Yeah, okay, so like Enter key, got it? Cool, thanks.” How successful this is depends on how much the program allows itself to be fooled.

In this case, the program was correlating the input messages with information from another channel (the WH_KEYBOARD hook), and only keyboard input goes through the WH_KEYBOARD hook, because it is when a message is fetched from the input queue that the WH_KEYBOARD hook is called. Posted messages masquerading as keyboard input don’t come from the input queue; they come from the posted message queue. And the code that pulls messages from the posted message queue doesn’t call the WH_KEYBOARD hook.

As usual, the typical¹ answers are either to use UI Automation to drive the target program, or if the target program’s support for UI Automation is insufficient, you can use Send­Input to generate synthetic input. Synthetic input is treated like real input, and it goes through the input system like hardware input.¹

¹ An atypical answer is to use the target program’s object model if it offers one. For example, Microsoft Word lets you manipulate the application and its active document through its Application object.

² Synthetic input can still be detected, for example, by looking for the LLKHF_INJECTED flag in the KBDLLHOOKSTRUCT‘s flags.

The post You can’t simulate keyboard input with PostMessage, revisited appeared first on The Old New Thing.