Global KeyboardHook Problem
Hi all, i have a global keyboardhook library being opened by my main program through my dll file. im using it so that whenever a user would hit a key combination they specify in the app, it would take a certain action that they specify. it works perfect except that whenever the user tries to hit any key, or deletes a file, or does anything related to windows explorer, explorer freezes. the only way i can unfreeze it is by terminating the program through task manager
anyone have any ideas why this is, i would much appreciate some insight on this
Are you sure a global keyboard hook is what you need? It sounds like you want to catch key combos in your app, not in every user mode process. Perhaps your hook is failing to pass key hits along to explorer.
sure because what if the user set key "Ctrl+F12" to be the key to automatically save a screenshot of a game they were playing to a directory of their choosing, wouldnt i have to have a global hook for that?
and i do CallNextHookEx() on every condition in the keyboardproc, so thats why im confused
and i do CallNextHookEx() on every condition in the keyboardproc, so thats why im confused
all my main program does is SetKeyboardHook, then goes into an infinite looping checking for GetHookState(), and loops out when GetHookState() == -1, then UnsetsKeyboardHook, terminates program
#include <windows.h>#pragma data_seg("SharedBlock") HINSTANCE hInst = NULL; HHOOK keyHook = NULL; int hookState = -1; char sequence[256];#pragma data_seg()#pragma comment(linker, "/section:SharedBlock,RWS")extern "C" __declspec (dllexport) int _stdcall GetHookState(){ return hookState;}extern "C" __declspec (dllexport) char* _stdcall GetKeySequence(){ return sequence;}extern "C" __declspec (dllexport) LRESULT CALLBACK __stdcall KeyboardProc(int code, WPARAM wParam, LPARAM lParam){ // dont do anything with these yet if ( (code < 0) || (wParam >= VK_F1 && wParam <= VK_F10)) { hookState = 1; return CallNextHookEx(keyHook, code, wParam, lParam); } // i temporarily have ctrl+f11 to set hookstate = -1 so that // i have a way of exiting infinite loop if ( (GetKeyState(VK_CONTROL) & 0x8000) && (GetKeyState(VK_F11) & 0x8000) ) { hookState = -1; return CallNextHookEx(keyHook, code, wParam, lParam); } // this is the button sequence to set hookstate to 0 (Ctrl + F12) // main program waits for hookstate to be 0 to determine action if ( (GetKeyState(VK_CONTROL) & 0x8000) && (GetKeyState(VK_F12) & 0x8000) ) { hookState = 0; //to let main program know user has entered ctrl+f12 key sequence sequence = "Ctrl+F12"; return CallNextHookEx(keyHook, code, wParam, lParam); } return CallNextHookEx(keyHook, code, wParam, lParam);}extern "C" int __declspec (dllexport) __stdcall SetKeyboardHook(){ keyHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInst, 0); if (keyHook == NULL) { hookState = -1; return -1; } else { hookState = 1; return 0; }}extern "C" int __declspec (dllexport) __stdcall UnsetKeyboardHook(){ //unhook UnhookWindowsHookEx(keyHook); hookState = -1; return 0;}extern "C" BOOL __declspec (dllexport) __stdcall DllMain (HINSTANCE hInstance, DWORD reason, LPVOID reserved){ switch (reason) { case DLL_PROCESS_ATTACH: { hInst = hInstance; break; } case DLL_PROCESS_DETACH: break; } return TRUE;}
Quote:Original post by Adam_42
You might want to try RegisterHotKey() for a simpler way to implement a global keyboard shortcut.
wow i didnt even realize there was a function like that, thanks this helps a bunch
Regarding your code, it might crash on ctrl+f12 because of the string
sequence = "Ctrl+F12";
The string on the right hand side is stored in the dll and the values of each character are hopefully transferred in the assignment to the shared sequence array variable. If that doesn't happen. If sequence is simply made to point to the string literal, then even though that string literal is stored in the dll and even though the dll is loaded into both your hook launcher app and the target app, you might get an error because the dll isn't loaded into the same address in both programs. When crossing process boundary lines, it's important to remember that each process has it's own memory address space and that a particular dll doesn't always load at the same address in every process. That means that passing string literals between process isn't a good idea. An address that is valid in one process is not guaranteed to be valid in every other process.
If the assignment of the string literal operates as a complete copy (ala old fashioned strcpy), it should work.
If you're not sure, the WM_COPYDATA message can be used to transfer string data between processes. For an idea of how to send that message from inside a hook dll, check out this demo I wrote a few years ago: GlobalMessageHook.
And since you're applying a kb hook, consider using the low level hook, WH_KEYBOARD_LL, it lets you get away with more, as this demo, keylog, shows. It lets you hook into the kb without having to fuss with a dll.
sequence = "Ctrl+F12";
The string on the right hand side is stored in the dll and the values of each character are hopefully transferred in the assignment to the shared sequence array variable. If that doesn't happen. If sequence is simply made to point to the string literal, then even though that string literal is stored in the dll and even though the dll is loaded into both your hook launcher app and the target app, you might get an error because the dll isn't loaded into the same address in both programs. When crossing process boundary lines, it's important to remember that each process has it's own memory address space and that a particular dll doesn't always load at the same address in every process. That means that passing string literals between process isn't a good idea. An address that is valid in one process is not guaranteed to be valid in every other process.
If the assignment of the string literal operates as a complete copy (ala old fashioned strcpy), it should work.
If you're not sure, the WM_COPYDATA message can be used to transfer string data between processes. For an idea of how to send that message from inside a hook dll, check out this demo I wrote a few years ago: GlobalMessageHook.
And since you're applying a kb hook, consider using the low level hook, WH_KEYBOARD_LL, it lets you get away with more, as this demo, keylog, shows. It lets you hook into the kb without having to fuss with a dll.
Just for future reference, i learned that since i was using a 32-bit dll, i was going to encounter issues on a 64-bit machine, which is probably why explorer crashes. So i went to test it on my 32-bit xp machine and it works perfect
Now that i have compiled my dll/program in 64-bit, my application just crashes, it always sais something about failed to read memory location etc..
any thoughts?
----EDIT
I found the solution to my problem yet im not going to attempt a solution atm. Its not just that my OS is a 64-bit process, any 64-bit process will freeze with my 32-bit hook dll.
The solution is to write a 32-bit and 64-bit dll, each one checking the process of the currently selected application, if they are not the same process (32-bit or 64-bit) then do nothing.
[Edited by - b1gjo3 on July 10, 2009 7:34:22 PM]
Now that i have compiled my dll/program in 64-bit, my application just crashes, it always sais something about failed to read memory location etc..
any thoughts?
----EDIT
I found the solution to my problem yet im not going to attempt a solution atm. Its not just that my OS is a 64-bit process, any 64-bit process will freeze with my 32-bit hook dll.
The solution is to write a 32-bit and 64-bit dll, each one checking the process of the currently selected application, if they are not the same process (32-bit or 64-bit) then do nothing.
[Edited by - b1gjo3 on July 10, 2009 7:34:22 PM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement