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

时间:2013-12-16 17:52:13

标签: delphi bluetooth serial-port delphi-2007

我正在寻找一种方法,以编程方式首先枚举系统具有友好名称和端口号的所有蓝牙串行端口,然后通过传入或传出端口对它们进行排序。从我所看到的,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;

0 个答案:

没有答案