Reputation: 20764
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
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