1

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

}
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 に答える