大佬教程收集整理的这篇文章主要介绍了delphi – 如何检测新串口的添加?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
是否有事件告知何时添加或删除了一个comport?
更新1
我尝试了RRUZ的第一个建议,并把它变成了一个独立的程序.当电缆插入或拔出时,它会对WM_DEVICECHANGE作出反应,但WParam不会显示设备的到达或移除.结果是:
@H_863_8@msg = 537,wparam = 7,lparam = 0 msg = 537,lparam = 0插入USB电缆时会发送第一条消息,插入USB电缆时会发送下一条消息.
消息部分显示WM_DEVICECHANGE消息(537),但WParam为7,不是WM_DEVICECHANGE或DBT_DEVICEARRIVAl.我稍微修改了代码以便处理消息,但是当LParam为零时,这是没用的.结果与VCL和FMX相同.作为检查,请参阅下面的代码.
更新2
我现在运行WMI代码.它只在添加COM端口时触发,当一个端口被移除时没有反应.结果:
TargeTinstance.ClassGuid : {4d36e978-e325-11ce-bfc1-08002be10318} TargeTinstance.Description : Arduino Mega ADK R3 TargeTinstance.Name : Arduino Mega ADK R3 (COM4) TargeTinstance.PNPDevicEID : USB\VID_2341&PID_0044\64935343733351E0E1D1 TargeTinstance.Status : OK
这可以解释一个事实,在其他代码中,这不被视为添加COM端口?它似乎将新连接视为USB端口(实际上是什么). Arduino驱动程序将其转换为COM端口,但WMI无法识别. Windows消息传递’看到’COM端口更改但无法检测是否添加或删除了它.
无论如何:设备更改工作.我只需要枚举COM端口,看看哪个实际存在,这是我已经手动完成的.现在我可以使用WM_DEVICECHANGE自动执行此操作.我只是向CPDrv组件添加一个事件.
感谢RRUZ的代码和帮助!
unit dev_change; interface uses Winapi.Windows,Winapi.messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls; type TProc = procedure (text: String) of object; BroadcastHdr = ^DEv_broaDCAST_HDR; DEv_broaDCAST_HDR = packed record dbch_size: DWORD; dbch_deviCEType: DWORD; dbch_reserved: DWORD; end; TDevBroadcastHdr = DEv_broaDCAST_HDR; type 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; const DBT_DEVICESOMETHING = $0007; DBT_DEVICEARRIVAL = $8000; DBT_DEVICEREMOVECOMPLETE = $8004; DBT_DEVTYP_DEVICEINTERFACE = $00000005; type TDeviceNotifyProc = procedure(Sender: TObject; const deviceName: String) of Object; TDeviceNotifier = class private hRecipient: HWND; FNotificationHandle: Pointer; FDeviceArrival: TDeviceNotifyProc; FDeviceRemoval: TDeviceNotifyProc; FOnWin: TProc; procedure WndProc(var Msg: TmessagE); public constructor Create(GUID_DEVINTERFACE : TGUID); property OnDeviceArrival: TDeviceNotifyProc read FDeviceArrival write FDeviceArrival; property OnDeviceRemoval: TDeviceNotifyProc read FDeviceRemoval write FDeviceRemoval; destructor Destroy; override; property OnWin: TProc read FOnWin write FOnWin; end; TForm1 = class(TForm) Memo: TMemo; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } DeviceNotifier : TDeviceNotifier; public { Public declarations } procedure arrival(Sender: TObject; const deviceName: String); procedure report (text: String); end; var Form1: TForm1; implementation {$R *.dfm} constructor TDeviceNotifier.Create(GUID_DEVINTERFACE : TGUID); var NotificationFilter: TDevBroadcastDeviceInterface; begin inherited Create; hRecipient := AllocateHWnd(WndProc); ZeroMemory (@NotificationFilter,SizeOf(NotificationFilter)); NotificationFilter.dbcc_size := SizeOf(NotificationFilter); NotificationFilter.dbcc_deviCEType := DBT_DEVTYP_DEVICEINTERFACE; NotificationFilter.dbcc_classguid := GUID_DEVINTERFACE; //register the device class to monitor FNotificationHandle := RegisterDeviceNotification(hRecipient,@NotificationFilter,DEVICE_NOTIFY_WINDOW_HANDLE); end; procedure TDeviceNotifier.WndProc(var Msg: TmessagE); var Dbi: PDevBroadcastDeviceInterface; begin OnWin (Format ('msg = %d,wparam = %d,lparam = %d',[msg.Msg,msg.WParam,msg.LParam])); with Msg do if (Msg = WM_DEVICECHANGE) and ((WParam = DBT_DEVICEARRIVAL) or (WParam = DBT_DEVICEREMOVECOMPLETE) or (WParam = DBT_DEVICESOMETHING)) then try Dbi := PDevBroadcastDeviceInterface (LParam); @R_197_9792@bi.dbcc_deviCEType = DBT_DEVTYP_DEVICEINTERFACE then begin if WParam = DBT_DEVICEARRIVAL then begin if Assigned(FDeviceArrival) then FDeviceArrival(Self,PChar(@Dbi.dbcc_Name)); end else if WParam = DBT_DEVICEREMOVECOMPLETE then begin if Assigned(FDeviceRemoval) then FDeviceRemoval(Self,PChar(@Dbi.dbcc_Name)); end; end; except Result := DefWindowProc(hRecipient,Msg,WParam,LParam); end else Result := DefWindowProc(hRecipient,LParam); end; destructor TDeviceNotifier.Destroy; begin UnregisterDeviceNotification(FNotificationHandlE); DeallocateHWnd(hRecipient); inherited; end; procedure TForm1.arrival(Sender: TObject; const deviceName: String); begin report (deviceName); Showmessage(deviceName); end; procedure TForm1.FormCreate(Sender: TObject); const GUID_DEVINTERFACE_COMPORT : TGUID = '{86E0D1E0-8089-11D0-9CE4-08003E301F73}'; begin DeviceNotifier:=TDeviceNotifier.Create(GUID_DEVINTERFACE_COMPORT); DeviceNotifier.FDeviceArrival:=arrival; DeviceNotifier.onWin := report; end; procedure TForm1.FormDestroy(Sender: TObject); begin DeviceNotifier.Free; end; procedure TForm1.report (text: String); begin Memo.Lines.Add (text); end; end.
RegisterDeviceNotification
WinAPI函数将
DEV_BROADCAST_DEVICEINTERFACE
结构与
GUID_DEVINTERFACE_COMPORT
设备接口类一起传递.
试试这个样本.
type PDevBroadcastHdr = ^DEv_broaDCAST_HDR; DEv_broaDCAST_HDR = packed record dbch_size: DWORD; dbch_deviCEType: DWORD; dbch_reserved: DWORD; end; TDevBroadcastHdr = DEv_broaDCAST_HDR; type 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; const DBT_DEVICEARRIVAL = $8000; DBT_DEVICEREMOVECOMPLETE = $8004; DBT_DEVTYP_DEVICEINTERFACE = $00000005; type TDeviceNotifyProc = procedure(Sender: TObject; const deviceName: String) of Object; TDeviceNotifier = class private hRecipient: HWND; FNotificationHandle: Pointer; FDeviceArrival: TDeviceNotifyProc; FDeviceRemoval: TDeviceNotifyProc; procedure WndProc(var Msg: TmessagE); public constructor Create(GUID_DEVINTERFACE : TGUID); property OnDeviceArrival: TDeviceNotifyProc read FDeviceArrival write FDeviceArrival; property OnDeviceRemoval: TDeviceNotifyProc read FDeviceRemoval write FDeviceRemoval; destructor Destroy; override; end; type TForm17 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } DeviceNotifier : TDeviceNotifier; public { Public declarations } procedure arrival(Sender: TObject; const deviceName: String); end; var Form17: TForm17; implementation {$R *.dfm} constructor TDeviceNotifier.Create(GUID_DEVINTERFACE : TGUID); var NotificationFilter: TDevBroadcastDeviceInterface; begin inherited Create; hRecipient := AllocateHWnd(WndProc); ZeroMemory(@NotificationFilter,SizeOf(NotificationFilter)); NotificationFilter.dbcc_size := SizeOf(NotificationFilter); NotificationFilter.dbcc_deviCEType := DBT_DEVTYP_DEVICEINTERFACE; NotificationFilter.dbcc_classguid := GUID_DEVINTERFACE; //register the device class to monitor FNotificationHandle := RegisterDeviceNotification(hRecipient,DEVICE_NOTIFY_WINDOW_HANDLE); end; procedure TDeviceNotifier.WndProc(var Msg: TmessagE); var Dbi: PDevBroadcastDeviceInterface; begin with Msg do if (Msg = WM_DEVICECHANGE) and ((WParam = DBT_DEVICEARRIVAL) or (WParam = DBT_DEVICEREMOVECOMPLETE)) then try Dbi := PDevBroadcastDeviceInterface(LParam); @R_197_9792@bi.dbcc_deviCEType = DBT_DEVTYP_DEVICEINTERFACE then begin if WParam = DBT_DEVICEARRIVAL then begin if Assigned(FDeviceArrival) then FDeviceArrival(Self,PChar(@Dbi.dbcc_Name)); end else if WParam = DBT_DEVICEREMOVECOMPLETE then begin if Assigned(FDeviceRemoval) then FDeviceRemoval(Self,PChar(@Dbi.dbcc_Name)); end; end; except Result := DefWindowProc(hRecipient,LParam); end else Result := DefWindowProc(hRecipient,LParam); end; destructor TDeviceNotifier.Destroy; begin UnregisterDeviceNotification(FNotificationHandlE); DeallocateHWnd(hRecipient); inherited; end; procedure TForm17.arrival(Sender: TObject; const deviceName: String); begin Showmessage(deviceName); end; procedure TForm17.FormCreate(Sender: TObject); const GUID_DEVINTERFACE_COMPORT : TGUID = '{86E0D1E0-8089-11D0-9CE4-08003E301F73}'; begin DeviceNotifier:=TDeviceNotifier.Create(GUID_DEVINTERFACE_COMPORT); DeviceNotifier.FDeviceArrival:=arrival; end; procedure TForm17.FormDestroy(Sender: TObject); begin DeviceNotifier.Free; end; end.
以上是大佬教程为你收集整理的delphi – 如何检测新串口的添加?全部内容,希望文章能够帮你解决delphi – 如何检测新串口的添加?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。