WM_DEVICECHANGE消息 查閱MSDN得知: The framework calls this member function to notify an application or device driver of a change to the hardware configurati
-
WM_DEVICECHANGE消息
查閱MSDN得知:
The framework calls this member function to notify an application or device driver of a change to the hardware configuration of a device or the computer.
即:框架調用這個函數來通知應用程式或者設備驅動程式設備硬體配置或者電腦的配置被改變了。
所以,檢測U盤的插入和拔出也就相當於偵測處理WM_DEVICECHANGE消息。
-
獲取WM_DEVICECHANGE消息的方法
WM_DEVICECHANGE的使用方式有兩種,一種是通過WindowProc()的方式,另一種是通過OnDeviceChange()消息響應函數的方式,底下就先介紹第一種方式,再介紹第二種。
-
通過WindowProc()的方式檢測U盤
這裡通過一個簡單的Demo來說明
程式界面如下:
需要包含的頭文件:
#include <dbt.h>
#include <winioctl.h>
重寫WindowProc()函數實現U盤檢測,代碼如下:
1 char FirstDriveFromMask(ULONG unitmask) //獲取盤符 2 { 3 char i; 4 for (i = 0; i < 26; ++i) 5 { 6 if (unitmask & 0x1) 7 break; 8 unitmask = unitmask >> 1; 9 } 10 return (i + 'A'); 11 } 12 13 14 LRESULT CUpanDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 15 { 16 CString detectMsg; 17 18 switch (message) 19 { 20 //WM_DEVICECHANGE,系統硬體改變發出的系統消息 21 case WM_DEVICECHANGE: 22 { 23 PDEV_BROADCAST_HDR lpdb=(PDEV_BROADCAST_HDR)lParam; 24 switch(wParam) 25 { 26 case WM_DEVICECHANGE: 27 break; 28 case DBT_DEVICEARRIVAL://設備檢測結束,並且可以使用 29 { 30 if(lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME)//邏輯捲 31 { 32 PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb; 33 switch(lpdbv->dbcv_flags) 34 { 35 case 0: //U盤 36 { 37 CString decDriver; 38 decDriver = FirstDriveFromMask(lpdbv ->dbcv_unitmask); 39 detectMsg.Format(_T("檢測到U盤:[%s]插入!"), decDriver.GetBuffer(0)); 40 m_editControl.SetWindowText(detectMsg); 41 } 42 break; 43 case DBTF_MEDIA: //光碟 44 break; 45 } 46 } 47 } 48 break; 49 case DBT_DEVICEREMOVECOMPLETE://設備卸載或者拔出 50 { 51 if(lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME)//邏輯捲 52 { 53 PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb; 54 switch(lpdbv->dbcv_flags) 55 { 56 case 0: //U盤 57 { 58 CString decDriver; 59 decDriver = FirstDriveFromMask(lpdbv ->dbcv_unitmask); 60 detectMsg.Format(_T("檢測到U盤:[%s]拔出!"), decDriver.GetBuffer(0)); 61 m_editControl.SetWindowText(detectMsg); 62 } 63 break; 64 case DBTF_MEDIA: //光碟 65 66 break; 67 } 68 } 69 } 70 break; 71 } 72 } 73 break; 74 } 75 76 return CDialog::WindowProc(message, wParam, lParam); 77 }View Code
程式運行結果如下:
插入U盤時:
拔出U盤時:
2. 通過OnDeviceChange()的方式檢測U盤
首先在頭文件聲明一個消息函數:
afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData);
消息映射:
BEGIN_MESSAGE_MAP(OGrgFrmRepair, CDialog)
ON_WM_DEVICECHANGE()
END_MESSAGE_MAP()
實現:
1 char FirstDriveFromMask(ULONG unitmask) //獲取盤符 2 { 3 char i; 4 for (i = 0; i < 26; ++i) 5 { 6 if (unitmask & 0x1) 7 break; 8 unitmask = unitmask >> 1; 9 } 10 return (i + 'A'); 11 } 12 13 14 BOOL CUpanDlg::OnDeviceChange(UINT nEventType, DWORD dwData) 15 { 16 CString detectMsg; 17 PDEV_BROADCAST_HDR lpdb=(PDEV_BROADCAST_HDR)dwData; 18 19 switch (nEventType) 20 { 21 case DBT_DEVICEREMOVECOMPLETE: 22 { 23 if(lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME)//邏輯捲 24 { 25 PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb; 26 switch(lpdbv->dbcv_flags) 27 { 28 case 0: //U盤 29 { 30 CString decDriver; 31 decDriver = FirstDriveFromMask(lpdbv ->dbcv_unitmask); 32 detectMsg.Format(_T("檢測到U盤:[%s]拔出!"), decDriver.GetBuffer(0)); 33 m_editControl.SetWindowText(detectMsg); 34 } 35 break; 36 case DBTF_MEDIA: //光碟 37 38 break; 39 } 40 } 41 } 42 break; 43 case DBT_DEVICEARRIVAL: 44 { 45 if(lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME)//邏輯捲 46 { 47 PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb; 48 switch(lpdbv->dbcv_flags) 49 { 50 case 0: //U盤 51 { 52 CString decDriver; 53 decDriver = FirstDriveFromMask(lpdbv ->dbcv_unitmask); 54 detectMsg.Format(_T("檢測到U盤:[%s]插入!"), decDriver.GetBuffer(0)); 55 m_editControl.SetWindowText(detectMsg); 56 } 57 break; 58 case DBTF_MEDIA: //光碟 59 break; 60 } 61 } 62 } 63 break; 64 } 65 66 return TRUE; 67 68 }View Code