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よりコピー&改変
//http://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;
}
