Simulating input via WM_CHAR messages may fake out the recipient but it won’t fake out the input system

We saw some time ago that you can't simulate keyboard input with Post­Message. You may get away with it, depending on how the application you're trying to fake out processes input, but since you're just faking data, the application may discover that it's all a ruse when they try to access information that you didn't fake out, say by calling Get­Key­State and discovering that the key it was told was being pressed is in fact not being pressed after all.

When you try to do this fake-out, you might or might not be able to fake out the application, but you're definitely not going to fake out the input system itself.

I wrote a test program that simulates input via WM_CHAR messages to write characters into Notepad. I set the local screen saver timeout to one minute, but the screen saver launches after one minute even if my program has been running. On the other hand, when I type on the physical keyboard, the screen saver does not kick in, as expected. How does the screen saver know that the system is really idle and the input is just being generated by a program?

Actually, the question is backwards. How does the screen saver find out about your fake input? Pumping WM_CHAR messages directly into Notepad bypasses the input system. It's not that it "knew" that you pulled an end run around it; it is merely acting on what it knows, and your fake input is not part of what it knows.

It's like prank-calling somebody and saying, "Hi, this is your credit card company. You don't need to pay your bill this month. Don't worry about it." Sure, that person may be fooled into not paying their bill, but a month later, they're going to get a late payment notice from the credit card company. "How does the credit card company know that the bill wasn't forgiven and the phone call was fake?"

If you want to generate input programmatically, use Send­Input.

Note that the window manager still knows whether the input came from hardware or from Send­Input, and the SPI_SET­BLOCK­SEND­INPUT­RESETS system parameter controls whether programmatically-generated input should reset the screen saver.

Comments (19)
  1. Vilx- says:

    Real Men write their own keyboard driver which emulates keystrokes. Before breakfast.

  2. Dan Bugglin says:

    Or you could, you know, have your program disable the screen saver while it runs.

    Though I love SendInput.  Used it to make a library for .NET so I can simulate keyboard/mouse input with a Wii Remote.  Good times.

  3. Mark says:

    The MAZZTer: hmm, fiddling with global state to solve a local problem?  Please don't disable the screensaver while your program is running unless you're a presentation program.

  4. Bob says:

    Mark: Hopefully The MAZZTer is using local means to disable the screensaver. SetThreadExecutionState is perfectly fine for this purpose.

  5. Homer S. says:

    I once used a dippy bird for such purposes. Everybody was fooled until it let me down, but luckily the unrequested fission surplus was stopped in the end, by my end.

  6. Mason Wheeler says:

    @Mark: Or a full-screen game.  I've had the screensaver toggle in the middle of long cutscenes/movies before, and it is not a pleasant experience.

    Come to think of it, I've also had it toggle while watching DVDs and YouTube videos. It can be more trouble than it's worth sometimes, and there are more legitimate reasons to disable it than you might think at first.

    [Or just handle the WM_SYSCOMMAND/SC_SCREENSAVE message. -Raymond]
  7. R. Bemrose says:

    @Mason Wheeler:

    That really depends on how the application is doing it.  In my experience, programs that use a "real" full screen mode don't get interrupted by screensavers, while ones that fake it, by creating a borderless window the size of your viewing area, do get interrupted by the screen saver.  Unless they've used some other trick to block it, presumably like what Bob suggested.

  8. MikeCaron says:

    @R Bemrose: It's not a trick, it's the whole point of SetThreadExecutionState. It tells Windows "even though the user may not appear to be interacting with the PC, it would be really inconvenient for that user if the system were to sleep or the display were to turn off." Programs that use it include, but are not limited to:

    • DVD/Video Players
    • CD/DVD Burners

    • Games

    • Presentation programs

    • Voice chat clients

    • Backup programs

    • More!

    Many of these do not go into fullscreen mode. Some don't even have UI all the time. However, they still need to block the computer from becoming idle.

    (Also, I suspect that fullscreen programs do not necessarily get this protection automatically. They still have to call this function too!)

  9. BTW SetThreadExecutionState() does not stop the screen saver from executing…

  10. Gabe says:

    Waleri: Indeed, it's a good thing that it doesn't, as I need my screen saver to call SetThreadExecutionState!

  11. Alex Grigoriev says:

    Wait, even with ES_DISPLAYREQUIRED? That's what the function documentation tells to do for the video player apps.

  12. Gabe says:

    Alex: SetThreadExecutionState is actually just a power management function. Its job is to prevent the monitor and/or computer from shutting down automatically. The screensaver is somebody else's job.

  13. lefty says:

    Ok – I now know more that I need to know about disabling the screensaver without actually pressing any keys. Could someone please explain the answer to the problem about getting my credit card company to not bother with billing me even thogh I don't pay them anything?

  14. steveg says:

    @lefty: SendMessage(hWndCreditCard, WM_CLOSE, accountNum, pin);

  15. Why even bother with screensavers anymore? says:

    These days its better to just have the screen go into power save mode.

    Power save mode does just as much (if not more) to save your screen (CRT or otherwise) from burn-in and uses even less electricity than a screensaver does.

  16. If I remember correctly, even if you do things right as a media player/etc, if you have the screensaver lock the computer, it will still effect the screensaver after the timeout period.  I can't find the reference but I know that was the observed behavior with Media Center and Windows Media Player.

  17. Bob says:

    Yeah, that's the new behavior under the Vista/7 regime. Handling SC_SCREENSAVE (as Raymond mentioned earlier) doesn't prevent the machine from locking by design. It does work under XP and earlier, though.

  18. Ens says:


    I'd recommend PostMessage.  Credit card companies like to hang onto their customers…

  19. Chris Taylor says:

    It might be worth mentioned that sending WM_CHAR cannot be used to change the 'shift' state of the keyboard. So while you might be able to fake sending characters to notepad, you will not be able to change the case of the characters.

Comments are closed.