129 lines
3.8 KiB
ObjectPascal
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.
|