TechEd Yokohamaで、「C++、C++ / CLI、C# 適材適所の BOF 」があり、デバイスの検出を例に説明があり、興味深く聞かせていただきました。
デバイスの検出関連はこれまで触ったことがなかったので、URLなどをいくつかメモ。
WM_DEVICECHANGE、struct _DEV_BROADCAST_HDR などの定義
C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include\Dbt.h
C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\PocketPC2003\Include\dbt.h
C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\Smartphone2003\Include\dbt.h
WindProc にフックを掛けるだけであれば、InterOpはいらず、WinProcをオーバーライドすればよい。
// A device has been added to or removed from the system.
// Windows NT 4.0 and Windows Me/98/95: This value is not supported.
private const int DBT_DEVNODES_CHANGED = 0x0007;
// Windows NT 4.0 and Windows Me/98/95: This value is not supported.
private const int DBT_DEVNODES_CHANGED = 0x0007;
private const int WM_DEVICECHANGE = 0x0219;
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (m.Msg != WM_DEVICECHANGE)
{
base.WndProc(ref m);
return;
}
{
if (m.Msg != WM_DEVICECHANGE)
{
base.WndProc(ref m);
return;
}
switch ((int)(m.WParam))
{
….
{
….
case DBT_DEVICEARRIVAL:
MessageBox.Show("DBT_DEVICEARRIVAL");
break;
case DBT_DEVICEREMOVECOMPLETE:
MessageBox.Show("DBT_DEVICEREMOVECOMPLETE");
break;
….
MessageBox.Show("DBT_DEVICEARRIVAL");
break;
case DBT_DEVICEREMOVECOMPLETE:
MessageBox.Show("DBT_DEVICEREMOVECOMPLETE");
break;
….
case DBT_DEVNODES_CHANGED:
MessageBox.Show("DBT_DEVNODES_CHANGED");
break;
….
MessageBox.Show("DBT_DEVNODES_CHANGED");
break;
….
}
base.WndProc(ref m);
}
}
なお、USBドライブが追加された場合には、WParam が DBT_DEVNODES_CHANGED でメッセージが飛んでくる。
問題はこの後どれだけ複雑な InterOp が必要かどうかで、複雑な構造体(ネストしていると最悪)が必要な場合など、C++/CLI でのつなぎは可能性の1つとして面白そう。でも、自分の場合MFC触ったことないので別のアプローチ取るしかないですね。orz
やっとここまでたどり着いた…w
BoF でやってた一番ありがちなネタの部分(DBT_DEVICEARRIVAL/DBT_DEVICEREMOVECOMPLETE) は、DEV_BROADCAST_VOLUME 構造体しか使わないので、C#でも取り扱いは可能です。
とはいえ、こいつの肝というか、このメッセージを受け取ってるのって実際にはどれだけコンパクトに処理できるかという部分がでかいので、実際には、通知メッセージを一度ぶった切ることができないと実際の実装はかなり厳しいことになります。
WM_DEVICECHANGED そのものが、BroadCast&SendMessageという代物なので…
InterOpで書いていくとどのぐらい複雑になるのか比較してみると面白いかもしれませんね。
うんざりしそうですが・・・