Code:
' BlueTooth Framework Demo - Mike Trader Oct 2007

' This demonstrates the detecting of Paired bluetooth devices, selecting of the first device found
' and sending an AT command to that device to dial (800)555-1212.
' (The first device should be a cell phone - or you will need to adjust the code) 
                                           
' Requires Bluetooth Framework: Bluetooth® Framework X Demo
' available at: http://www.btframework.com/download.htm
' If you have the Widdcom Stack put the bftowdthunk.dll in the SYSTEM folder
' BluetoothFrameworkX.ocx may be local to the app or in the system folder

' Also required: "BTF.inc" wrappers
' available at: http://www.jose.it-berater.org/smfforum/index.php?topic=1391.0

' Many thanks to Mike Petrichenko, Dominic Mitchell and the amazing Jose Roca for making this possible.         


' COM info
' A useable COM Object comprises a Dispatch Interface whose member Methods and Properties 
' can be accessed by a COM client.  
' An Object's Dispatch Interface is uniquely identifiable by its PROGID and CLSID.  
' Broadly speaking, a Dispatch Interface is the actual mechanism that is used by a COM-aware 
' application to communicate with the COM Object
' Further, a PROGID and a CLSID must be present to uniquely identify each Dispatch 
' Interface exposed by a COM Object. 
             
' The term COM is often used in the software development world as an umbrella term 
' that encompasses the OLE, OLE Automation, ActiveX, COM+ and DCOM technologies.
                  
' Different component types are identified by class IDs (CLSIDs), which are Globally Unique Identifiers

' Because the location of each component is stored in a system-wide location 
' (the Windows registry), there can be only one version of a certain component installed. 
' Thus, COM seriously suffers from DLL hell, where two or more applications require 
' different versions of the same component.
 
' use DllRegisterServer to register the OCX Dll

'  A COM object is basically a C++ class (structure) that always starts with a pointer to its VTable 
'  (an array of function pointers). The first three pointers in the VTable will always be named:
'  QueryInterface, AddRef, and Release. 
'  What additional functions may be in its VTable, and what the name of their pointers are, 
'  depends upon what type of object it is.
'      
'  Globally Universal Identifier (GUID) is a 16 byte array that is filled in with a unique series of bytes. 
'  And when I say unique, I do mean unique, it cannot have the same series of bytes as another GUID... 
'  anywhere in the world. Every GUID ever created has a unique series of 16 bytes.  
'  
'  Microsoft has defined a COM object known as an IUnknown. An IUnknown objects VTable contains only the 
'  QueryInterface, AddRef, and Release functions  
'  In other words, an IUnknown is the bare minimum COM object
'  Microsoft created a special GUID for an IUnknown object, But Our IExample object can also masquerade 
'  as an IUnknown object because it has the QueryInterface, AddRef, and Release functions in it.
'          
'  Microsoft's include files give the IUnknown GUID the C variable name IID_IUnknown: 
'  
'  - Bluetooth® Framework VCL™ can be uses with following Bluetooth® APIs: 
'  - Microsoft® Bluetooth® API (Windows XP® + SP2 and high)
'  - WidComm® (BroadComm®) Bluetooth® API (1.4.2.10 SP5 and high)
'  - BlueSoleil® (IVT®) Bluetooth® API (1.6 and high) 
'  - Toshiba® Bluetooth® API (4.0 and high) (Servers not supported).
'    
'  Tested Devices List - http://www.btframework.com/devices.htm

        




#COMPILE EXE "BTFDemo.exe"
#DIM ALL

#INCLUDE "WIN32API.inc" ' Power Basic Win32 API Declares
                       
#INCLUDE "BTF.inc" ' Interface Definitions for BluetoothFrameworkX Library
                                          
                       

                    
%CLSCTX_INPROC_SERVER   = 1    ' The code that creates and manages objects of this class is a DLL that 
                               ' runs IN the same process AS the caller OF the FUNCTION specifying the class context.
%CLSCTX_INPROC_HANDLER  = 2    ' The code that manages objects of this class is an in-process handler.
%CLSCTX_LOCAL_SERVER    = 4    ' The EXE code that creates and manages objects of this class runs on 
                               ' same machine but is loaded in a separate process space.
%CLSCTX_REMOTE_SERVER   = 16   ' A remote machine context.
%CLSCTX_SERVER          = 21   ' %CLSCTX_INPROC_SERVER OR %CLSCTX_LOCAL_SERVER OR %CLSCTX_REMOTE_SERVER
%CLSCTX_ALL             = 23   ' %CLSCTX_INPROC_HANDLER OR %CLSCTX_SERVER


'¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤'
' Decrements the reference Count for the calling interface on a object. If the reference
' Count on the object falls to 0, the object is freed from memory.
FUNCTION IUnknown_Release(BYVAL pthis AS DWORD PTR) AS DWORD
    LOCAL DWRESULT AS DWORD
    IF pthis = %NULL THEN EXIT FUNCTION
    CALL DWORD @@pthis[2] USING IUnknown_Release(pthis) TO DWRESULT
    FUNCTION = DWRESULT
END FUNCTION
        


'¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤'
FUNCTION PBMAIN 

  LOCAL i, RetVal, Count, lReturn, hFile, NeedLF AS LONG
  LOCAL iReturn, iAuth, iBluetooth AS INTEGER  
  LOCAL dReturn AS DOUBLE
  LOCAL dwReturn AS DWORD
  LOCAL dwContext, pInfo, pDiscovery, pDevices, pDevice, pSerial, pTransport AS DWORD 
  LOCAL s, sReturn, sDeviceAddr, sCommand, sResponse AS STRING
  LOCAL CLSID, IID AS GUID  

  LOCAL tAPIs         AS BFBluetoothAPIsX  
  LOCAL tTransports   AS BFAPITransportsX

                       

              
    dwContext = %CLSCTX_INPROC_SERVER 
                          

    ' Get a reference to Info
    CLSID = $CLSID_BFAPIInfoX 
    IID   = $IID_IBFAPIInfoX  
    RetVal = CoCreateInstance(CLSID, BYVAL %NULL, dwContext, IID, pInfo) 
    IF pInfo = 0 THEN 
      MSGBOX "Error="+HEX$(RetVal)+", pInfo="+STR$(pInfo),48,"CoCreateInstance Error"
      EXIT FUNCTION
    END IF  

    RetVal = BTF_IBFAPIInfoX_get_HasBluetooth(pInfo, iBluetooth)
    s = s + "HasBluetooth = " + STR$(iBluetooth) + $CRLF + $CRLF 
    IF iBluetooth = 0 THEN MSGBOX "No BlueTooth Stack found",48,"BlueTooth Error"

    BTF_IBFAPIInfoX_get_BluetoothAPIs pInfo, tAPIs
    s = s + "BlueSoleil = " + STR$(tAPIs.baBlueSoleil) + $CRLF + _
            "Toshiba = "    + STR$(tAPIs.baToshiba)    + $CRLF + _
            "WidComm = "    + STR$(tAPIs.baWidComm)    + $CRLF + _
            "WinSock = "    + STR$(tAPIs.baWinSock)    + $CRLF + $CRLF 
 
    RetVal = BTF_IBFAPIInfoX_get_Transports(pInfo, tTransports)
    s = s + "Bluetooth = "  + STR$(tTransports.Bluetooth) + $CRLF + _
            "COMPort = "    + STR$(tTransports.COMPort)   + $CRLF + _
            "IrDA = "       + STR$(tTransports.IrDA)      + $CRLF + $CRLF  

    IUnknown_Release pInfo
    '=====================

    MSGBOX "Search for Bluetooth Devices?"+$CRLF+"(This may take a minute)",64,"BlueTooth"
             


    ' Get a reference to Discovery
    CLSID = $CLSID_BFBluetoothDiscoveryX 
    IID   = $IID_IBFBluetoothDiscoveryX  
    RetVal = CoCreateInstance(CLSID, BYVAL %NULL, dwContext, IID, pDiscovery) 
    IF pDiscovery = 0 THEN 
      MSGBOX "Error="+HEX$(RetVal)+", pDiscovery="+STR$(pDiscovery),48,"CoCreateInstance Error"
      EXIT FUNCTION
    END IF  
  
 
    ' Get a reference to the Devices collection Object
    RetVal = BTF_IBFBluetoothDiscoveryX_Discovery(pDiscovery, 0, -1, 0, -1, pDevices)
    IF pDevices = 0 THEN   
      MSGBOX "Error="+HEX$(RetVal)+", pDevices="+STR$(pDevices),48,"Devices Error" 
      EXIT FUNCTION
    END IF
           

    RetVal = BTF_IBFBluetoothDevicesX_get_Count(pDevices, Count)    
    FOR i = 0 TO Count-1 
      s = s + "Device="+STR$(i) + $CRLF
        
      RetVal = BTF_IBFBluetoothDevicesX_get_Device(pDevices, i, pDevice)
      IF pDevice = 0 THEN   
        s = s + "Device Error" + $CRLF + $CRLF
        ITERATE
      END IF
             
      RetVal = BTF_IBFBluetoothDeviceX_get_Name(pDevice, sReturn)
      s = s + "Name="+sReturn + $CRLF

      RetVal = BTF_IBFBluetoothDeviceX_get_Address(pDevice, sReturn)
      s = s + "Address="+sReturn + $CRLF 
      IF i = 0 THEN sDeviceAddr = sReturn
                     
      RetVal = BTF_IBFBluetoothDeviceX_get_ClassOfDevice(pDevice, lReturn)
      s = s + "ClassOfDevice="+HEX$(lReturn) + $CRLF

      RetVal = BTF_IBFBluetoothDeviceX_get_ClassOfDeviceName(pDevice, sReturn)
      s = s + "ClassOfDeviceName="+sReturn + $CRLF
                            
      RetVal = BTF_IBFBluetoothDeviceX_get_Services(pDevice, dwReturn) 
      s = s + "Services="+HEX$(dwReturn) + $CRLF

      RetVal = BTF_IBFBluetoothDeviceX_get_Remembered(pDevice, iReturn)
      s = s + "Remembered="+STR$(iReturn) + $CRLF 

      RetVal = BTF_IBFBluetoothDeviceX_get_Authenticated(pDevice, iReturn)
      s = s + "Authenticated="+STR$(iReturn) + $CRLF 
      IF i = 0 THEN iAuth = iReturn

      RetVal = BTF_IBFBluetoothDeviceX_get_BTAddress(pDevice, dReturn) 
      s = s + "BTAddress="+STR$(dReturn) + $CRLF

      RetVal = BTF_IBFBluetoothDeviceX_get_Connected(pDevice, iReturn)
      s = s + "Connected="+STR$(iReturn) + $CRLF

      RetVal = BTF_IBFBluetoothDeviceX_get_LastSeen(pDevice, dReturn) 
      s = s + "LastSeen="+STR$(dReturn) + $CRLF
          
      RetVal = BTF_IBFBluetoothDeviceX_get_LastUsed(pDevice, dReturn) 
      s = s + "LastUsed="+STR$(dReturn) + $CRLF

      s = s + $CRLF + $CRLF  
    NEXT
    IUnknown_Release pDevice
    IUnknown_Release pDevices 
    '=====================
              
            

    s = s + "Dial number on First Device?"
    MSGBOX s,64,"BlueTooth"

                     


    ' Get a reference to SerialPortClient
    CLSID = $CLSID_BFSerialPortClientX 
    IID   = $IID_IBFSerialPortClientX   
    RetVal = CoCreateInstance(CLSID, BYVAL %NULL, dwContext, IID, pSerial) 
    IF pSerial = 0 THEN 
      MSGBOX "Error="+HEX$(RetVal)+", pSerial="+STR$(pSerial),48,"CoCreateInstance Error"
      EXIT FUNCTION
    END IF  
                
    ' Get a reference to the BluetoothTransport object
    RetVal = BTF_IBFSerialPortClientX_get_BluetoothTransport(pSerial, pTransport)
    IF RetVal THEN   
      MSGBOX "Error="+HEX$(RetVal),48,"OpenDevice Error" 
      EXIT FUNCTION
    END IF
             
    RetVal = BTF_IBFBluetoothClientTransportX_put_Address(pTransport, sDeviceAddr) ' Set the Device Address  

    RetVal = BTF_IBFSerialPortClientX_Open(pSerial) ' Open a connection to the specified Device
    IF RetVal THEN   
      MSGBOX "Error="+HEX$(RetVal),48,"OpenDevice Error" 
      EXIT FUNCTION
    END IF
             

    sCommand = "ATD8005551212;" ' 800 Directory Assistance - ";" indicates a voice call
    NeedLF = 0 ' Need a Line Feed?
    RetVal = BTF_IBFSerialPortClientX_ExecuteATCommand(pSerial, sCommand, sResponse, NeedLF) ' Send the AT Command
    MSGBOX "Response: "+sResponse,64,"AT Command: "+sCommand   
    IUnknown_Release pSerial     
    IUnknown_Release pTransport 
    '=====================



END FUNCTION  

'¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤'