我正在寻找一种方法,以编程方式首先枚举系统具有友好名称和端口号的所有蓝牙串行端口,然后通过传入或传出端口对它们进行排序。从我所看到的,Windows通常首先分配传出端口,下一个端口通常是传入端口,但情况并非总是如此。有没有办法从注册表或其他方法(如Windows API调用)确定哪些端口是传入或传出,哪些端口仅用于蓝牙?在蓝牙无线电属性下,它显示端口,方向和名称,因此这些数据必须在某处可用(我希望)。
我当前的代码只是抓取所有活动的COM端口,并将它们放在一个带有友好名称和端口号的组合框中。例如: 通讯端口(COM1) 蓝牙通信端口(COM9) 蓝牙通信端口(COM10)
procedure Form1.RefreshButtonClick(Sender: TObject);
var
strsCOMPorts : TStringList;
GotDev: LongBool;
Handle1, Devn, idx, maxwidth, tmpwidth: integer;
dinst, itsname, text: string;
PluggedIn: ulong;
DeviceInfo: SP_DEVINFO_DATA;
PnPHandle: HDEVINFO;
DeviceInstanceId : array [0..255] of char;
RequiredSize: DWORD;
qSetupDiGetDeviceRegistryPropertyA : TSetupDiGetDeviceRegistryPropertyA;
qSetupDiGetClassDevsA : tSetupDiGetClassDevsA;
qSetupDiEnumDeviceInfo : tSetupDiEnumDeviceInfo;
qSetupDiGetDeviceInstanceIdA : tSetupDiGetDeviceInstanceIdA;
qSetupDiDestroyDeviceInfoList : tSetupDiDestroyDeviceInfoList;
function get_driver_property(RegProperty:Cardinal):string;
var lval : string[255];
RequiredSize : DWORD;
PropertyRegDataType: DWord;
DeviceInfo1: SP_DEVINFO_DATA;
begin
DeviceInfo1:=DeviceInfo;
RegProperty:=RegProperty;
lval:=' ';
SetLength(lval,255);
RequiredSize:=255;
PluggedIn:=PluggedIn or ord(qSetupDiGetDeviceRegistryPropertya(PnPHandle,DeviceInfo1,
RegProperty,
PropertyRegDataType,
@lval[1],RequiredSize,RequiredSize));
SetLength(lval,RequiredSize-1);
if RequiredSize=255 then
lval:=' ';
result:=lval;
end;
begin
Handle1 := LoadLibrary('SetupAPI.dll');
if Handle1 <> 0 then
begin
qSetupDiGetClassDevsA := GetProcAddress(Handle1, 'SetupDiGetClassDevsA');
qSetupDiEnumDeviceInfo := GetProcAddress(Handle1, 'SetupDiEnumDeviceInfo');
qSetupDiGetDeviceInstanceIdA := GetProcAddress(Handle1, 'SetupDiGetDeviceInstanceIdA');
qSetupDiDestroyDeviceInfoList := GetProcAddress(Handle1, 'SetupDiDestroyDeviceInfoList');
qSetupDiGetDeviceRegistryPropertyA := GetProcAddress(Handle1,'SetupDiGetDeviceRegistryPropertyA');
end;
text := portsCombo.Text;
strsCOMPorts := TStringList.Create;
PnPHandle := qSetupDiGetClassDevsa(0, NIL, 0,DIGCF_ALLCLASSES or DIGCF_PRESENT);
Devn := 0;
repeat
DeviceInfo.cbSize:=sizeof(DeviceInfo);
GotDev:=qSetupDiEnumDeviceInfo(PnPHandle,Devn,DeviceInfo);
PluggedIn:=0;
if GotDev then
begin
qSetupDiGetDeviceInstanceIdA(PnPHandle,@DeviceInfo,@DeviceInstanceId,255,@RequiredSize);
dinst:=strpas(@DeviceInstanceId);
itsname:=get_driver_property(SPDRP_FriendlyName);
if itsname=' ' then
itsname:=get_driver_property(SPDRP_DEVICEDESC);
if (TRIM(itsname) <> '') and (pos('(COM',itsname) > 0) then
strsCOMPorts.Add(itsname);
Inc(Devn);
end;
until not GotDev;
qSetupDiDestroyDeviceInfoList(PnPHandle);
FreeLibrary(Handle1);
portsCombo.Items.Assign(strsCOMPorts);
strsCOMPorts.Free;
idx := portsCombo.Items.IndexOf(text);
if idx >= 0 then
portsCombo.ItemIndex := idx
else
portsCombo.ItemIndex := 0;
maxwidth := portsCombo.Width;
for idx := 0 to portsCombo.Items.Count - 1 do
begin
tmpwidth := portsCombo.Canvas.TextWidth(portsCombo.Items[idx]);
if tmpwidth > maxwidth then
maxwidth := tmpwidth + 10; // +10 for padding?
end;
portsCombo.Perform( CB_SETDROPPEDWIDTH, maxwidth, 0 );
end;