如何设置系统范围的挂钩来监听 WM_DEVICECHANGE?
How do I setup a systemwide hook to listen for WM_DEVICECHANGE?
我想在 C++ 中设置一个系统范围的钩子来监听 WM_DEVICECHANGE
。我知道挂钩是使用 SetWindowsHookEx()
设置的。我以前对键盘消息 (WM_KEYUP
、WM_KEYDOWN
) 这样做过,但我想对 WM_DEVICECHANGE
这样做。我目前正在使用:
#include <windows.h>
#include <tchar.h>
#include <iostream>
void WinHook();
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);
int _tmain(int argc, _TCHAR* argv[])
{
WinHook();
std::cout << GetLastError() << " winhook\n";
return 0;
}
void WinHook()
{
HHOOK hook = NULL;
hook = SetWindowsHookEx(WH_GETMESSAGE, HookProc, NULL, GetCurrentThreadId());
std::cout << GetLastError() << " sethook\n";
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam){
std::cout << GetLastError() << " hookproc called\n";
switch (wParam){
case WM_DEVICECHANGE: std::cout << "SUCCESS!!!!!"; break;
default: return CallNextHookEx(NULL, nCode, wParam, lParam);
}
}
编辑:
SetWindowsHookEx()
returns 0 之后的 GetLasterror()
和函数 HookProc()
中的那一个永远不会被调用。
您正在为您自己的线程正在接收的所有消息安装 WindowsHook。
您的程序没有打开任何 window,它没有收到任何消息。所以钩子不会被调用。
正如其中一条评论所述,您需要创建(可能隐藏的)顶层 window 和 RegisterDeviceNotification
,您不需要挂钩。
另一种方法是安装系统范围的挂钩,但这需要额外的 DLL 和桌面上的任何其他顶级 window,而且更复杂,更耗资源。
尝试为此使用挂钩是错误的。
正确的做法是使用window来接收消息。如果手头有的话,也许是顶级 window。或者只有一条消息 window。顶级 windows 将收到基本通知。或者使用 RegisterDeviceNotification
和仅 window 的消息来接收更全面的通知。
我想在 C++ 中设置一个系统范围的钩子来监听 WM_DEVICECHANGE
。我知道挂钩是使用 SetWindowsHookEx()
设置的。我以前对键盘消息 (WM_KEYUP
、WM_KEYDOWN
) 这样做过,但我想对 WM_DEVICECHANGE
这样做。我目前正在使用:
#include <windows.h>
#include <tchar.h>
#include <iostream>
void WinHook();
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);
int _tmain(int argc, _TCHAR* argv[])
{
WinHook();
std::cout << GetLastError() << " winhook\n";
return 0;
}
void WinHook()
{
HHOOK hook = NULL;
hook = SetWindowsHookEx(WH_GETMESSAGE, HookProc, NULL, GetCurrentThreadId());
std::cout << GetLastError() << " sethook\n";
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam){
std::cout << GetLastError() << " hookproc called\n";
switch (wParam){
case WM_DEVICECHANGE: std::cout << "SUCCESS!!!!!"; break;
default: return CallNextHookEx(NULL, nCode, wParam, lParam);
}
}
编辑:
SetWindowsHookEx()
returns 0 之后的 GetLasterror()
和函数 HookProc()
中的那一个永远不会被调用。
您正在为您自己的线程正在接收的所有消息安装 WindowsHook。
您的程序没有打开任何 window,它没有收到任何消息。所以钩子不会被调用。
正如其中一条评论所述,您需要创建(可能隐藏的)顶层 window 和 RegisterDeviceNotification
,您不需要挂钩。
另一种方法是安装系统范围的挂钩,但这需要额外的 DLL 和桌面上的任何其他顶级 window,而且更复杂,更耗资源。
尝试为此使用挂钩是错误的。
正确的做法是使用window来接收消息。如果手头有的话,也许是顶级 window。或者只有一条消息 window。顶级 windows 将收到基本通知。或者使用 RegisterDeviceNotification
和仅 window 的消息来接收更全面的通知。