How do I send key strokes to a window without having to activate it using Windows API?
Asked Answered
P

3

41

    I have made an application already that sends commands to an activated window. I want to be able to use the computer while my process is running because as soon as I switch focus to another window the key strokes being sent via send keys will go to the window I just switched to.

    Currently I use FindWindow, IsIconic, and ShowWindow from the Windows API. I have to check to see if the window is there with FindWindow and set my object to the specific window that is returned with that call, I then check if it's minimized with IsIconic and call ShowWindow if it is, and then finally I have to call Interaction.AppActivate to set focus to that window. All of this is done before I even send key strokes. Seems like there should be a way to just send key strokes without having to show the window and activate it. The big thing is while my application is running the key strokes I can't do anything on my computer.

Pannonia answered 3/8, 2009 at 5:56 Comment(4)
I'm using Windows Vista. I'm also using .NET 3.5 SP1 framework with Visual Studio 2008 in C#.Pannonia
There are good reasons you can't direct keyboard input to anything but the active window. They're kind of subtle, but they're there.Hartwell
I did a similar thing once in C++ on Windows. I captured the HDC (device context) of a notepad instance and mirror its input in another (inactive) notepad using SendMessage. You can even write to minimized application if you have its device context.Oestrogen
@Oestrogen this is an old thread but your answer seem very relevant to what I need. Is you HDC (device context) capture more reliable than SendMessage? To send simulated input to minimized windowsRevels
H
40

Alright, this is kind of disappointing I'm sure, but you fundamentally cannot do this with 100% reliability.

Windows assumes that the active window is the one getting keyboard input. The proper way to fake keyboard input is with SendInput, and you'll notice that it sends messages to the active window only.

That being said, you can SendMessage WM_KEYUP, WM_CHAR, and WM_KEYDOWN messages and (depending on the WndProc receiving them) maybe get away with it. But remember, its going to break under some circumstances, period.

Hartwell answered 5/8, 2009 at 0:44 Comment(2)
Anyone have any live links as to the going to break link?Doridoria
@MichalCiechan Late response to your question, but this is the link: devblogs.microsoft.com/oldnewthing/20050530-11/?p=35513Reticulate
N
10

Sounds like you are using keybd_event() or SendInput(), which both send keystrokes to the currently active window. To direct keystrokes to a specific window, regardless of whether that widnow is focused or not, you need to find its HWND handle first, and then post appropriately-formatted WM_KEYUP/DOWN and WM_CHAR messages directly to it.

Novotny answered 5/8, 2009 at 0:41 Comment(1)
Hi Remy :) I have been trying to send VK_SNAPSHOT to the HWND returned by GetDesktopWindow(), but it is somehow not working. My goal is to simulate a hardware press of the printscreen key. I know I can use SendInput() but my target app (a game) blocks screen capture this way :( , because it might have installed a Keyboard hook and it checks the LLKHF_INJECTED flag and makes VK_SNAPSHOT skip the message queue. GDI method for screen cap doesnt work. So I was trying to use SendMessage() to desktop window handle, but I dont think its working? Or am I sending to wrong window in wrong formatDemivolt
D
8

once you have the windows HWND, you can directly SendMessage() the WM_KEYDOWN and WM_KEYUP messages to its message queue. The window does not have to be active.

However, understand that this depends on how the target application processes keyboard input. There are several different ways to handle it.

WM_KEYUP/WM_KEYDOWN is most common and some applications only process one or the other (usually WM_KEYDOWN).

WM_CHAR is also fairly common

Some programs use GetAsyncKeyState, GetKeyState, or GetKeyboardState. This is extremely unusual, but effectively prevents keypress injection with SendMessage(). If this is the case fall back to keybd_event() which is directly handled by the keyboard driver. Of course the window will have to be active

Danialdaniala answered 6/10, 2016 at 16:34 Comment(1)
If some program uses GetAsyncKeyState, is there a way to fake a keyboard to send it simulated input? Maybe intercept syscall or I'm not sure whatRevels

© 2022 - 2024 — McMap. All rights reserved.