Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
477 views
in Technique[技术] by (71.8m points)

winapi - How to make a keyboard hook global across processes

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

I figured out how to get the keyboard callback, but for whatever reason once I click into another app, my keystroke util receives no more keys. Even if I click back to my console window or msvc, I will not receive any input. This is 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);
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...