FrozenHeart
FrozenHeart

Reputation: 20764

Unable to intercept the right-click event

I need to intercept the right-click event from the windows with the specific title in Windows, so I decided to use SetWindowsHookExA function with the WH_MOUSE argument like this:

Application that launches thus process

#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 with the hook function

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

Unfortunately it doesn't work as expected. It hangs the whole explorer.exe or do the other kind of stuff on the different platforms.

What am I doing wrong? How can I fix it?

Thanks in advance.

Upvotes: 0

Views: 137

Answers (1)

Mark Jansen
Mark Jansen

Reputation: 1509

You need a message loop where you have std::cin.get() now.

See the Remarks in the 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.

Oh, and in case you don't want to use a dll, you can use the WH_MOUSE_LL, which is called in the context of your own application.

See: https://stackoverflow.com/a/872720/4928207

Upvotes: 2

Related Questions