Why does the SendMessage() function not work? - windows

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.

Related

How to write a program that runs another GUI program inside it

I am not sure how to ask the question so here is a picture of some idea that came to mind
So for example, when you run my "custom launcher" it displays a window with a couple buttons on the side which you can assign values to. When you click on a button, the appropriate program will run in the big panel on the right (in window mode).
This is all from the user's perspective of course. They will just see that the program they want to run appears in that panel. The actual implementation may have nothing to do with "one program running inside another program"
My own use case is limited to windows desktop platforms only, but if it is possible to generalize it that would be nice as well.
Is this actually possible? Can I write such a program that will run another program inside a panel? The program that's launched may be someone else's, such as MS paint or calculator.
Just to expand on my comment above, here is an approach that may work for you: Fake it :)
When you launch the program, intercept all windows messages to the program that control it's position on screen. That way it 'appears' to be fixed in place, but in reality it's still attached to the normal Windows desktop.
Here's some light reading for you:
Windows Event Hooks
A hook is a mechanism by which an application can intercept events,
such as messages, mouse actions, and keystrokes. A function that
intercepts a particular type of event is known as a hook procedure. A
hook procedure can act on each event it receives, and then modify or
discard the event.
I would recommend against it in a commercial application because you are modifying the behavior of software you don't own - that software may make assumptions about what its parent window is, but for experimentation there's the SetParent Win32 function.

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.

Is there a command line utility that can listen for OS-wide keystrokes and tell me via stdout?

I'm developing an app and I'd like to trigger functions in my app via keystroke combos when it's not in focus.
Because I'm developing my app in AIR, I do not have access to listen to global Keystrokes. However, I can receive STDOUT from an application. So, I'm looking for a utility that can give me this ability. I'm looking for both Windows and OSX (cross-platform baby!)
For Windows, you could write a simple application that installs a keyboard hook and prints information about the key event to stdout. See SetWindowsHookEx.
For Windows:
I don't know of any app off the top of my head, but here are some ideas that might work within 100 lines of code...
I would avoid SetWindowsHook, as that would inject your code into all apps. (Because I've spent good time debugging crash dumps and bugs as a result of poorly written hooks...)
You could write a console app with DirectInput (old gaming keyboard API). I believe you just pass DISCL_BACKGROUND and DISCL_NONEXCLUSIVE into IDirectInputDevice8::SetCooperativeLevel call. Use IDirectInputDevice8::SetEventNotification to set the event handle so you don't have get into a busy wait loop polling for input. And that should do it. I did this once for my app a long time ago on Windows 98 and it worked really well. But DirectInput is very close to being deprecated technology so YMMV.
Another simple hacked up way to do what you are doing is to have your app create a hidden window, call call RegisterHotkey for all the keyboard, and pump window messages. Your wndproc will get a WM_HOTKEY window message that you can use that to generate a message to stdout.
The simplest way, but will be slightly error prone and cpu-expensive is to have your console app get into a loop and call GetKeyboardState. This will return the entire state of the keyboard of all keys that are up and down. You'll have to figure out how translate each poll into a logical keystroke. I'd recommend sleeping a few milliseconds between polls so you don't kill system-wide performance.
Can't help you on OSX.
For windows, here is a utility that will listen to the keyboard.
http://www.dynamicnetservices.com/~will/academic/textinput/keycapture/

Receive screensaver notification

I want to receive a notification in my C++ application when a screensaver is about to start. I tried listening to WM_SYSCOMMAND messages with wParam == SC_SCREENSAVE which some people think should do the trick.
That didn't work. Spy++ even showed that my window didn't receive any WM_SYSCOMMAND message. Interesting thing is when I turned off the monitor I did receive the message with wParam == SC_MONITORPOWER. Am I understanding it wrong? Or did I just miss something?
Edit: For testing I used the default windows screensaver (the one with windows logo).
It appears that I will receive the SC_SCREENSAVE message only when my window has focus. The way around this is to set global hook. That would require me to put the callback function in a separate DLL and there is also this scary message about hooks slowing down the system so I decided to drop the idea of responding to screensaver start.
This is a relatively complex task (although it would be nice if it were easy).
Some of these tests you'll find online only work if your window is in focus. If it's running in the background it may not receive such messages.
Other tests rely on a screensaver program running (check the currently set screensaver, and then watch the process list to see if it's active) but don't work if you go into powersave mode, or if your screensaver is a black screen (ie, no program, just monitor off).
I don't believe there's an ideal way to do this. You might want to go back to the beginning and think more carefully about why you need to detect this state, and what you are trying to accomplish. You might need a different solution.
Probably my answer comes too late.
The MSDN handles screensavers under "Legacy".
On a notebook they waste battery and on a PC they are also useless.
It is better to turn the monitor off than letting it show a screensaver.
As you don't explain exactly what you want to do I don't know if you really need the notification BEFORE the saver starts or if it is enough to get notified when it already has just started.
In the latter case it is easy.
Write a thread that periodically checks:
BOOL b_SaverRunning;
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &b_SaverRunning, 0);

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

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

Resources