2012-12-12 20 views
0

我想趕上WM_DEVICECHANGE.But的消息,但有一個問題,我不明白。我想看看什麼時候插入USB或CD。也許我的通知過濾器是錯誤的。 我使用radstudio和它的c語言,也是它的命令行應用程序。我認爲在代碼中一切都很明顯。我做錯了什麼,我創建了只獲取消息的窗口。我也不明白它是如何傳遞給WndProc來自消息循環。RegisterDeviceNotification獲取WM_DEVICECHANGE

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

} 

回答

2

我做錯了什麼,我創建了只獲取消息的窗口。

你問CreateWindow()創建"lua"類的一個窗口,但你有沒有實際註冊通過RegisterClass/Ex()"lua"類調​​用CreateWindow()面前,你不檢查,以查看是否CreateWindow()失敗時返回NULL窗口句柄。

另外我不明白它是如何從消息循環WndProc消息。

這是由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); 
+0

謝謝它解決了我的問題你幫了我不少。我的信息很多,誤解很多。如果我沒有問,我自己解決需要很長時間。所以你很棒。 –

+0

我修正了一個編譯錯誤,但是你的代碼不起作用:'RegisterListerError'在'RegisterDeviceNotification'(hVolNotify爲NULL)之後返回1066 – chacham15

+0

修改結構爲'DEV_BROADCAST_DEVICEINTERFACE'後,它修復了這個問題,但是創建了一個只有消息的窗口如您指定的那樣)阻止郵件由於某種原因被傳送。 – chacham15

0

您需要設置DEV_BROADCAST_VOLUME結構的dbcv_unitmask領域,這是您哪個驅動器字母興趣。如果你想看看你還需要設置DBTF_MEDIA國旗在dbcv_flags現場媒體的變化。