Why must SetWindowsHookEx be used with a windows message queue - c++

I've been trying some things with hooks, and I don't understand why hooks must be used with a message queue
hook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(hook);
Why doesn't something like this work ?
hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, 0);
cin >> aKey;
UnhookWindowsHookEx(hook);
Using boost threads, and a barrier doesn't work either. Why can't the waiting between the hook and unhook be done in another manner ?
EDIT:
I did a mistake when I created this sample, I create a WH_KEYBOARD_LL hook, not WH_KEYBOARD, (I don't think it makes a big difference)
Also the loop never executes only waits on the GetMessage function.
The loop executes only when I post the quit message PostThreadMessage(id, WM_QUIT, 2323, NULL); so I don't understand what does it do beside waiting, is there some internal processing ?
RELATED:
C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup
How can I set up a CBT hook on a Win32 console window?

The low-level hooks, WH_KEYBOARD_LL and WH_MOUSE_LL are different from all the other hooks. They don't require a DLL to be injected into the target process. Instead, Windows calls your hook callback directly, inside your own process. To make that work, a message loop is required. There is no other mechanism for Windows to make callbacks on your main thread, the callback can only occur when you've called Get/PeekMessage() so that Windows is in control.
A global hook like WH_KEYBOARD is very different. It requires a DLL and the callback occurs within the process that processes the keyboard message. You need some kind of inter-process communication to let your own program be aware of this. Named pipes are the usual choice. Which otherwise of course requires that this injected process pumps a message loop. It wouldn't get keyboard messages otherwise.
Favor a low-level hook, they are much easier to get going. But do pump or it won't work. And beware of timeouts, if you're not responsive enough then Windows will kill your hook without notice.
Understanding the low-level mouse and keyboard hook (win32)

Windows Hooks hook the Windows message loop: http://msdn.microsoft.com/en-us/library/ms644959#wh_keyboardhook
The WH_KEYBOARD hook enables an application to monitor message traffic
for WM_KEYDOWN and WM_KEYUP messages about to be returned by the
GetMessage or PeekMessage function. You can use the WH_KEYBOARD hook
to monitor keyboard input posted to a message queue.
Console applications don't pump messages themselves - the console process does. So it won't work unless the process has a message loop.
See:
How can I set up a CBT hook on a Win32 console window?
C++ SetWindowsHookEx WH_KEYBOARD_LL Correct Setup

Related

Program stopps working at GetMessage() function

I'm pretty new to the Hook-Stuff and I'm trying to learn how to work with it. When I learn new stuff I usually copy Code from the Internet and see if it works - if yes i go into detail and search everything up. So with all Codes I tried I have the same issue. They stop working at the GetMessage() function. I'm working with Visual Studio - I debugged it and when it reaches the function it just does nothing but stays on it.
I tried it with several Codes - for example this one:
HMODULE lib = LoadLibrary("C:\\Users\\A\\Desktop\\Dll1.dll");
if (lib) {
HOOKPROC procedure = (HOOKPROC)GetProcAddress(lib, "_procedure#12");
if (procedure)
hook = SetWindowsHookEx(WH_CALLWNDPROC, procedure, lib, 0);
else
printf("Can't find function in dll!\n");
}
else
printf("Can't find dll!\n");
if (hook)
printf("Hook installed properly!\n\n");
MSG message;
while (GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
FreeLibrary(lib);
UnhookWindowsHookEx(hook);
It prints "Hook installed properly!" and does nothing! The code is from http://www.rohitab.com/discuss/topic/41238-global-hooks-to-intercept-windows-messages/
Unlike a mouse/keyboard hook, a window procedure hook runs in the context of a hooked thread that calls a window procedure. It does not delegate back to the thread that installed the hook, like you are expecting. That is why a window procedure hook must exist in a DLL when hooking other processes - the DLL gets injected into the address space of a hooked process, and then the hook is called by any hooked thread before/after it passes a message to a window procedure.
Your program that is installing the hook has no windows of its own, so no messages are being received. That is why GetMessage() blocks your app indefinitely. You would need to add a UI to your app, or have your hook manually post/send its own message back to your app using (Post|Send)Message() or PostThreadMessage(), in order to unblock GetMessage().
Your program is not going to receive messages unless it creates windows, hooks are delivered as part of the hooked program's message loop (that is why the hook function needs to be in a DLL for this situation).
The message queue is specific to the thread that created the window, posted messages are always going to be received on the thread that created the window, that is simply the way Windows operates.

Low level mouse hook - mouse freeze on breakpoint

I would like to draw and move my windows by myself (using chromium embedded framework).
To do this, i need a global callback when the mouse is being moved, outside of my window - so i installed a low level mouse hook:
hMouseLLHook = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)mouseHookProc, hInstance, NULL);
The hook simple grabs the mouse events and calls "CallNextHookEx". No problems here, everything works as excpected.
My problem now: if the debugger breaks or an exception is being thrown, I can't move the mouse anymore..
I tried processing the hook in another thread, like so:
HANDLE mouseProcHandle = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)mouseProcessor, NULL, NULL, &dwMouseProcThread);
DWORD WINAPI Win32Application::mouseProcessor(LPVOID lpParm) {
hMouseLLHook = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)mouseHookProc, ((Win32Application*)Application::getInstance())->hInstance, NULL);
MSG message;
while (GetMessage(&message, NULL, 0, 0)) {
TranslateMessage(&message);
DispatchMessage(&message);
}
UnhookWindowsHookEx(hMouseLLHook);
return 0;
}
But this also does not solve the problem. Is there a workaround, solution or another method to do this?
Also, I think a low level hook may not be necessary, as I only need to be informed about the moevement and it wouldn't be a problem if I would be the last one in line, so the system/other processes can process the mouse callbacks first.
To shed a little more light on this: When you intercept all mouse move events they all end up in your hook which can modify or swallow them. The system therefore calls for every mouse move event your hook and waits until your hook routine is done with it until it calls your hook again for the next pending mouse move event.
Guess what happens when you break into the debugger in your hook event? No more mouse events until you have stepped through your hook routine. Normally you could bring down your whole system with such a central hook. But luckily Windows did anticipate bad hooks. You will notice that after some timeout the system responds to mouse events again. My guess would be that Windows simply removes your hook when it does hang once.
Now about debugging: The only way to safely break into the debugger is to never touch the mouse after you are in the hook. Not very practical. The only way out is to trace the interesting things and look into your log file what did happen inside the hook.
If you are after example code how to hook mouse and keyboard events you can have a look here:
http://etwcontroler.codeplex.com/SourceControl/latest#ETWControler/Hooking/Hooker.cs
As your debugger stop the whole program (all threads of it)
there is probably no workaround if using the hook.
Not as accurate, but you could poll GetCursorPos in a thread instead.

Intercept WM_CLOSE for cleanup operations

I have an external application that calls my application and is supposed to end it when the job is done. The log from this external application claims it uses WM_CLOSE on my app.
How can I intercept the WM_CLOSE message in my application to do some cleanup operations? I tried at_exit() and wrapping it in a class, but I think I have the wrong approach.
The official solution for console applications is HandlerRoutine, a callback set by SetConsoleCtrlHandler. Windows will call your handler with a CTRL_CLOSE_EVENT argument in case of a WM_CLOSE exit.
When you're using a class method with SetConsoleCtrlHandler, it must be a static method - Windows won't provide you with a this pointer.
You could just handle WM_CLOSE in your message loop to do whatever cleanup is necessary, or even abort the close (by returning 1 instead of 0). See e.g. this: http://cboard.cprogramming.com/windows-programming/141438-handling-wm_close-wm_destroy.html#post1056273
Edit: for console applications, this may be of interest: http://support.microsoft.com/kb/178893
You must create hidden window using winapi, and handle WM_CLOSE message in its message loop. Is your app using any gui elements?
The easiest way I think is to call PeekMessage from time to time.
BOOL IsCloseEventReceived()
{
MSG msg;
return PeekMessage(&msg, NULL, WM_CLOSE, WM_CLOSE, PM_NOREMOVE);
}
This function should work to check if a WM_CLOSE message has been posted. It's not blocking, and you'll need to call it on a regular basis.
I might be wrong, but I think you don't need a hidden window to handle messages, a message queue is attached to your process the first time you call a messages-related function, like PeekMessage. However if you receive a WM_CLOSE message prior to your first call of this function it might be lost.

keep a formless application from closing for a keyboard hook

I am working on a c++ win32 program that involves a keyboard hook. The application is a win32 project with no user interface whatsoever. I need to keep the application from closing without using causing the hook to not work or use up a bunch of system resources. I used to use a message box but I need the application to be completely invisible.
Any help would be appreciated!
If you have any questions just ask.
I think what you need is message only window
(MSDN says) A message-only window enables you to send and receive messages. It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.
Do you really need windows?
The MSDN LowLevelKeyboardProc page recommends using a simple message loop.
Just insert this snippet after the hook call.
// message loop to keep the keyboard hook running
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
A better way would be to add an loop that keeps going around.
bool shouldExit = false;
do
{
//some code to handle events
shouldExit = handleEvents();
//sleep for a small bit so we dont take up 100% cpu
sleep(500);
}
while (!shouldExit);

CDialog not Receiving Windows Messages in ActiveX Control

I have an ActiveX control in MFC that manipulates images and I am trying to add TWAIN scanning functionality to it.
I need to be able to receive a Windows Message back from the TWAIN driver that tells my control when an image has been scanned, so I have created a CDialog and I pass the HWND of the Dialog to the driver.
ALl the sample code I have seen on the net then uses PreTranslateMessage to capture the message from TWAIN, but in my ActiveX control this method is never being called.
Does anyone know how I can get the messages for that Dialog? I have also tried using PeekMessage with no success.
Many Thanks
You don't need to create a CDialog. You just need any window to process the messages. Anything dealing with TWAIN is best handled in its own thread. So, create a new thread for MFC (via CWinThread or AfxBeginThread). In that thread, create a CWnd. The HWND of this CWnd is the one you will pass with all the calls to the DSM, etc. Each thread has its own message queue, so set one up in there. Communicate with that thread via PostMessage, SendMessage, PostThreadMessage, etc. Assuming you post a message MY_SPECIAL_MESSAGE to signal to being acquiring an image, your message loop should look something like this:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if (msg.message == MY_SPECIAL_MESSAGE)
{
GetImageFromTWAIN();
}
else if (!ProcessTWAINMessage(&msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Definitely look at the source code in the TWAIN development kit to see how this all works in detail. TWAIN is a tricky creature.
Trust me, this is the best approach. You can do it all in a single thread using your main thread's message queue, but it's to be avoided.