winapi global hook WM_TIMER trace message sender - winapi

I'm trying to monitor a message sent by another window handle (particularly WM_TIMER) using WH_GETMESSAGE hook but it seems that I can only get the receiver handle, not the sender. Here's my code:
LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam){
if (nCode < 0){
return CallNextHookEx(hGetMsgHook, nCode, wParam, lParam);
}
else{
MSG* msg = (MSG*)lParam;
HWND window = msg->hwnd;
unsigned int msgCode=LOWORD(msg->message);
char* className = new char[50];
if (msgCode == WM_TIMER){
GetClassNameA(window, className, 50);
//className of the receiver handle
}
}
return CallNextHookEx(hGetMsgHook, nCode, wParam, lParam);
}
How do I get the sender hwnd?

You are asking to find information that has no meaning. The WM_TIMER message is not sent from one window to another. It is a pseudo-message that is synthesised by the system.
Certain low priority messages are implemented this way. The other common example is WM_PAINT. Your program has a message loop that repeatedly calls GetMessage which pulls messages off the queue. When the queue of real messages is empty, pseudo-messages are generated if needed. At this point the system will synthesise WM_TIMER or WM_PAINT messages.
So, these messages are never actually sent. They are just synthesised on demand.
On top of that, messages are not sent by windows. Messages are sent by calls to SendMessage, PostMessage etc. These functions do not ask the caller to supply a window handle for the sender. And they can be called from anywhere and have no clear affinity with any sender window. So even for tradition true messages, the concept of sender window has no meaning.

Related

Trouble catching WM_INPUT message for lParam, to collect Raw Mouse Input

For my college project I am developing a solution to distinguish between mouse user data from a person with Parkinson's compared to a healthy person. For which I need mouse data, ideally raw.
I presume I have misunderstood how to collect raw mouse input from the WM_INPUT message but I cannot figure it out.
I have been looking at the following thread: How to accurately measure mouse movement in inches or centimetres for a mouse with a known DPI
and Mouse input libraries on github all of which seem to easily catch a WM_INPUT message whose lParam is a handle to some RawInputData with something like this:
GetMessage(&msg, GetActiveWindow(), WM_INPUT, 0);
if (msg.message == WM_INPUT){ .....
And then retreiving the lParam from the message and collecting the data associated with that handle with:
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
However when I call GetMessage in my main loop, the function never exits!
Consequently there is no way (that i know of) for me to get a handle to the RawInputData. Especially since the MSDN page just assumes you have the lParam already.
In summary I need a method of getting an lParam to pass to the GetRawInputData function which will remain active whether the program is running in the active window of not.
I'm running this code in a blank C++ CLR project in Visual Studio with the "winuser.h" library.
#include "stdafx.h"
#include "Windows.h"
#include "winuser.h"
#ifndef HID_USAGE_PAGE_GENERIC
#define HID_USAGE_PAGE_GENERIC ((USHORT) 0x01)
#endif
#ifndef HID_USAGE_GENERIC_MOUSE
#define HID_USAGE_GENERIC_MOUSE ((USHORT) 0x02)
#endif
int main(array<System::String ^> ^args)
{
RAWINPUTDEVICE Rid[1];
Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE;
Rid[0].dwFlags = 0; //ideally RIDEV_INPUTSINK but that prevents registration
Rid[0].hwndTarget = GetActiveWindow(); //ideally this would be Null to be independent of the active window
if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE) {
//registration failed. Call GetLastError for the cause of the error
Console::WriteLine("Registration Error");
}
MSG msg;
while (true) {
while (GetMessage(&msg, GetActiveWindow(), WM_INPUT, 0) != 0) { //this command is never completed
DispatchMessage(&msg); //this line is never ran
}
if (msg.message == WM_INPUT) {
Console::WriteLine("caught a message!!!");
}
}
}
Issue solved after much more research I found the winAPI walk through which I followed fixing the issue above by adding an:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE unused, PSTR cmd, int show) {.....}
Function to register devices and create a window then call GetMessage which calls LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {....} with the parameters occupied by the message ID,WParam and LParam corresponding the message event.
For anyone stuck with a similar issue follow this MSDN guide: https://msdn.microsoft.com/en-us/library/bb384843.aspx

Can I call TranslateMessage inside the message callback?

I don't have the canonical message loop running, so is there a way I can call TranslateMessage (or its equivalent) inside my message proc handler?
Basically I need WM_CHAR messages and unless I can call TranslateMessage I'm not going to get those. Currently I have the message proc setup, but no message loop.
// Static window function called by Windows for message processing. Implementation
// delegates message processing to MemberWndProc.
LRESULT CALLBACK FxPlayerTiny::WindowsMsgStatic(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
msg = PeekMessage(&msg, HWnd, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE);
if (msg type is key down){
TranslateMessage(&msg);
//DispatchMessage(&msg); -- needed?
}
else process msg normally
}
My message proc handler is the first point of entry of messages, being setup in the following manner:
WNDCLASSEX wc;
wc.lpfnWndProc = WindowsMsgStatic;
....
RegisterClassEx(&wc);
At some point, in order to get a queued message, you must call a function like GetMessage or PeekMessage. Those functions yield MSG objects and it is those MSG objects that you must pass to TranslateMessage and DispatchMessage.
In the code in the original version of the question, you are trying to call TranslateMessage and DispatchMessage too late. You call them inside your window proc. You should call them at the point where you first receive the MSG object. In other words, call TranslateMessage and DispatchMessage straight after the call to PeekMessage or GetMessage.

win32 / opengl and callback functions.. how are they structured?

I'm working on a win32 c/cpp project involving openGL. I'm just starting and had a few basic questions regarding how a standard win32 program works. Following a tutorial, I made the winmain create a new window, enable openGL for the window, and then enter the main loop where if there are messages, the program handles them, and otherwise, the program moves onto drawing openGL animations. Following that, I simply shut down openGL and destroy the window. I'm not too confused about what's happening in here, but this is where I get lost:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message)
{
case WM_CREATE:
return 0;
case WM_CLOSE:
PostQuitMessage( 0 );
return 0;
case WM_DESTROY:
return 0;
case WM_KEYDOWN:
switch ( wParam )
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
}
return 0;
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
though I do see in the winmain that I register this function to my window class via
wc.lpfnWndProc = WndProc;
How exactly does this process work? Can someone explain the pipeline to me - as the winmain method runs, it goes onto drawing the opengl animation, but as soon as a key is pressed, it enters message handling... and then what? How does my winmain method communicate with the WndProc method? What's actually happening from the machine's point of view?
In your WinMain there should be a pair of TranslateMessage / DispatchMessage calls. TranslateMessage is responsible for getting keystrokes being delivered correctly and DispatchMessage traverses the window hierachy to deliver the messages to the window that has the input focus, effectively calling the function which pointer was registered as default window message handler (Window Procedure) with the message as parameters.

KeyPress with multiple modifiers not working in QWidget

I have added an override for my main widget's keyPressEvent:
void MainWindow::keyPressEvent(QKeyEvent* e)
{
if (e->key() == Qt::Key_F11)
{
if (e->modifiers() & Qt::AltModifier && e->modifiers() & Qt::ControlModifier)
{
// do stuff
}
}
}
The problem is that it does not work. If I try the AltModifier or ControlModifier alone it works (while changing the second condition of course), but not for both of them. The key() won't equal to Qt::Key_F11 while I do press F11. I'm using windows.
Edit: checked with logging and the result is that Ctrl+Alt+F11 and Ctrl+Alt+F12 do not send a key event (while other Ctrl+Alt+Fxx keys do).
Oook, so I managed to solve it though I'm not exactly pleased with the solution. At least there is no mystery and it works :).
The reason why I didn't receive the hotkeys Ctrl+Alt+F11 and Ctrl+Alt+F12
They were registered as global hotkeys. I managed to find this out using the ActiveHotkeys program of the fellow stackoverflow member moodforaday (thanks a lot for it!). Apparently there is no documented way to find out which program registered a particular hotkey (and it didn't do anything on my system). See moodforaday's thread about the issue.
The solution
One of the answers in the aforementioned thread led me to another question. Efotinis' answer was absolutely perfect for me. I did not have experience with setting up low-level keyboard hooks, but it was not nearly as difficult as it sounds. For future's sake, here is how I did it in my Qt application:
In my mainwindow.h:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
// ... code
private:
void tryLogin();
friend LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wparam, LPARAM lparam);
};
LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wparam, LPARAM lparam);
In my mainwindow.cpp:
// setting up the hook in the constructor
SetWindowsHookEx(WH_KEYBOARD_LL,
LowLevelKeyboardProc,
NULL,
0);
The hook code (mostly from efotinis' answer):
LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wparam, LPARAM lparam)
{
KBDLLHOOKSTRUCT* kllhs = reinterpret_cast<KBDLLHOOKSTRUCT*>(lparam);
if (code == HC_ACTION)
{
if (wparam == WM_KEYDOWN && kllhs->vkCode == VK_F12 &&
(GetAsyncKeyState(VK_MENU) < 0 && GetAsyncKeyState(VK_CONTROL) < 0))
{
MainWindow* w = dynamic_cast<MainWindow*>(qApp->activeWindow());
if (NULL != w)
{
w->tryLogin(); // this should not be blocking!
return 1;
}
}
}
return CallNextHookEx(0, code, wparam, lparam);
}
As you can see, we get the pointer to the application window from the global QApplication object. We use dynamic_cast so in the active window happens to not be a MainWindow instance we would get a NULL pointer.
If you are wondering why the GetAsyncKeyState calls are checked for < 0, it's because this function returns with MSB set if the key is down. And when the MSB is set, the SHORT number is negative (on x86/x64 and compatible platforms). If windows ever gets ported to a platform where signed integers are represented differently, this code might break. The absolutely proper way would be to create a 16-bit mask and use that to check the MSB, but I'm lazy to do that. :)
One thing to note is that when you call a function from your hook, the Qt event loop has just begun processing. That means until you don't return from your function, it will block the UI (freezing it for a few seconds). If you wanted to show a dialog like I did, instead of exec(), call raise, activateWindow and show, while setting the window modality of the dialog to modal (in its constructor maybe).
You can unregister the hook with UnHookWindowsHookEx if you want to (which happens when the module containing the hook is unloaded). To do this, save the return value of the SetWindowsHookEx call.

Create a native Windows window in JNA and some GetWindowLong with GWL_WNDPROC

Good day,
I have been using JNA for a while to interact with the Windows API and now I am stuck when creating a window. As far as I have done the following:
1. Have created a child window of an existing window and obtained a valid handler to it.
2. Understood that every window in Windows has a non-stop message-dispatch loop.
3. Understood that the best way to include my window in the message-dispatch loop is to use something like the following code (not mine, but that is what I would do as well):
final LONG_PTR prevWndProc = new LONG_PTR(User32.INSTANCE.GetWindowLong(hwnd, User32.GWL_WNDPROC)); //this is to obtain a pointer to the WNDPROC of the parent window, which we are going to need later
wndProcCallbackListener = new WndProcCallbackListener()
{
public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam)
{
if (uMsg == WTSAPI.WM_POWERBROADCAST)
{
System.out.println("WM_POWERBROADCAST Event: hWnd="+hwnd+", uMsg="+uMsg+", uParam="+uParam+", lParam="+lParam);
}
else if (uMsg == WTSAPI.WTS_SESSION_CHANGE)
{
System.out.println("WTS_SESSION_CHANGE Event: hWnd="+hwnd+", uMsg="+uMsg+", uParam="+uParam+", lParam="+lParam);
}
//Call the window's actual WndProc so the events get processed.
return User32.INSTANCE.CallWindowProc(prevWndProc, hWnd, uMsg, uParam, lParam);
}
};
//Set the WndProc function to use our callback listener instead of the window's one.
int result = User32.INSTANCE.SetWindowLong(hwnd, User32.GWL_WNDPROC, wndProcCallbackListener);
However, my problem is when I call the GetWindowLong() for the parent window (my first line of code) I get a 0 for the pointer which indicated the function did not complete successfully. A subsequent call to GetLastError() and a quick check in the error codes give me an 'Access is denied' error. This, of course, is logical, since I am trying from my own thread to access the address of the WNDPROC of another, but I was wondering if there is any way (there should be, of course) to circumvent that.
Any pointers? (pun intended)
Do not use GetLastError() after a JNA call. JNA & JNI may call other APIs that may change the last error. Declare SetWindowLong with the clause throws LastErrorException, like this:
int SetWindowLongA(int hWnd, int nIndex, WndProcCallbackListener dwNewLong)
throws LastErrorException;
Notice the 'A' after the name. It makes explicit use of ANSI version. You could use SetWindowLongW as well.
Make sure your callback implements both Callback and StdCall. I prefer using primitive types as much as possible, because this makes mapping fast and obvious to JNA:
public interface WndProcCallbackListener extends Callback, StdCall {
int callback(int hWnd, int Msg, int wParam, int lParam);
}

Resources