delphi中检测usb拔插状态

工作中对于读卡器的操作比较多,就自己总结了一下usb拔插的检测。

首先,让自己的自定义类能接收windows消息,FHandle := AllocateHWnd(WinMethod);这个貌似有点像.net中的委托,把函数当做参数,添加自定义函数WinMethod.

第二步,注册自己的usb设备。

 1 procedure TUsbTest.RegisterUsbHandler;
 2 var rDbi : DEV_BROADCAST_DEVICEINTERFACE;
 3     iSize : integer;
 4 begin
 5   iSize := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
 6   ZeroMemory(@rDbi,iSize);
 7   rDbi.dbcc_size := iSize;
 8   rDbi.dbcc_devicetype := USB_INTERFACE;
 9   rDbi.dbcc_classguid  := GUID_DEVINTF_USB_DEVICE;
10   RegisterDeviceNotification(FHandle,@rDbi,DEVICE_NOTIFY_WINDOW_HANDLE);
11 end;
View Code

第三步,WinMethod方法的实现。

 1 procedure TUsbTest.WinMethod(var Message: TMessage);
 2 var
 3   SendData:TCopyDataStruct;
 4 begin
 5   //检查usb状态
 6   if message.Msg = WM_DEVICECHANGE then
 7   begin
 8     //移入
 9     if message.WParam = USB_INSERTION then
10     begin
11       fillchar(SendData,sizeof(SendData),0);
12       SendData.dwData :=USB_INSERTION;
13       //这里的SendData不是必须的,最后一个参数直接写0也可以,这个相当于是一个扩展的参数
14       SendMessage(FHandle,WM_COPYDATA,USB_INSERTION,LParam(@SendData));
15     end;
16     //移出
17     if message.WParam = USB_REMOVAL then
18     begin
19       fillchar(SendData,sizeof(SendData),0);
20       SendData.dwData :=USB_REMOVAL;
21       SendMessage(FHandle,WM_COPYDATA,USB_REMOVAL,LParam(@SendData));
22     end;
23   end
24   else
25     Message.Result := DefWindowProc(FHandle,Message.Msg,
26       Message.wParam,Message.lParam);
27 end;
View Code

第四步,在窗口加上一个自定义的windows消息接收函数,窗口初始化的时候把handle传给TusbTest类。

FUsbTest := TUsbTest.Create(self);
FUsbTest.FHandle := Handle;

1 procedure TFrm_Main.Recv_WMCopyData(var Msg: TWMCopyData);
2 begin
3   if Msg.From = USB_INSERTION then
4     SBar1.Panels[0].Text := 'usb设备接入....';
5   if Msg.From = USB_REMOVAL then
6     SBar1.Panels[0].Text := 'usb设备移出....';
7 end;
View Code

最后补上DEV_BROADCAST_DEVICEINTERFACE这个结构的定义。

 1 type
 2   // Win API Definitions
 3   PDevBroadcastDeviceInterface  = ^DEV_BROADCAST_DEVICEINTERFACE;
 4   DEV_BROADCAST_DEVICEINTERFACE = record
 5     dbcc_size : DWORD;
 6     dbcc_devicetype : DWORD;
 7     dbcc_reserved : DWORD;
 8     dbcc_classguid : TGUID;
 9     dbcc_name : char;
10   end;
View Code

GUID和USB_INTERFACE,USB_INSERTION,USB_REMOVAL都是自定义的常量。

最后我有个疑问,不同的设备,GUID应该是不一样的吧,为什么我公司用的读卡器的GUID,回家之后能识别我自己的通用的读卡器的拔插?希望大牛解惑,欢迎拍砖。

原文地址:https://www.cnblogs.com/jinshizuofei/p/3271812.html