unit dev.usb.notifier; interface uses Windows, Messages, Classes; type TUsbNotifyProc = procedure(Sender: TObject; const DeviceName: String) of object; TUsbNotifier = class private fWindowHandle : HWND; fNotificationHandle : Pointer; fOnUsbArrival : TUsbNotifyProc; fOnUsbRemoval : TUsbNotifyProc; private procedure WndProc(var Msg: TMessage); public constructor Create; destructor Destroy; override; public property OnUsbArrival: TUsbNotifyProc read fOnUsbArrival write fOnUsbArrival; property OnUsbRemoval: TUsbNotifyProc read fOnUsbRemoval write fOnUsbRemoval; end; implementation const GUID_DEVINTERFACE_USB_DEVICE: TGUID = '{A5DCBF10-6530-11D2-901F-00C04FB951ED}'; DBT_DEVICEARRIVAL = $8000; DBT_DEVICEREMOVECOMPLETE = $8004; DBT_DEVTYP_DEVICEINTERFACE = $00000005; type PDevBroadcastHdr = ^DEV_BROADCAST_HDR; DEV_BROADCAST_HDR = packed record dbch_size : DWORD; dbch_devicetype: DWORD; dbch_reserved : DWORD; end; TDevBroadcastHdr = DEV_BROADCAST_HDR; PDevBroadcastDeviceInterface = ^DEV_BROADCAST_DEVICEINTERFACE; DEV_BROADCAST_DEVICEINTERFACE = record dbcc_size : DWORD; dbcc_devicetype: DWORD; dbcc_reserved : DWORD; dbcc_classguid : TGUID; dbcc_name : Char; end; TDevBroadcastDeviceInterface = DEV_BROADCAST_DEVICEINTERFACE; { TUsbNotifier } // ================================================================================================ // constructor // ================================================================================================ constructor TUsbNotifier.Create; var size: cardinal; dbi : TDevBroadcastDeviceInterface; begin inherited; FWindowHandle := AllocateHWnd( WndProc); Size := SizeOf(dbi); ZeroMemory(@dbi, Size); dbi.dbcc_size := Size; dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE; dbi.dbcc_classguid := GUID_DEVINTERFACE_USB_DEVICE; FNotificationHandle := RegisterDeviceNotification( FWindowHandle, @dbi, DEVICE_NOTIFY_WINDOW_HANDLE); end; // ================================================================================================ // destructor // ================================================================================================ destructor TUsbNotifier.Destroy; begin UnregisterDeviceNotification(FNotificationHandle); DeallocateHWnd(FWindowHandle); inherited; end; // ================================================================================================ // window proc // ================================================================================================ procedure TUsbNotifier.WndProc(var Msg: TMessage); var Dbi: PDevBroadcastDeviceInterface; begin with Msg do if Msg = WM_DEVICECHANGE then if (WParam = DBT_DEVICEARRIVAL) or (WParam = DBT_DEVICEREMOVECOMPLETE) then try Dbi := PDevBroadcastDeviceInterface(LParam); if Dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE then if WParam = DBT_DEVICEARRIVAL then begin if Assigned(FOnUsbArrival) then FOnUsbArrival(Self, PChar(@Dbi.dbcc_name)); end else begin if Assigned(FOnUsbRemoval) then FOnUsbRemoval(Self, PChar(@Dbi.dbcc_name)); end except Result := DefWindowProc(FWindowHandle, Msg, WParam, LParam); end else Result := DefWindowProc(FWindowHandle, Msg, WParam, LParam); end; end.