当前位置:  开发笔记 > 开发工具 > 正文

如何使键盘挂钩跨进程全局

如何解决《如何使键盘挂钩跨进程全局》经验,为你挑选了2个好方法。

我正在尝试创建一个实用程序按键应用程序,以便我可以执行诸如杀死预编程进程或启动某些内容之类的操作.我想我应该在任何应用程序中持有cmd,然后输入一个4位数的命令键,这样我就可以在编程,调试观看视频等时快速启动或杀死任何内容.

我想出了如何获得键盘回调,但无论出于何种原因,一旦我点击进入另一个应用程序,我的keystroke util就不再接收键.即使我点击回到我的控制台窗口或msvc,我也不会收到任何输入.这是除非它的全局,所以如何设置钩子是全局的?

我的代码是

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

Ferruccio.. 12

为了能够从所有进程访问您的键盘钩子,它必须放在一个DLL中,然后将其加载到每个进程的地址空间.需要记住的一件重要事情是,由于DLL的每个实例都是在一个单独的进程中加载​​的,因此每个DLL都有自己的全局变量副本.如果需要在这些实例之间共享数据,最简单的方法是在DLL中创建共享数据段.以下代码来自我写的RSI监控程序.

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


小智.. 5

避免使用codeproject样本.(大量的错误,MSDN的错误副本)

在钩子上查看MSDN上的大量完整样本(MSDN,SDK,KB等)

而且你不需要任何DLL,只需使用LL钩子



1> Ferruccio..:

为了能够从所有进程访问您的键盘钩子,它必须放在一个DLL中,然后将其加载到每个进程的地址空间.需要记住的一件重要事情是,由于DLL的每个实例都是在一个单独的进程中加载​​的,因此每个DLL都有自己的全局变量副本.如果需要在这些实例之间共享数据,最简单的方法是在DLL中创建共享数据段.以下代码来自我写的RSI监控程序.

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



2> 小智..:

避免使用codeproject样本.(大量的错误,MSDN的错误副本)

在钩子上查看MSDN上的大量完整样本(MSDN,SDK,KB等)

而且你不需要任何DLL,只需使用LL钩子

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有