這裡是使用WndProc()來監聽Windows的訊息,
WM_DEVICECHANGE是 Windows 系統發送給應用程序的消息,用於通知設備的插入、移除或狀態改變。
例如,當你插入或拔出 USB 設備時,系統會發送這條消息。
WM_DEVICECHANGE訊息
- wParam:表示设备事件的类型(例如插入、移除等)。
- lParam:指向一個結構體,包含事件的詳細信息(比如設備類型、設備路徑等)。
常數名稱 | 數值(十六進位) | 說明 |
---|---|---|
DBT_DEVICEARRIVAL | 0x8000 | 裝置已插入(例如:USB 插入) |
DBT_DEVICEREMOVECOMPLETE | 0x8004 | 裝置已被移除 |
DBT_DEVNODES_CHANGED | 0x0007 | 裝置樹發生變更(新增或移除裝置) |
DBT_DEVICEQUERYREMOVE | 0x8001 | 請求移除裝置(應用程式可拒絕) |
DBT_DEVICEQUERYREMOVEFAILED | 0x8002 | 裝置移除請求失敗(使用者或應用程式拒絕) |
DBT_DEVICETYPEDATA | 0x8005 | 特定裝置類型的事件(例如媒體更換) |
lParam 常用結構:DEV_BROADCAST_DEVICEINTERFACE
當 wParam 是 DBT_DEVICEARRIVAL 或 DBT_DEVICEREMOVECOMPLETE 時,
lParam 會指向一個 DEV_BROADCAST_HDR 結構,包含裝置類型與裝置名稱(裝置路徑 GUID)。
public struct DEV_BROADCAST_HDR { public int dbch_size; // 結構大小(含裝置名稱等) public int dbch_devicetype; // 裝置類型(如 DBT_DEVTYP_DEVICEINTERFACE) public int dbch_reserved; // 保留,通常為 0 }
dbch_devicetype
常數名稱 | 數值(十六進位) | 說明 |
---|---|---|
DBT_DEVTYP_OEM | 0x00000000 | OEM 裝置類型(較少使用) |
DBT_DEVTYP_DEVNODE | 0x00000001 | 設備節點(不含裝置名稱) |
DBT_DEVTYP_VOLUME | 0x00000002 | 卷(Volume)裝置,像是硬碟或 USB 隨身碟的邏輯磁碟區 |
DBT_DEVTYP_PORT | 0x00000003 | 埠(如 COM 或 LPT) |
DBT_DEVTYP_NET | 0x00000004 | 網路資源 |
DBT_DEVTYP_DEVICEINTERFACE | 0x00000005 | 裝置介面(例如 USB 裝置) |
DBT_DEVTYP_HANDLE | 0x00000006 | 特定裝置的 Handle(需配合 API 使用) |
DEV_BROADCAST_HDR hdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HDR)); switch (hdr.dbch_devicetype) { case DBT_DEVTYP_DEVICEINTERFACE: // USB、藍芽等裝置 break; case DBT_DEVTYP_VOLUME: // 磁碟區插入或移除(例如 U 盤) break; case DBT_DEVTYP_PORT: // 串列埠變化(例如 COM3) break; default: // 其他裝置 break; }
範例一
private const int WM_DEVICECHANGE = 0x0219; // 裝置插入/移除 private const int DBT_DEVICEARRIVAL = 0x8000; // 裝置插入 private const int DBT_DEVICEREMOVECOMPLETE = 0x8004; // 裝置拔除 protected override void WndProc(ref Message m) { if (m.Msg == WM_DEVICECHANGE) { int eventType = m.WParam.ToInt32(); if (eventType == DBT_DEVICEARRIVAL) { //Console.WriteLine("裝置插入!"); Debug.WriteLine("裝置插入!"); } else if (eventType == DBT_DEVICEREMOVECOMPLETE) { //Console.WriteLine("裝置拔除!"); Debug.WriteLine("裝置拔除!"); } } base.WndProc(ref m); }
範例二
private const int WM_DEVICECHANGE = 0x0219; // 裝置插入/移除 private const int DBT_DEVICEARRIVAL = 0x8000; // 裝置插入 private const int DBT_DEVICEREMOVECOMPLETE = 0x8004; // 裝置拔除 private const int DBT_DEVTYP_DEVICEINTERFACE = 0x00000005; private const int DBT_DEVTYP_VOLUME = 0x00000002; private const int DBT_DEVTYP_PORT = 0x00000003; public struct DEV_BROADCAST_HDR { public int dbch_size; // 結構大小(含裝置名稱等) public int dbch_devicetype; // 裝置類型(如 DBT_DEVTYP_DEVICEINTERFACE) public int dbch_reserved; // 保留,通常為 0 } protected override void WndProc(ref Message m) { if (m.Msg == WM_DEVICECHANGE) { int eventType = m.WParam.ToInt32(); if (eventType == DBT_DEVICEARRIVAL) { //Console.WriteLine("裝置插入!"); Debug.WriteLine("裝置插入!"); DEV_BROADCAST_HDR hdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HDR)); switch (hdr.dbch_devicetype) { case DBT_DEVTYP_DEVICEINTERFACE: // USB、藍芽等裝置 Debug.WriteLine("USB、藍芽等裝置"); break; case DBT_DEVTYP_VOLUME: // 磁碟區插入或移除(例如 U 盤) Debug.WriteLine("U 盤!"); break; case DBT_DEVTYP_PORT: // 串列埠變化(例如 COM3) Debug.WriteLine("串列埠變化"); break; default: // 其他裝置 Debug.WriteLine("其他裝置"); break; } } else if (eventType == DBT_DEVICEREMOVECOMPLETE) { //Console.WriteLine("裝置拔除!"); Debug.WriteLine("裝置拔除!"); } } base.WndProc(ref m); }
留言
張貼留言