无法拦截右键单击事件

时间:2015-08-07 12:16:46

标签: c++ windows winapi

我需要在Windows中拦截具有特定标题的Windows中的右键单击事件,因此我决定使用SetWindowsHookExA函数和WH_MOUSE参数,如下所示:

启动此流程的应用程序

#include <Windows.h>

#include <cstdlib>
#include <iostream>

int main()
{
  HMODULE hook_dll_handle = LoadLibraryA("hook_dll.dll");
  if (hook_dll_handle == NULL)
  {
    std::cerr << "Unable to load \"hook_dll.dll\". Error code: " << GetLastError() << std::endl;
    return EXIT_FAILURE;
  }

  auto mouse_hook = (HOOKPROC)GetProcAddress(hook_dll_handle, "mouse_hook");
  if (mouse_hook == NULL)
  {
    std::cerr << "Unable to get \"mouse_hook\" function's address. Error code: " << GetLastError() << std::endl;
    return EXIT_FAILURE;
  }

  HHOOK hook = SetWindowsHookExA(WH_MOUSE, mouse_hook, hook_dll_handle, 0);
  if (hook == NULL)
  {
    std::cerr << "Unable to set hook. Error code: " << GetLastError() << std::endl;
    return EXIT_FAILURE;
  }

  std::cin.get();

  if (UnhookWindowsHookEx(hook) == 0)
  {
    std::cerr << "Unable to unhook mouse_hook. Error code: " << GetLastError() << std::endl;
    return EXIT_FAILURE;
  }
}
带挂钩功能的

DLL

#include "stdafx.h"

BOOL APIENTRY DllMain(
  HMODULE hModule,
  DWORD  ul_reason_for_call,
  LPVOID lpReserved
)
{
  switch (ul_reason_for_call)
  {
  case DLL_PROCESS_ATTACH:
  case DLL_PROCESS_DETACH:
  case DLL_THREAD_ATTACH:
  case DLL_THREAD_DETACH:
    break;
  }
  return TRUE;
}

extern "C"
{
  __declspec(dllexport) LRESULT CALLBACK mouse_hook(int code, WPARAM wParam, LPARAM lParam)
  {
    return CallNextHookEx(NULL, code, wParam, lParam);
  }
}

不幸的是,它没有按预期工作。它挂起整个explorer.exe或在不同平台上执行其他类型的操作。

我做错了什么?我该如何解决?

提前致谢。

1 个答案:

答案 0 :(得分:2)

您需要一个消息循环,现在有std::cin.get()

请参阅MouseProc documentation

中的备注
  

可以在安装它的线程的上下文中调用此挂钩。通过向安装了挂钩的线程发送消息来进行调用。 因此,安装钩子的线程必须有一个消息循环。

哦,如果您不想使用dll,可以使用WH_MOUSE_LL,这是在您自己的应用程序的上下文中调用的。

请参阅:https://stackoverflow.com/a/872720/4928207