使用钩子 (SetWindowsHookEX & WH_GETMESSAGE)
Working with hooks (SetWindowsHookEX & WH_GETMESSAGE)
我将从描述我的确切需求和原因开始。
我正在库 (dll) 中制作游戏内界面,我需要能够接收和删除消息(防止目标进程接收消息),具体取决于代码中的不同条件。
除了鼠标和键盘的消息外,我不需要任何其他东西。为此,有两种方法。找到一种可以让我从鼠标和键盘接收消息的钩子,或者在鼠标和键盘上放置两个单独的钩子,但是代码会比一个钩子多得多。
我决定采用第一种方式,在创建 window 的线程的消息上放置一个 WH_GETMESSAGE
钩子。但是,我试图阻止该消息没有成功。
LRESULT CALLBACK messageHandler(int nCode, WPARAM wParam, LPARAM lParam)
{
return -1; // This works fine with WH_MOUSE or WH_KEYBOARD, but for some reason, with the WH_GETMESSAGE hook, the process still receives a message
}
DWORD WINAPI messageDispatcher(LPVOID thread)
{
hookHandle = SetWindowsHookEx(WH_GETMESSAGE, messageHandler, GetModuleHandle(nullptr), *reinterpret_cast<DWORD*>(thread));
if (!hookHandle)
{
return GetLastError();
}
MSG message{};
while (GetMessage(&message, 0, 0, 0) > 0)
{
TranslateMessage(&message);
DispatchMessage(&message);
}
return 0;
}
我不确定 WH_GETMESSAGE
是否适合我。也许更有经验的程序员会告诉我,最好使用两个钩子 WH_MOUSE
和 WH_KEYBOARD
,而不是使用 WH_GETMESSAGE
.
但是,尽管如此,如果使用WH_GETMESSAGE
不是一个坏主意,那么请帮助我实现它,以便我可以控制进程对某些消息的接收(不要让它们被看到通过过程)。
I decided to go the first way and put the WH_GETMESSAGE hook on the messages of the thread that created the window. However, my attempts to block the message were unsuccessful.
根据文档,WH_GETESSAGE
挂钩不能阻止消息,只能阻止 view/modify 消息。当钩子退出时,消息总是传递给目标线程:
The GetMsgProc hook procedure can examine or modify the message. After the hook procedure returns control to the system, the GetMessage or PeekMessage function returns the message, along with any modifications, to the application that originally called it.
另一方面,WH_MOUSE/_LL
和 WH_KEYBOARD/_LL
挂钩可以根据各自的文档阻止消息:
LowLevelMouseProc callback function
KeyboardProc callback function
LowLevelKeyboardProc callback function
If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.
因此...
Perhaps much more experienced programmers will tell me that it is better to do, for example, two hooks, WH_MOUSE and WH_KEYBOARD, rather than using WH_GETMESSAGE.
您确实需要使用单独的 WH_MOUSE
/WH_KEYBOARD
挂钩。
我将从描述我的确切需求和原因开始。
我正在库 (dll) 中制作游戏内界面,我需要能够接收和删除消息(防止目标进程接收消息),具体取决于代码中的不同条件。
除了鼠标和键盘的消息外,我不需要任何其他东西。为此,有两种方法。找到一种可以让我从鼠标和键盘接收消息的钩子,或者在鼠标和键盘上放置两个单独的钩子,但是代码会比一个钩子多得多。
我决定采用第一种方式,在创建 window 的线程的消息上放置一个 WH_GETMESSAGE
钩子。但是,我试图阻止该消息没有成功。
LRESULT CALLBACK messageHandler(int nCode, WPARAM wParam, LPARAM lParam)
{
return -1; // This works fine with WH_MOUSE or WH_KEYBOARD, but for some reason, with the WH_GETMESSAGE hook, the process still receives a message
}
DWORD WINAPI messageDispatcher(LPVOID thread)
{
hookHandle = SetWindowsHookEx(WH_GETMESSAGE, messageHandler, GetModuleHandle(nullptr), *reinterpret_cast<DWORD*>(thread));
if (!hookHandle)
{
return GetLastError();
}
MSG message{};
while (GetMessage(&message, 0, 0, 0) > 0)
{
TranslateMessage(&message);
DispatchMessage(&message);
}
return 0;
}
我不确定 WH_GETMESSAGE
是否适合我。也许更有经验的程序员会告诉我,最好使用两个钩子 WH_MOUSE
和 WH_KEYBOARD
,而不是使用 WH_GETMESSAGE
.
但是,尽管如此,如果使用WH_GETMESSAGE
不是一个坏主意,那么请帮助我实现它,以便我可以控制进程对某些消息的接收(不要让它们被看到通过过程)。
I decided to go the first way and put the WH_GETMESSAGE hook on the messages of the thread that created the window. However, my attempts to block the message were unsuccessful.
根据文档,WH_GETESSAGE
挂钩不能阻止消息,只能阻止 view/modify 消息。当钩子退出时,消息总是传递给目标线程:
另一方面,The GetMsgProc hook procedure can examine or modify the message. After the hook procedure returns control to the system, the GetMessage or PeekMessage function returns the message, along with any modifications, to the application that originally called it.
WH_MOUSE/_LL
和 WH_KEYBOARD/_LL
挂钩可以根据各自的文档阻止消息:
LowLevelMouseProc callback function
KeyboardProc callback function
LowLevelKeyboardProc callback function
If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.
因此...
Perhaps much more experienced programmers will tell me that it is better to do, for example, two hooks, WH_MOUSE and WH_KEYBOARD, rather than using WH_GETMESSAGE.
您确实需要使用单独的 WH_MOUSE
/WH_KEYBOARD
挂钩。