c - RegisterDeviceNotification 获取 WM_DEVICECHANGE

标签 c winapi

我想捕获 WM_DEVICECHANGE 的消息。但是,有一个我无法理解的问题。我想看看 usb 或 cd 何时插入。也许我的通知过滤器是错误的。 我正在使用 radstudio 和它的 c 语言,还有它的命令行应用程序。我认为代码中的一切都很明显。我做错了什么,我创建了仅用于获取消息的窗口。而且我不明白它是如何将消息从消息循环。

#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);
    }
}

}

最佳答案

What am i doing wrong,i created window for only getting messages.

您要求 CreateWindow() 创建类 "lua" 的窗口,但您实际上还没有注册 "lua" 类在调用 CreateWindow() 之前通过 RegisterClass/Ex(),并且您没有检查 CreateWindow() 是否返回 NULL 失败时的窗口句柄。

Also i did not understand how it message going to WndProc from message loop.

这是由 DispatchMessage() 处理的。在调用 CreateWindow() 之前,您需要分配 wndClass.lpfnWndProc 并使用 RegisterClass() 注册它。之后,当 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);

关于c - RegisterDeviceNotification 获取 WM_DEVICECHANGE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13843758/

相关文章:

c++ - 在 C++ 中获取窗口标题

c++ - 在 C++ Windows API 中最小化的应用程序事件

c++ - 如何将状态栏放置在OPENGL之上?

c - 在哪里可以找到 Apache 用于处理 .htaccess 的源代码?

c - sscanf 函数更改另一个字符串的内容

c - <dos.h> 头文件在代码块中工作吗?

c - 尽管进行了更改,为什么 Makefile 认为它是最新的?

c - Unix 可执行文件在通过套接字传输时更改为文档

c++ - MessageBox() 在触摸屏上的 WM_ACTIVATEAPP 中没有响应

c++ - ActiveX 控件的全屏模式