Note that there are some explanatory texts on larger screens.

plurals
  1. POGetting Bluetooth incoming/outgoing serial ports in Delphi
    primarykey
    data
    text
    <p>I am looking for a way, programmatically, to first enumerate all Bluetooth serial ports a system has with friendly names and port number and then sort them by either incoming or outgoing ports. From what I have seen, Windows normally assigns the outgoing port first and the next port is usually the incoming port, but this is not always the case. Is there a way to determine from either the registry or other methods such as a Windows API call to determine which ports are incoming or outgoing, and which ones are only for Bluetooth? Under the Bluetooth Radio Properties, it shows port, direction, and name, so this data must be available somewhere (I would hope).</p> <p>My current code just grabs all active COM ports and places them in a combo box with friendly names and port numbers. Eg: Communications Port (COM1) Bluetooth Communications Port (COM9) Bluetooth Communications Port (COM10)</p> <pre><code>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 &lt;&gt; 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) &lt;&gt; '') and (pos('(COM',itsname) &gt; 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 &gt;= 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 &gt; maxwidth then maxwidth := tmpwidth + 10; // +10 for padding? end; portsCombo.Perform( CB_SETDROPPEDWIDTH, maxwidth, 0 ); end; </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload