1

我想捕捉 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);
    }
}

}
4

2 回答 2

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);
于 2012-12-12T21:49:58.933 回答
0

您需要设置结构的dbcv_unitmask字段DEV_BROADCAST_VOLUME以指示您感兴趣的驱动器号。如果您想查看媒体更改,您还需要在字段中设置DBTF_MEDIA标志。dbcv_flags

于 2012-12-12T19:38:19.937 回答