我想要捕获WM_DEVICECHANGE的消息。但是,有一个我无法理解的问题。我想看看何时插入usb或cd。可能我的通知过滤器是错误的。 我使用radstudio和它的c语言,也是它的命令行应用程序。我认为代码中的一切都是显而易见的。我做错了什么,我创建了只获取消息的窗口。我也不明白它是如何从WndProc发送消息的消息循环。
#pragma hdrstop
#pragma argsused
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <dbt.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
switch (uiMsg)
{
case WM_DEVICECHANGE:
{
MessageBox(0,"a","b",1);
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
BOOL bRet;
HANDLE a;
HWND lua;
HANDLE hInstance;
MSG msg;
WNDCLASSEX wndClass;
HANDLE hVolNotify;
DEV_BROADCAST_DEVICEINTERFACE dbh;
DEV_BROADCAST_VOLUME NotificationFilter;
lua = CreateWindow("lua", NULL, WS_MINIMIZE, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
wndClass.lpfnWndProc = WndProc;
ZeroMemory(&NotificationFilter, sizeof (NotificationFilter));
NotificationFilter.dbcv_size = sizeof (NotificationFilter);
NotificationFilter.dbcv_devicetype = DBT_DEVTYP_VOLUME;
a = RegisterDeviceNotification(lua,&NotificationFilter,DEVICE_NOTIFY_WINDOW_HANDLE);
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
MessageBox(0,"o","b",1);
if (bRet == -1)
{
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
答案 0 :(得分:2)
我做错了什么,我创建了仅获取消息的窗口。
您要求CreateWindow()
创建一个班级"lua"
的窗口,但在致电"lua"
之前您尚未通过RegisterClass/Ex()
注册CreateWindow()
班级,并且你没有检查CreateWindow()
是否在失败时返回NULL
窗口句柄。
我也不明白它是如何通过消息循环传递给WndProc的。
由DispatchMessage()
处理。在致电wndClass.lpfnWndProc
之前,您需要指定RegisterClass()
并将其注册到CreateWindow()
。之后,当DispatchMessage()
看到以CreateWindow()
创建的窗口为目标的消息时,它知道WndProc()
已与该窗口关联,并将直接调用它,并将消息传递给它。
请改为尝试:
#pragma hdrstop
#pragma argsused
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <dbt.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
if (uiMsg == WM_DEVICECHANGE)
{
MessageBox(NULL, TEXT("WM_DEVICECHANGE"), TEXT("WndProc"), MB_OK);
return 0;
}
return DefWindowProc(hWnd, uiMsg, wParam, lParam);
}
int _tmain(int argc, _TCHAR* argv[])
{
HINSTANCE hInstance = reinterpret_cast<HINSTANCE>(GetModuleHandle(NULL));
WNDCLASS wndClass = {0};
wndClass.lpfnWndProc = &WndProc;
wndClass.lpszClassName = TEXT("lua");
wndClass.hInstance = hInstance;
if (RegisterClass(&wndClass))
{
HWND lua = CreateWindow(wndClass.lpszClassName, NULL, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (lua != NULL)
{
DEV_BROADCAST_VOLUME NotificationFilter = {0};
NotificationFilter.dbcv_size = sizeof(NotificationFilter);
NotificationFilter.dbcv_devicetype = DBT_DEVTYP_VOLUME;
HDEVNOTIFY hVolNotify = RegisterDeviceNotification(lua, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
if (hVolNotify != NULL)
{
MSG msg;
while( GetMessage(&msg, NULL, 0, 0) > 0 )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnregisterDeviceNotification(hVolNotify);
}
DestroyWindow(lua);
}
UnregisterClass(wndClass.lpszClassName, hInstance);
}
return 0;
}
如果需要,您可以使用CreateWindowEx()
代替CreateWindow()
来创建仅限消息的窗口:
HWND lua = CreateWindowEx(0, wndClass.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, NULL);
答案 1 :(得分:0)
您需要设置dbcv_unitmask
结构的DEV_BROADCAST_VOLUME
字段,以指明您感兴趣的驱动器号。如果您想查看媒体更改,还需要设置{{1} DBTF_MEDIA
字段中的}标志。