在Delphi中获取蓝牙输入/输出串行端口

在Delphi中获取蓝牙输入/输出串行端口,delphi,bluetooth,serial-port,delphi-2007,Delphi,Bluetooth,Serial Port,Delphi 2007,我正在寻找一种方法,以编程方式,首先枚举系统具有友好名称和端口号的所有蓝牙串行端口,然后按传入或传出端口对它们进行排序。据我所见,Windows通常首先分配传出端口,下一个端口通常是传入端口,但情况并非总是如此。是否有办法从注册表或其他方法(如Windows API调用)确定哪些端口是传入的或传出的,哪些端口仅用于蓝牙?在Bluetooth Radio属性下,它显示端口、方向和名称,因此这些数据必须在某个地方可用(我希望如此) 我当前的代码只是获取所有活动的COM端口,并将它们放在一个带有友好名

我正在寻找一种方法,以编程方式,首先枚举系统具有友好名称和端口号的所有蓝牙串行端口,然后按传入或传出端口对它们进行排序。据我所见,Windows通常首先分配传出端口,下一个端口通常是传入端口,但情况并非总是如此。是否有办法从注册表或其他方法(如Windows API调用)确定哪些端口是传入的或传出的,哪些端口仅用于蓝牙?在Bluetooth Radio属性下,它显示端口、方向和名称,因此这些数据必须在某个地方可用(我希望如此)

我当前的代码只是获取所有活动的COM端口,并将它们放在一个带有友好名称和端口号的组合框中。如: 通信端口(COM1) 蓝牙通信端口(COM9) 蓝牙通信端口(COM10)

procedure Form1.刷新按钮点击(发送方:TObject);
变量
strsCOMPorts:TStringList;
戈德夫:朗布尔;
Handle1,Devn,idx,maxwidth,tmpwidth:整数;
dinst,其名称,text:string;
PluggedIn:ulong;
DeviceInfo:SP_DeviceInfo_数据;
PnPHandle:HDEVINFO;
DeviceInstanceId:字符的数组[0..255];
所需尺寸:DWORD;
QSetupDiggetDeviceRegistrypropertya:tSetupDiggetDeviceRegistrypertya;
qSetupDiGetClassDevsA:tSetupDiGetClassDevsA;
qSetupDiEnumDeviceInfo:tSetupDiEnumDeviceInfo;
qSetupDiGetDeviceInstanceIdA:tSetupDiGetDeviceInstanceIdA;
QSetupDiDestroyDeviceInfo列表:TsetupDiDestroyDeviceInfo列表;
函数get\u driver\u property(RegProperty:Cardinal):字符串;
变量lval:string[255];
所需尺寸:DWORD;
PropertyRegDataType:DWord;
DeviceInfo 1:SP_DeviceInfo_数据;
开始
DeviceInfo 1:=DeviceInfo;
RegProperty:=RegProperty;
lval:='';
设定长度(lval,255);
所需大小:=255;
PluggedIn:=PluggedIn或ord(qSetupDiGetDeviceRegistryPropertya(PnPHandle,DeviceInfo 1,
RegProperty,
PropertyRegDataType,
@lval[1],RequiredSize,RequiredSize));
设置长度(lval,所需尺寸-1);
如果所需大小=255,则
lval:='';
结果:=lval;
结束;
开始
Handle1:=LoadLibrary('SetupAPI.dll');
如果handle10那么
开始
qSetupDiGetClassDevsA:=GetProcAddress(Handle1,'SetupDiGetClassDevsA');
qSetupDiEnumDeviceInfo:=GetProcAddress(Handle1,'SetupDiEnumDeviceInfo');
qSetupDiGetDeviceInstanceIdA:=GetProcAddress(Handle1,'SetupDiGetDeviceInstanceIdA');
qsetupdidestroydeviceinfo:=GetProcAddress(Handle1,'setupdidestroydeviceinfo');
qSetupDiGetDeviceRegistryPropertyA:=GetProcAddress(Handle1,'SetupDigetDeviceRegistrypertya');
结束;
text:=portsCombo.text;
strsCOMPorts:=TStringList.Create;
PnPHandle:=qSetupDiGetClassDevsa(0,NIL,0,DIGCF_所有类或DIGCF_存在);
Devn:=0;
重复
DeviceInfo.cbSize:=sizeof(DeviceInfo);
GotDev:=qSetupDiEnumDeviceInfo(PnPHandle、Devn、DeviceInfo);
PluggedIn:=0;
如果有,那么
开始
qSetupDiGetDeviceInstanceIdA(PnPHandle,@DeviceInfo,@DeviceInstanceId,255,@RequiredSize);
dinst:=strpas(@DeviceInstanceId);
itsname:=获取驱动程序属性(SPDRP\U FriendlyName);
如果它的名称为“”,则
itsname:=获取驱动程序属性(SPDRP\U DEVICEDESC);
如果(TRIM(itsname)')和(pos('(COM',itsname)>0),则
strsCOMPorts.Add(其名称);
公司(德国);
结束;
直到没有GotDev;
QSetupDiDestroyDeviceInfo列表(PnPHandle);
免费图书馆(Handle1);
portsCombo.Items.Assign(strsCOMPorts);
strsCOMPorts.Free;
idx:=portsCombo.Items.IndexOf(文本);
如果idx>=0,则
portsCombo.ItemIndex:=idx
其他的
portsCombo.ItemIndex:=0;
maxwidth:=portsCombo.Width;
对于idx:=0到portsCombo.Items.Count-1 do
开始
tmpwidth:=portsCombo.Canvas.TextWidth(portsCombo.Items[idx]);
如果tmpwidth>maxwidth,则
maxwidth:=tmpwidth+10;//+10用于填充?
结束;
portsCombo.Perform(CB_SETDROPPEDWIDTH,maxwidth,0);
结束;

以下是您的答案:@PsyChip,我不认为这正是我想要的。我看不到一种方法来确定端口是传入的还是传出的,或者它是否确实是Bluetooth(除非我要求“Bluetooth”在友好名称中有效,我不认为总是这样).除非我错过了?绝地API翻译有一个JwaBlueToothAPI.pas`单元,可以让你列举蓝牙设备并获取信息。@KenWhite我已经有一段时间没有参与这个项目了,但是如果你能举一个例子,用JwaBlueToothAPI在答案中获取信息,我会接受它。@Evan:我没有一个例子不幸的是,没有一款设备可以使用蓝牙和Windows,我无法开发。该单元中的注释描述了所涉及的结构,MSDN描述了以及如何使用它。
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;