工作中对于读卡器的操作比较多,就自己总结了一下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;
第三步,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;
第四步,在窗口加上一个自定义的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;
最后补上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;
GUID和USB_INTERFACE,USB_INSERTION,USB_REMOVAL都是自定义的常量。
最后我有个疑问,不同的设备,GUID应该是不一样的吧,为什么我公司用的读卡器的GUID,回家之后能识别我自己的通用的读卡器的拔插?希望大牛解惑,欢迎拍砖。