How do I send key strokes to a window without having to activate it using Windows API? - winapi

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.

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.

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.

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

Related

SetWindowsHookEx(WH_SHELL, ...): What is the meaning of event HSHELL_WINDOWREPLACED?

If I register a hook via SetWindowsHookEx(WH_SHELL, ShellProc, ...), what is the meaning of event HSHELL_WINDOWREPLACED? (My Google-fu fails me. I have searched high and low!)
Win32 Docs:
SetWindowsHookEx(): https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexw
ShellProc (callback): https://learn.microsoft.com/en-us/windows/win32/winmsg/shellproc
The offical docs read: A top-level window is being replaced. Weirdly, they also say: Windows 2000: Not supported. Does that mean only supported before or after Win2K?
I created a test driver to watch a Microsoft Windows session, but I was never able to trigger this mysterious event.
I also found a similar event here:
RegisterShellHookWindow: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registershellhookwindow
... that says:
HSHELL_WINDOWREPLACING: A handle to the window replacing the top-level window.
HSHELL_WINDOWREPLACED: A handle to the window being replaced.
Related:
How can I be notified when a new window is created on Win32?
Why HSHELL_WINDOWDESTROYED, HSHELL_WINDOWCREATED?
In this instance, the term "replace" refers to the occasions when a window stops responding to messages ("hangs") and, after a certain period, Windows hides it and replaces it on-screen with a faded-out copy (called a "ghost window").
Windows does this so that, even when the app is not processing messages, the user can interact with the ghost window to move it around and try to close it.
The wParam value is the handle of the hung window (the one being replaced) and the lParam value is the handle of the ghost window (its replacement).
If the window starts responding again, the notification is sent again, with the window handles swapped around.

Preventing WM_SETCURSOR and WM_NCHITTEST messages from being generated

I'm making an application that hooks itself in to a target application and, when activated by the user, prevents all keyboard and mouse window messages from reaching the target application's window proc. My application does this by translating the incoming input messages, such as WM_MOUSEMOVE, to WM_NULL, so that the window proc is unaware input happened.
The problem is that Windows also automatically sends WM_SETCURSOR and WM_NCHITTEST to the window proc (e.g. when the application calls PeekMessage) when mouse input occurs. These messages aren't posted to the window's message queue, so I can't change them to WM_NULL.
I initially worked around this by subclassing the window proc and simply ignoring WM_SETCURSOR and WM_NCHITTEST there, but subclassing seems to have compatibility issues with some of the applications I'm hooked in to.
My question is: How do I prevent WM_SETCURSOR and WM_NCHITTEST from being generated in the first place OR how do I prevent them from reaching the application's window proc.
Some Ideas to Try
I just finished implementing a global/system wide CallWndRetProc with a WH_CALLWNDPROCRET Windows Hook (like it describes in the past post of the link below).
http://help.lockergnome.com/windows2/Igor-SetCursor-SetWindowsHookEx--ftopict285504.html
Using that in combination with hiding all the system cursors using SetSystemCursor has effectively hidden the cursor for most applications.
If you wanted to continue hacking at this target application, you could try using API Monitor to diagnosis what is going on: http://www.rohitab.com/apimonitor
The guy at rohitab hints at releasing his source code eventually; his site seems to have some of the better forums about Hooking, Subclassing, Injecting, etc.
It sounds like you successfully used SetWindowLongPtr(), but there are a few different ways to get into the address space of the program you are working on...
Have you tried SetCapture()?
Other Links
Here are a few other links that may be useful:
http://support.microsoft.com/kb/31747
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646262(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633569%28v=vs.85%29.aspx#winproc_subclassing
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648395(v=vs.85).aspx
Hope that helps. Good luck.

Stop application stealing input

I have a third party application (I'll call it GreedyApp for brevity), which holds the mouse and keyboard input hostage when its window gets focus i.e. it hides the standard mouse cursor and replaces it with it's own cursor, and confines the cursor to its window. The only way to get input to other windows is to ALT+TAB away from GreedyApp.
I need to allow the user free use of all of the components of the system (the delivered system will be purely touch-screen), so at the minute the rest of the system becomes unusable once GreedyApp gets focus.
So far, I've hijacked user32.dll for GreedyApp, hooked SetCursor, ShowCursor and ClipCursor, and disabled them. The result is that GreedyApp no longer hides the cursor, and the cursor is free to roam wherever the user moves it, but...
The problem I'm left with, is that no matter where on the screen the cursor is pressed, or what keys on the keyboard are pressed (except ALT+TAB), the input is still directed into GreedyApp, and other windows don't receive any input.
I'm not sure how GreedyApp is achieving this, and therefore I don't yet know which API calls to hook to stop it. I though it might have been using hooks itself, but I've hooked and disabled SetWindowsHookEx, but the problem persists.
So my question is this:
Either:
A) Is there a (relatively straight-forward) way to find out what API calls an application is making at runtime?
or
B) What method is GreedyApp likely to be using to stop other windows from receiving input?
The application was using RegisterRawInputDevices to get raw mouse and keyboard input, and using the flag RIDEV_CAPTUREMOUSE to stop other applications getting focus.
I've hooked the API call and remove the flag before passing the parameters to the Windows API to process. The user now has control over the system :)

Why does the SendMessage() function not work?

I try to send a WM_LBUTTONDOWN and WM_LBUTTONUP messages to a window( simulating mouse clicks without moving the cursor ).
My program is working very good on many windows, but there are a few that don't work :(
Like Registry Editor, Yahoo Messenger, some Firefox sites, etc...
How can I make to work with those from above ??
NOTE#1: I use Win7
NOTE#2: My code is just calling the api and functions and aply them on the specific window handle. Its working ok but not on all windows :(
It is another aspect of UAC, called UIPI or User Interface Privacy Isolation that could cause this trouble. Designed to prevent a program that run un-elevated from hijacking the capabilities of an elevated one. That certainly explains the trouble with Regedit.exe, clearly UAC would be ineffective if a program could commandeer it to poke stuff into the registry. You'd have to run your program elevated to bypass this restriction.
Another one is that SendMessage() doesn't properly simulate mouse input. The messages you are sending are normally posted to the message queue. You need to use PostMessage() instead. You should also emulate WM_MOUSEMOVE.
The proper way to simulate mouse input is through SendInput(). That one exactly emulates the mouse driver behavior, there's no way for a program to tell the difference. But with the added requirement that you have to make sure that whatever program you are trying to automate runs in the foreground. That's very difficult, SetForegroundWindow() isn't reliable enough. So only consider SendInput() if you actually only want to send mouse messages to the foreground window, whatever it might be.
You can call SwitchToThisWindow instead of SetForegroundWindow, which is much better and it works most of the times, and then either call SendInput or mouse_event, which is much more comfortable, because you're not dealing with structs at all.

What message will be sent by Windows when you press "Windows+D"

I used SPY++ to hook my windows message, but there is no WM_SYSCOMMAND message was sent when I pressed "Windows+D". What message will be sent by Windows when you press "Windows+D"?
Your application will not get a window message at all. Win+D is a hotkey registered by Explorer.exe (the shell program that's responsible for showing the taskbar, desktop icons, etc.).
It simply uses RegisterHotKey and it will receive a window message when you press WIN+D and will then take care of the whole show/hide thing.
Note you can register your own WIN+x hotkeys using said function but you're not supposed to and will run into problems - unless you were replacing Explorer.exe or such.
I don't think that this is a Window-Message at all...this is most likely handled by the kernel itself.
"Windows+D" is a hotkey combination.
Perhaps you can catch it as a WM_HOTKEY message.
You can register your own hotkeys, if you want, with the RegisterHotKey function.
Windows+D is a system wide hotkey and is reserved for use by operating system.
Hotkeys with MOD_WIN can not be registered by RegisterHotKey API or received by WM_HOTKEY message

Resources