views:

1637

answers:

4

so i am trying to create a util keystroke app so i can do things like kill or launch something. I am thinking i should hold cmd in any app, then type in a 4 digi cmd key so i can launch or kill anything quickly while programming, debugging watching a vid, etc.

I figured out how to get the keyboard callback but for whatever reason once i click into another app my keystroke util recv no more keys. Even if i click back to my console window or msvc i'll will not recv input. This is unless unless its global so how do i set the hook to be global? my code is

int main()
{
hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, GetModuleHandle(0), 0);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
 TranslateMessage(&msg);
 DispatchMessage(&msg);
}
UnhookWindowsHookEx(hook);
}
A: 

Re-read the introduction to hooks in the Win32 guide. (A good place to start is here.)

Specifically, if you want to hook events in other processes, you need to place your callback in a DLL, which is injected into other processes by Win32. From the code you've supplied, I can't tell if KeyboardProc is in a DLL or in the main program. It doesn't look like it, considering the HINSTANCE you're passing.

Jim Nelson
A: 

I had to mess with global hooks when I was writing a "Picture in Picture" sort of app. This article and sample code helped me out tremendously:

http://www.codeproject.com/KB/system/WilsonSystemGlobalHooks.aspx

David Brown
+6  A: 

In order for your keyboard hook to be accessible from all processes, it has to be placed in a DLL which will then be loaded into each process' address space. One important thing to keep in mind is that since each instance of the DLL is loaded in a separate process, each will have its own copy of any global variables in the DLL. If you need to share data between these instances, the simplest way is to create a shared data segment in the DLL. The following code is from an RSI monitoring program I wrote.

//
// some data will be shared across all
// instances of the DLL
//
#pragma comment(linker, "/SECTION:.SHARED,RWS")
#pragma data_seg(".SHARED")
int iKeyCount = 0;
HHOOK hKeyboardHook = 0;
HHOOK hMouseHook = 0;
#pragma data_seg()

//
// instance specific data
//
HMODULE hInstance = 0;

//
// DLL load/unload entry point
//
BOOL APIENTRY DllMain(HANDLE hModule, 
                      DWORD  dwReason, 
                      LPVOID lpReserved)
{
   switch (dwReason)
   {
   case DLL_PROCESS_ATTACH :
      hInstance = (HINSTANCE) hModule;
      break;

   case DLL_THREAD_ATTACH :
      break;

   case DLL_THREAD_DETACH :
      break;

   case DLL_PROCESS_DETACH :
      break;
   }
   return TRUE;
}

//
// keyboard hook
//
LRESULT CALLBACK KeyboardProc(int code,       // hook code
                              WPARAM wParam,  // virtual-key code
                              LPARAM lParam)  // keystroke-message information
{
   if ((lParam & 0x80000000) != 0)
   {
      ++iKeyCount;
   }
   return CallNextHookEx(hKeyboardHook, code, wParam, lParam);
}

//
// mouse hook
//
LRESULT CALLBACK MouseProc(int code,       // hook code
                           WPARAM wParam,  // message identifier
                           LPARAM lParam)  // mouse coordinates
{
   switch (wParam)
   {
   case WM_LBUTTONDOWN :
   case WM_MBUTTONDOWN :
   case WM_RBUTTONDOWN :
   case WM_LBUTTONDBLCLK :
   case WM_MBUTTONDBLCLK :
   case WM_RBUTTONDBLCLK :
      ++iKeyCount;
      break;
   }
   return CallNextHookEx(hMouseHook, code, wParam, lParam);
}

//
// install keyboard/mouse hooks
//
void KBM_API InstallHooks(void)
{
   hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInstance, 0);
   hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, hInstance, 0);
}

//
// remove keyboard/mouse hooks
//
void KBM_API RemoveHooks(void)
{
   UnhookWindowsHookEx(hKeyboardHook);
   UnhookWindowsHookEx(hMouseHook);
   hKeyboardHook = hMouseHook = 0;
}

//
// retrieve number of keystrokes
//
int KBM_API FetchKeyCount(bool bClear)
{
   int kc = iKeyCount;
   if (bClear)
      iKeyCount = 0;
   return kc;
}
Ferruccio
+2  A: 

Avoid codeproject samples. ( plenty of bugs, bad copies of MSDN )

See the tons of complete samples on MSDN on hooks (MSDN, SDK, KB, etc)

And you don't need any DLL, just use LL hooks

Just as fair warning: I think the DLL-less WH_KEYBOARD_LL hook didn't work until Windows XP, and some people need to support older versions. In principle, though, you're exactly right.
Tadmas