【发布时间】:2016-12-08 23:45:49
【问题描述】:
对于如何通过用户插入设备(USB、HID 等)的事件来通知我的 c++ 应用程序,我有点困惑。应用程序类型未定义。我正在尝试使用控制台/仅消息/服务示例应用程序,但没有结果。我正在使用 VS2015 和 Windows 10。
我发现有多种方法来处理它:
- 使用 WMI,如 here。但我实际上无法理解 WMI 在哪里。
-
使用 RegisterDeviceNotification 和 WM_DEVICECHANGE。据我所知,控制台应用程序无法做到这一点,只能使用 GUI(真实窗口)或仅消息窗口进行一次。我已经用this answer 的示例尝试了最后一个,但是当我插入我的 USB 闪存驱动器时,我的应用程序没有收到任何通知。我找到了this answer(来自与上述答案相同的问题)并尝试使用 ChangeWindowMessageFilterEx() 函数和 user32.dll 中的 GetProcAddress 以这种方式在没有将 dll 连接到我的应用程序的情况下加载它:
BOOL InitInstance(HWND hWnd) { HMODULE hDll = GetModuleHandle(TEXT("user32.dll")); if (hDll) { typedef BOOL(WINAPI *MESSAGEFILTERFUNCEX)(HWND hWnd, UINT message, DWORD action, VOID* pChangeFilterStruct); const DWORD MSGFLT_ALLOW = 1; MESSAGEFILTERFUNCEX ChangeWindowMessageFilterEx= (MESSAGEFILTERFUNCEX)::GetProcAddress(hDll, "ChangeWindowMessageFilterEx"); if (ChangeWindowMessageFilterEx) return func(hWnd, WM_COPYDATA, MSGFLT_ALLOW, NULL); } return FALSE; }而这个函数的用法是:
hWnd = CreateWindowEx(0, CLS_NAME, "DevNotifWnd", WS_ICONIC, 0, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, NULL, GetModuleHandle(0), (void*)&guid); InitInstance(hWnd);但是没有效果。
使用
while(true){...}循环并调用适当的Win API 函数,如this answer。但是这种方式似乎不是我的问题的完美解决方案。
我的问题是:
- 谁能解释一下最好的方法是什么?如果它是 RegisterDeviceNotification 的第二个,为什么它在仅消息窗口应用程序的情况下不起作用?
- 是否存在其他方法?如果没有,我该怎么做,例如,在安装某些特定软件时通知应用程序?
感谢任何 cmets。
【问题讨论】:
-
仅消息窗口是 Win32 中的常见模式。控制台应用程序创建仅消息窗口应该没有问题,但如果您的主线程不是事件驱动的,您可能希望在不同的线程上执行此操作。
-
当你说“我用这个答案的例子尝试了最后一个”时,你的意思是你编译并运行了这个例子,没有任何改变,对吧?
-
@immibis 是的,我是这个意思。所以我应该为仅消息窗口创建新线程?
-
@heyjohnnyfunt:问题的核心是你必须重复call
GetMessageandDispatchMessage。正如 immibis 试图解释的那样,您可以从您的主线程执行此操作,或者如果更方便,可以从另一个线程执行此操作。 (我强烈建议也从同一个线程调用CreateWindowEx) -
@MSalters:但我正在努力按照你说的去做。我在您提供的 MSDN 上使用
GetMessage的示例进行了 while 循环,并且还使用了CreateWindowEx,但我在控制台中看不到任何消息。这意味着我的应用没有收到WM_DEVICECHANGE事件。我也试过在另一个线程中这样做,但结果是一样的。
标签: c++ windows winapi events usb