c++ - 无法拦截右键事件

标签 c++ windows winapi

我需要拦截来自 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;
  }
}

带钩子(Hook)函数的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 或在不同的平台上执行其他类型的操作。

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

提前致谢。

最佳答案

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

请参阅 MouseProc documentation 中的备注:

This hook may be called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.

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

参见:https://stackoverflow.com/a/872720/4928207

关于c++ - 无法拦截右键事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31877523/

相关文章:

c++ - optarg 设置为空

c++ - 将代码从一个类移动到一个新类时出现问题?

windows - 为什么有些程序在使用调试器时可以运行,但在运行正常的调试执行时却不行?

windows - 200 端口命令成功。考虑使用 PASV。 425 建立连接失败

c++ - C++ 中的嵌入式资源

windows - 当两个路径可能是相对路径时,将路径与 Windows API 组合

c++ - 如何在 printf 中显示我的源代码的行号

c# - 如何在 Visual Studio 2010 中设置环境变量?

winapi - x86 程序集 (masm32) - 我可以在 Windows XP 上使用 int 21h 来打印内容吗?

c++ - 在另一台电脑上执行程序时加载 SDL2 共享库时出错