USBメモリーをUSBポートに挿したときや抜いたとき、DVDドライブにCD-ROMを入れたときなど、デバイスの状態が変化したときにはWM_DEVICECHANGEメッセージが届く。
残念ながらこのメッセージを通じて取得できるのは必要最低限の情報しかないため、続く処理を作るのはかなり面倒になる。しかし必要最低限の情報しかないため理解するのは楽だろう。
ここではメッセージを取得したときに得られる情報の一部をATLTRACEにて出力ウインドウに書き出している。
ATL/WTLアプリケーションウイザードでダイアログベースのプロジェクトを作成し、自動生成されたソースコードに変更を加える。
#define WINVER 0x0500■MainDlg.hを修正 includeファイルを2つ追加する。
#include "atlstr.h" #include "Dbt.h"メッセージマップにWM_DEVICECHANGE用のハンドラーを追加、CMainDlg内にメンバークラスを追加する。
BEGIN_MSG_MAP(CMainDlg) MESSAGE_HANDLER(WM_DEVICECHANGE, OnDeviceChange) (。。。省略。。。) END_MSG_MAP() // //この関数は以下のURLよりコピー&改変 //https://support.microsoft.com/kb/163503/ja // TCHAR FirstDriveFromMask(ULONG unitmask) { TCHAR i; for (i = 0; i < 26; ++i) { if (unitmask & 0x1) break; unitmask = unitmask >> 1; } return (i + _T('A')); } LRESULT OnDeviceChange(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) { bool bAddData; CAtlString strMessage; bAddData = false; switch(wParam) { case DBT_CONFIGCHANGECANCELED: strMessage = _T("DBT_CONFIGCHANGECANCELED:設定変更要求がキャンセルされました"); break; case DBT_CONFIGCHANGED: strMessage = _T("DBT_CONFIGCHANGED:設定が変更されました"); break; case DBT_CUSTOMEVENT: strMessage = _T("DBT_CUSTOMEVENT:ドライバー定義のカスタムイベントが発行されました"); bAddData = true; break; case DBT_DEVICEARRIVAL: strMessage = _T("DBT_DEVICEARRIVAL:デバイスが使用可能になりました"); bAddData = true; break; case DBT_DEVICEQUERYREMOVE: strMessage = _T("DBT_DEVICEQUERYREMOVE:デバイス停止要求が発行されました"); bAddData = true; break; case DBT_DEVICEQUERYREMOVEFAILED: strMessage = _T("DBT_DEVICEQUERYREMOVEFAILED:デバイス停止要求が失敗されました"); bAddData = true; break; case DBT_DEVICEREMOVECOMPLETE: strMessage = _T("DBT_DEVICEREMOVECOMPLETE:デバイスが停止されました"); bAddData = true; break; case DBT_DEVICEREMOVEPENDING: strMessage = _T("DBT_DEVICEREMOVEPENDING:デバイスを停止中です"); bAddData = true; break; case DBT_DEVICETYPESPECIFIC: strMessage = _T("DBT_DEVICETYPESPECIFIC:デバイスの独自イベントが発行されました"); bAddData = true; break; case DBT_DEVNODES_CHANGED: strMessage = _T("DBT_DEVNODES_CHANGED:システムのデバイス状態が変化しました"); break; case DBT_QUERYCHANGECONFIG: strMessage = _T("DBT_QUERYCHANGECONFIG:設定変更要求が発行されました"); break; case DBT_USERDEFINED: strMessage = _T("DBT_USERDEFINED"); break; default: strMessage.Format(_T("unknown(%04X)"),wParam); { _DEV_BROADCAST_USERDEFINED* pData = (_DEV_BROADCAST_USERDEFINED*)lParam; if(pData) { strMessage += _T("("); strMessage += pData->dbud_szName; strMessage += _T(")"); lParam = (LPARAM)&pData->dbud_dbh; bAddData = true; } } break; } if(bAddData) { DEV_BROADCAST_HDR* pData = (DEV_BROADCAST_HDR*)lParam; if(pData) { CAtlString strBuff; strBuff.Format(_T("(Size=%d DeviceType=%08d)"),pData->dbch_size,pData->dbch_devicetype); strMessage += strBuff; switch(pData->dbch_devicetype) { case DBT_DEVTYP_OEM: { DEV_BROADCAST_OEM* pExtend = (DEV_BROADCAST_OEM*)pData; if(pExtend) { } } break; case DBT_DEVTYP_DEVNODE: { DEV_BROADCAST_DEVNODE* pExtend = (DEV_BROADCAST_DEVNODE*)pData; if(pExtend) { } } break; case DBT_DEVTYP_VOLUME: { DEV_BROADCAST_VOLUME* pExtend = (DEV_BROADCAST_VOLUME*)pData; if(pExtend) { CAtlString strBuff; strBuff.Format(_T("「%c:」"),FirstDriveFromMask(pExtend->dbcv_unitmask)); strMessage += strBuff; } } break; case DBT_DEVTYP_PORT: { DEV_BROADCAST_PORT* pExtend = (DEV_BROADCAST_PORT*)pData; if(pExtend) { CAtlString strBuff; strBuff.Format(_T("(PORT:%s)"),pExtend->dbcp_name); strMessage += strBuff; } } break; case DBT_DEVTYP_NET: { DEV_BROADCAST_NET* pExtend = (DEV_BROADCAST_NET*)pData; if(pExtend) { } } break; case DBT_DEVTYP_DEVICEINTERFACE: { DEV_BROADCAST_DEVICEINTERFACE* pExtend = (DEV_BROADCAST_DEVICEINTERFACE*)pData; if(pExtend) { CAtlString strBuff; strBuff.Format(_T("(I/F:%s)"),pExtend->dbcc_name); strMessage += strBuff; } } break; case DBT_DEVTYP_HANDLE: { DEV_BROADCAST_HANDLE* pExtend = (DEV_BROADCAST_HANDLE*)pData; if(pExtend && pExtend->dbch_handle && pExtend->dbch_handle != INVALID_HANDLE_VALUE) { } } break; } } } ATLTRACE("%s\n",strMessage); return 0; }