How to use devicepicker for Bluetooth in VB?

André Dussault 20 Reputation points
2023-08-26T01:43:40.9+00:00

Would like to use the DevicePicker class in Visual Basic to find the characteristics of the available Bluetooth interfaces.

Are there clear examples of its usage?

Developer technologies Universal Windows Platform (UWP)
Developer technologies VB
{count} votes

Accepted answer
  1. Castorix31 90,681 Reputation points
    2023-09-02T20:11:26.99+00:00

    This test with BluetoothSelectDevices works on my OS (Windows 10 22H2), except for the Callback (not really needed...) :

    Dim bsdp As BLUETOOTH_SELECT_DEVICE_PARAMS = New BLUETOOTH_SELECT_DEVICE_PARAMS()
    bsdp.dwSize = Marshal.SizeOf(GetType(BLUETOOTH_SELECT_DEVICE_PARAMS))
    bsdp.hwndParent = Me.Handle
    'bsdp.pszInfo = "Information"
    bsdp.fShowAuthenticated = True
    bsdp.fShowUnknown = True
    bsdp.fShowRemembered = True
    'bsdp.fAddNewDeviceWizard = True
    DeviceCallbackProc = New PfnDeviceCallback(AddressOf DeviceCallback)
    bsdp.pfnDeviceCallback = DeviceCallbackProc
    Dim bRet = BluetoothSelectDevices(bsdp)
    If (bRet) Then
        ' Assuming 1 device is returned
        Dim pDevices As New BLUETOOTH_DEVICE_INFO()
        pDevices = CType(Marshal.PtrToStructure(bsdp.pDevices, pDevices.GetType()), BLUETOOTH_DEVICE_INFO)
    
        ' sAddress = "8C:D1:7B:BC:30:30"
        Dim sAddress = String.Join(":", BitConverter.GetBytes(pDevices.Address).Take(6).Reverse().[Select](Function(b) b.ToString("X2")))
        Dim sName = pDevices.szName
    
        ' ex : COD_MAJOR_PHONE and COD_PHONE_MINOR_SMART : see bthdef.h for all codes
        Dim nCODMajor = GET_COD_MAJOR(pDevices.ulClassofDevice)
        Dim nCODMinor = GET_COD_MINOR(pDevices.ulClassofDevice)
    
        BluetoothSelectDevicesFree(bsdp)
    End If
    

    With Declarations :

       <DllImport("Bthprops.cpl", SetLastError:=True, CharSet:=CharSet.Unicode)>
       Public Shared Function BluetoothSelectDevices(ByRef pbtsdp As BLUETOOTH_SELECT_DEVICE_PARAMS) As Boolean
       End Function
    
       <DllImport("Bthprops.cpl", SetLastError:=True, CharSet:=CharSet.Unicode)>
       Public Shared Function BluetoothSelectDevicesFree(ByRef pbtsdp As BLUETOOTH_SELECT_DEVICE_PARAMS) As Boolean
       End Function
    
       Public Delegate Function PfnDeviceCallback(pvParam As IntPtr, ByRef pDevice As BLUETOOTH_DEVICE_INFO) As Boolean
    
    
       <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
       Public Structure BLUETOOTH_SELECT_DEVICE_PARAMS
           Public dwSize As Integer
           Public cNumOfClasses As Integer
           Public prgClassOfDevices As IntPtr
           Public pszInfo As String
           Public hwndParent As IntPtr
           Public fForceAuthentication As Boolean
           Public fShowAuthenticated As Boolean
           Public fShowRemembered As Boolean
           Public fShowUnknown As Boolean
           Public fAddNewDeviceWizard As Boolean
           Public fSkipServicesPage As Boolean
           Public pfnDeviceCallback As PfnDeviceCallback 'PFN_DEVICE_CALLBACK
           Public pvParam As IntPtr
           Public cNumDevices As Integer
           Public pDevices As IntPtr
    
           Public ReadOnly Property Devices As BLUETOOTH_DEVICE_INFO()
               Get
                   If cNumDevices > 0 Then
                       Dim devs = New BLUETOOTH_DEVICE_INFO(cNumDevices - 1) {}
    
                       For idevice = 0 To cNumDevices - 1
                           devs(idevice) = CType(Marshal.PtrToStructure(New IntPtr(pDevices.ToInt64() + idevice * Marshal.SizeOf(GetType(BLUETOOTH_DEVICE_INFO))), GetType(BLUETOOTH_DEVICE_INFO)), BLUETOOTH_DEVICE_INFO)
                       Next
    
                       Return devs
                   End If
                   Return New BLUETOOTH_DEVICE_INFO(-1) {}
               End Get
           End Property
    
           Public ReadOnly Property Device As BLUETOOTH_DEVICE_INFO
               Get
                   If cNumDevices > 0 Then
                       Dim lDevice As BLUETOOTH_DEVICE_INFO = Marshal.PtrToStructure(pDevices, GetType(BLUETOOTH_DEVICE_INFO))
                       Return lDevice
                   End If
                   Return New BLUETOOTH_DEVICE_INFO()
               End Get
           End Property
       End Structure
       
        <StructLayout(LayoutKind.Sequential)>
        Structure SYSTEMTIME
            Public wYear As UShort
            Public wMonth As UShort
            Public wDayOfWeek As UShort
            Public wDay As UShort
            Public wHour As UShort
            Public wMinute As UShort
            Public wSecond As UShort
            Public wMilliseconds As UShort
        End Structure
        
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
        Public Structure BLUETOOTH_DEVICE_INFO
            Public dwSize As UInteger
            Public Address As ULong
            Public ulClassofDevice As UInteger
            Public fConnected As Boolean
            Public fRemembered As Boolean
            Public fAuthenticated As Boolean
            Public stLastSeen As SYSTEMTIME
            Public stLastUsed As SYSTEMTIME
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=248)>
            Public szName As String
        End Structure
        
        Public COD_FORMAT_BIT_OFFSET = (0)
        Public COD_MINOR_BIT_OFFSET = (2)
        Public COD_MAJOR_BIT_OFFSET = (8 * 1)
        Public COD_SERVICE_BIT_OFFSET = (8 * 1 + 5)
    
        Public COD_FORMAT_MASK = (&H3)
        Public COD_MINOR_MASK = (&HFC)
        Public COD_MAJOR_MASK = (&H1F00)
        Public COD_SERVICE_MASK = (&HFFE000)
    
        Public Function GET_COD_FORMAT(_cod As UInteger)
            Return ((_cod And COD_FORMAT_MASK) >> COD_FORMAT_BIT_OFFSET)
        End Function
    
        Public Function GET_COD_MINOR(_cod As UInteger)
            Return ((_cod And COD_MINOR_MASK) >> COD_MINOR_BIT_OFFSET)
        End Function
    
        Public Function GET_COD_MAJOR(_cod As UInteger)
            Return ((_cod And COD_MAJOR_MASK) >> COD_MAJOR_BIT_OFFSET)
        End Function
    
        Public Function GET_COD_SERVICE(_cod As UInteger)
            Return ((_cod And COD_SERVICE_MASK) >> COD_SERVICE_BIT_OFFSET)
        End Function
        
        Public Shared DeviceCallbackProc As PfnDeviceCallback = Nothing
    
        Public Shared Function DeviceCallback(pvParam As IntPtr, ByRef pDevice As BLUETOOTH_DEVICE_INFO) As Boolean
            ' Never reached...
            Return True
        End Function
    
    1 person found this answer helpful.
    0 comments No comments

3 additional answers

Sort by: Most helpful
  1. André Dussault 20 Reputation points
    2023-09-01T11:21:08.9766667+00:00

    I am trying to programmatically get the recognizable names of the BT interfaces connected to the computer, to match them to the COMxy names so that the program first recognizes (recognizable names) the interfaces it wants to work with AND then try and connect (COMxy) to them in the "transparent UART" mode.

    Easy said but not done...


  2. André Dussault 20 Reputation points
    2023-09-02T21:02:32.3766667+00:00

    Thank you Castorix31.

    I have to check my application's environment. It is a simple "forms-based VB application". I will try your suggestion during the next few days.

    Merci


  3. André Dussault 20 Reputation points
    2023-09-02T21:14:03.7566667+00:00

    Castorix31,

    Thank you indeed. I used your suggestions and when I imported the required components, it worked IMMEDIATELY.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.