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.
Related
I have tried doing things like...
const char *MessageBoxText = "";
DWORD WINAPI CreateMessageBox(LPVOID lpParam){
MessageBox(NULL, MessageBoxText, "", MB_OK|MB_APPLMODAL);
return TRUE;
}
MessageBoxText = "Blah, Blah, Blah...";
CreateThread(NULL, 0, &CreateMessageBox, NULL, 0, NULL);
However, this does not seem to work correctly for the task I am trying to perform.
What is the best way to create a thread for a message box, without having it glitch up?
Consider passing message text as thread parameter instead of global variable, to make code thread-safe.
DWORD WINAPI CreateMessageBox(LPVOID lpParam) {
MessageBoxA(NULL, (char*)lpParam, "", MB_OK);
return 0;
}
CreateThread(NULL, 0, &CreateMessageBox, "Blah, Blah, Blah...", 0, NULL);
Also, you don't need to specify MB_APPLMODAL as it's default flag (it equals to 0).
If you are targeting modern Windows OS, it's better to have UNICODE defined, because MessageBoxA will convert you strings to UTF-16 and call MessageBoxW
What is the best way to create a thread for a message box, without having it glitch up?
In general, you don't.
Under Windows, all the windows (small 'w', meaning individual GUI elements here) in an application "run" in a single thread. This is generally the "main" thread -- but in particular, it is the thread in which the message pump is running. See my linked post for more details on the message pump.
If what you are truly trying to achieve is a dialog box or some other kind of window that can run concurrently to other windows running, so that it can remain up while other windows are still responsive to user input, then you want a modeless window or dialog box. This is a window that doesn't block other windows from processing updates or accepting user input. See here for a description of how to implement this using MFC, but note that you don't need to use MFC in order to implement a modeless dialog box.
Old question, new answer...
If the thread being invoked is being called into existence by a process that immediately exits (say you're running an executable that uses a VC++ DLL which pops a message box) then the thread will never have a chance to execute.
I had created a VC++ executable for testing that ran a loadlibrary on my DLL and the DLL created various threads with debugging message boxes. Since my testing executable only called the DLL and then exited, it didn't work.
I was informed by a coworker that I needed to add a sleep to the end of the testing executable that is using the DLL file in order for it to work.
Sure enough, it fixed it. This makes sense too, especially in the context of a DLL. Most applications loop until instructed to exit; my test application did not.
Be mindful of how your application is behaving!
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
I have a windowless application whose only purpose is to install a 32 bit hook DLL file and wait until the parent program (a 64-bit program) exits. The 64-bit program is written in C#, and the windowless application is written in C++. I originally had this GetMessage loop which held the program open:
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
I was closing the C++ application using the Process.Kill method in C#, but I found out that that isn't allowing the C++ application to close cleanly. Also, if the C# application crashed, the C++ application would stay open forever. I made the C++ application check to see if the C# application is still running, using this loop:
while(true)
{
if(PeekMessage(&msg, NULL, 0, 0, true))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(!isMainProgramRunning())
break;
Sleep(1000);
}
For some reason the Sleep causes problems. The hooks installed by the DLL file are WH_CBT and WH_KEYBOARD. Whenever I press a key while the C++ application is running with this loop, the keys just get eaten up. Removing the Sleep makes it work fine, but, as expected, it uses 100% CPU, which I don't want. I tried removing the message loop altogether and instead using WaitForSingleObject with an infinite timeout on a thread which would end when isMainProgramRunning returned false. This basically locks up the whole computer.
I don't really understand why GetMessage, which, as far as I saw, never returned, but suspended the main thread indefinitely, didn't cause these problems yet WaitForSingleObject causes every application to freeze when I click on it. How can I get the C++ application to stay open until the C# application closes?
Edit:
Since it's been pointed out to me that sleeping in a message pump is bad, let me ask this: Is there a way to specify a timeout on the message waiting, so the program isn't waiting indefinitely for a message, but rather, will wait about 250 ms, timeout, let me run the isMainProgramRunning method, then wait some more?
Edit2:
I tried using MsgWaitForMultipleObjects, although in a somewhat different way than Leo suggested. This is the loop I used:
while(MsgWaitForMultipleObjects (0, NULL, true, 250, QS_ALLPOSTMESSAGE) != WAIT_FAILED)
{
if(PeekMessage(&msg, NULL, 0, 0, true))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(!isMainProgramRunning())
break;
}
Again I had the same problem with the Sleep. I also tried suspending the main thread and having the other thread resume it. Same problem. What is it that GetMessage does that allows it to wait without causing these problems? Maybe this should be the subject of another post, but why is it that when the C++ application installing the hooks sleeps or is suspended, all processing in the hooks seems to suspend as well?
Edit3:
Here is the DLL method that the C++ application calls to install the hooks:
extern "C" __declspec(dllexport) void install()
{
cbtHook = SetWindowsHookEx(WH_CBT, hookWindowEvents, hinst, NULL);
if(cbtHook == NULL)
MessageBox(NULL, "Unable to install CBT hook", "Error!", MB_OK);
keyHook = SetWindowsHookEx(WH_KEYBOARD, LowLevelKeyboardProc, hinst, NULL);
if(keyHook == NULL)
MessageBox(NULL, "Unable to install key hook", "Error!", MB_OK);
}
You have two separate problems:
How to make the windowless C++ program exit automatically if the C# program exits (e.g. crashes).
In the C++ program, open a handle to the C# program. Since the C# program runs the C++ program, have the C# program pass its own PID as an argument; the C++ program can then open a handle to that process using OpenProcess.
Then use MsgWaitForMultipleObjects in your message loop. If the C# program exits the handle you have to it will be signalled and you will wake up. (You can also use WaitForSingleObject(hProcess,0)==WAIT_OBJECT_0 to check if the process is signalled or not, e.g. to verify why you were woken up, although the MsgWaitForMultipleObjects result will tell you that as well.)
You should close the process handle as you are exiting (although the OS will do it for you when you exit, it's good practice in case you re-use this code in a different context). Note that the handle outlives the process it represents, and that is why you can wait on it.
How to make the C# program instruct the C++ program to exit.
You may not need this if you get #1 working, but you could just have the C# program post a message to the C++ one if you want.
Do NOT use PostQuitMessage and do NOT post or send WM_QUIT across threads or processes.
Instead, post some other message that the two apps agree on (e.g. WM_APP+1) using PostThreadMessage.
You can create a named event and use:
MsgWaitForMultipleObjects
in your message loop.
The C# application only have to open and raise this event to tell your application to exit.
It's kind of minimal interprocess communication.
You should exit the process by posting a WM_QUIT message to it and handling it correctly, as specified in this article (Modality), by Raymond Chen. Don't sleep inside a loop without handling messages - it's wrong. Your app should either be handling a message or waiting for new messages.
GetMessage never returns is because you don't have a window created!
To use a message-queue you have to have some GUI. You Can for instance create a hidden window.
If my application crashes, I use an ExceptionFilter to catch the crash, perform some final actions, then show a message box to the user that the application has crashed.
Because the application already crashed, there's not much I can (or I dare) to do, because if I do too much, the executed code might access corrupted memory and crash again.
Some of the things I currently can't do (or I don't dare to do) is to close network connections, Oracle database sessions, ...
Problem is that if an application crashes, and the user is out to lunch while the MessageBox is open, other users might be blocked, because of the open database session. Therefore I want:
Either a MessageBox with a time-out. Problem is that you can't do this with the standard MessageBox Win32 API function, and I don't want to make a specific dialog for it (because I want to minimize the executed logic after the crash)
Or the possibility to close the MessageBox from another thread (the other thread can provide the time-out logic).
Did I overlook something in the Win32 API and is there a possibility to have a MessageBox with a time-out?
Or what is the correct way to close an open MessageBox from another thread (how to get the MessageBox handle, how to close it, ...)?
While I agree that spawning a new process to display a fire-and-forget dialog is probably best, FWIW there is actually a timeoutable messagebox function exported from user32 on XP & above; MessageBoxTimeout (as used by things like WShell.Popup())
Quick copy/paste solution:
int DU_MessageBoxTimeout(HWND hWnd, const WCHAR* sText, const WCHAR* sCaption, UINT uType, DWORD dwMilliseconds)
{
// Displays a message box, and dismisses it after the specified timeout.
typedef int(__stdcall *MSGBOXWAPI)(IN HWND hWnd, IN LPCWSTR lpText, IN LPCWSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
int iResult;
HMODULE hUser32 = LoadLibraryA("user32.dll");
if (hUser32)
{
auto MessageBoxTimeoutW = (MSGBOXWAPI)GetProcAddress(hUser32, "MessageBoxTimeoutW");
iResult = MessageBoxTimeoutW(hWnd, sText, sCaption, uType, 0, dwMilliseconds);
FreeLibrary(hUser32);
}
else
iResult = MessageBox(hWnd, sText, sCaption, uType); // oups, fallback to the standard function!
return iResult;
}
You should ask yourself, why you want a messagebox in the first place. When it is OK that the message box is not seen when noone is sitting in front of the computer, why isn't it OK that the user doesn't see a message when his program disappears?
If you really want it, I think the simplest solution is to spawn a new process displaying the message. It can run as long as it wants and does not interfer with your crashing program.
I noticed that if the main thread simply exits the application while the other thread still has the ::MessageBox open, that the MessageBox is being adopted by a process called CSRSS. This solves my problem, since this only requires a time-out on the Event in the main thread (WaitForSingleObject with timeout).
However, this raised another question: https://stackoverflow.com/questions/3091915/explanation-why-messagebox-of-exited-application-is-adopted-by-winsrv.
This does not justify a thread.
The best solution would be to use a modal dialog box that registers a timer for auto-close.
What about just logging the event to a local file (and record memory dumps or whatever information you might need for later debugging)?
You could close your application, close network connections and do your housekeeping stuff.
As soon as the application is started again, you can inform your user (based on local file information) that the application has crashed during last execution.
A Win32 MessageBox really is a dialog, with a dialog message pump. You can therefore rely on standard Win32 timer messages (WM_TIMER). Send one to your own window, and when you do get it, dismiss the MessageBox by sending a WM_COMMAND/BN_CLICKED message to the ID_OK button.
The messagebox, since it's a dialog, will be class "#32770". Since it's the only dialog box you will have open, it's easy to find amongst your child windows.
I would run your original code from inside a wrapper application that does a CreateProcess and then a MsgWaitForMultipleObjects on the process handle (most process launching code samples use WaitForSingleObject, but you need to guard against messaging deadlock scenarios). Your watching process can then detect the failure of the spawned process, pop up its own timed-out dialog, and exit on user response or timeout.
I think that's the cleanest solution which prevents your unstable program having to execute any code.
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.