Files
bds.mr.devmgr/src.devmgr/dev/usb/dev.usb.notifier.pas
T
2026-01-03 18:53:14 +01:00

129 lines
3.8 KiB
ObjectPascal

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.