• Партнер

  • Поместим на форму компонент TactionList и изменим его
    свойство Name на ActionList. Теперь два раза щелкнем по ActionList и в появившемся окне редактора свойств добавим две TAction со следующими свойствами: 
    Caption - Connectable, Name - acConnectable; Caption - Discoverable, Name - acDiscoverable.
    На панель Panel добавим две TButton и установим свойства:
    Action - acConnectable, Name - btConnectable; Action - acDiscoverable, Name
    -  btDiscoverable.

    Напишем вот такой обработчик события OnUpdate у acConnectable: 

    procedure TfmMain.acConnectableUpdate(Sender: TObject);
    var
    SelectedItem: TListItem;
    SelectedNode: TTreeNode;
    begin
    SelectedNode := TreeView.Selected;
    SelectedItem := ListView.Selected;

    with TAction(Sender) do 
    begin
    Enabled := Assigned(SelectedNode) and Assigned(SelectedItem) and (SelectedNode.ImageIndex = -1);

    if Enabled then
    if StrToBool(SelectedItem.SubItems[4])
    then Caption := 'Not conn.'
    else Caption := 'Connectable';
    end;
    end; 

    И то же самое напишем для обработчика события OnUpdate - acDiscoverable: 

    procedure TfmMain.acDiscoverableUpdate(Sender: TObject);
    var
    SelectedItem: TListItem;
    SelectedNode: TTreeNode;
    begin
    SelectedNode := TreeView.Selected;
    SelectedItem := ListView.Selected;

    with TAction(Sender) do 
    begin
    Enabled := Assigned(SelectedNode) and Assigned(SelectedItem) and (SelectedNode.ImageIndex = -1);

    if Enabled then 
    if StrToBool(SelectedItem.SubItems[5])
    then Caption := 'Not disc.'
    else Caption := 'Discoverable';
    end;
    end; 

    Теперь обработчик события OnExecute для acConnectable: 

    procedure TfmMain.acConnectableExecute(Sender: TObject);
    var
    SelectedItem: TListItem;
    begin
    SelectedItem := ListView.Selected;

    if Assigned(SelectedItem) then
    if not BluetoothEnableIncomingConnections(Integer(SelectedItem.Data), TAction(Sender).Caption = 'Not conn.') 
    then MessageDlg('Unable to change Radio state', mtError, [mbOK], 0)
    else TreeViewChange(TreeView, TreeView.Selected);
    end; 

    Такой же обработчик напишем и для OnExecute - acDiscoverable: 

    procedure TfmMain.acConnectableExecute(Sender: TObject);
    var
    SelectedItem: TListItem;
    begin
    SelectedItem := ListView.Selected;

    if Assigned(SelectedItem) then
    if not BluetoothEnableDiscovery(Integer(SelectedItem.Data), TAction(Sender).Caption = 'Not disc.') 
    then MessageDlg('Unable to change Radio state', mtError, [mbOK], 0)
    else TreeViewChange(TreeView, TreeView.Selected);
    end; 

    Вывод окна свойств устройства

    Важно: Если Windows сам использует радиомодуль, то он не даст поменять статус, хотя и функция выполнится без ошибок!

    Здесь мы ввели две новые функции:

    BluetoothEnableInfomingConnection - функция разрешает/запрещает подключения к локальному радиомодулю Bluetooth.

    Объявление функции: 

    function BluetoothEnableIncomingConnections(
    hRadio : THandle;
    fEnabled : BOOL): BOOL; stdcall; 

    Параметры:

    hRadio - Handle радиомодуля, статус которого мы хотим изменить. Если 0, то меняем у всех. 
    fEnabled  - TRUE – разрешаем подключения; FALSE – запрещаем. 

    Возвращаемые значения: 

    TRUE - если вызов успешен и статус изменен, 
    FALSE - в противном случае. 

    BluetoothEnableDiscovery - функция разрешает/запрещает обнаружение локального радиомодуля Bluetooth

    Объявление функции: 

    function BluetoothEnableDiscovery(
    hRadio : THandle;
    fEnabled : BOOL): BOOL; stdcall; 

    Параметры: 

    hRadio - Handle радиомодуля, статус которого мы хотим изменить. Если 0, то меняем у всех. 
    fEnabled - TRUE – разрешаем обнаружение; FALSE – запрещаем. 

    Возвращаемые значения: 

    TRUE - если вызов успешен и статус изменен, 
    FALSE - в противном случае. 

    Теперь давайте научимся выводить системное окно свойств устройства Bluetooth. Для этого добавим к ActionList еще один TAction.
    Добавим на Panel кнопку TButton с такими свойствами:
    Action - acProperty, Name - btProperty.

    Теперь напишем такой обработчик событий OnUpdate у acProperty: 

    procedure TfmMain.acPropertyUpdate(Sender: TObject);
    var
    SelectedNode: TTreeNode;
    SelectedItem: TListItem;
    begin
    SelectedNode := TreeView.Selected;
    SelectedItem := ListView.Selected;

    TAction(Sender).Enabled := Assigned(SelectedNode) and
    Assigned(SelectedItem) and
    (SelectedNode.ImageIndex > 0);
    end; 

    И обработчик OnExecute для нее же: 

    procedure TfmMain.acPropertyExecute(Sender: TObject);
    var
    Info: BLUETOOTH_DEVICE_INFO;
    begin
    Info := BLUETOOTH_DEVICE_INFO(ListView.Selected.Data^);
    BluetoothDisplayDeviceProperties(Handle, Info);
    end; 

    Важно: В исходном виде в файле JwaBluetoothAPIs функция BluetoothDisplayDeviceProperties объявлена не верно. Второй параметр должен быть указателем, а там он передается как структура. Я исправил функцию так, чтобы он передавался как var-параметр (по ссылке). Используйте модуль JwaBluetoothAPIs из этого примера, чтобы не возникало ошибок доступа к памяти.

    Важно: Ни в этой процедуре, ни ранее, ни далее я не провожу проверку ошибок, чтобы не загромождать код лишними подробностями. В реальном приложении НЕОБХОДИМО проверять возвращаемые функциями значения и указатели.

    И так, в этом коде есть новая функция, выделенная жирным шрифтом.

    BluetoothDisplayDeviceProperty - функция выводит стандартное окно свойств устройства Bluetooth.

    Объявление функции: 

    function BluetoothEnableDiscovery(
    hwndParent : HWND;
    var pbtdi : PBLUETOOTH_DEVICE_INFO): BOOL; stdcall; 

    Важно: В оригинале функция выглядит вот так: 

    function BluetoothEnableDiscovery(
    hwndParent : HWND;
    pbtdi : PBLUETOOTH_DEVICE_INFO): BOOL; stdcall;

    Это не верно, так как в документации Microsoft указано, что параметр pbtdi должен передаваться как указатель (что подразумевает запись PBLUETOOTH_DEVICE_INFO), но как я писал выше, этот тип ошибочен. Он не является указателем. Я изменил функцию так, как показано выше (так она и должна быть, если не менять определение типа). 

    Параметры: hwndParent Handle родительского окна, которому будет принадлежать диалог свойств. Может быть 0, тогда родительским выбирается окно Desktop. 

    pbtdi Указатель на структуру BLUETOOTH_DEVICE_INFO в которой содержится адрес требуемого устройства. 

    Возвращаемые значения: 

    TRUE - если вызов успешен 
    FALSE - в противном случае (код ошибки можно узнать вызовом функции GetLastError). 

    Выбор устройства 

    Рассмотрим, как вызвать окно диалога выбора устройства.

    Добавим в наш проект на Panel еще одну кнопку TButton и установите ее свойства как в таблице:
    Caption - Select, Name - btSelect .

    Напишем вот такой обработчик события OnClick у этой кнопки: 

    procedure TfmMain.btSelectClick(Sender: TObject);
    var
    ASelParams: BLUETOOTH_SELECT_DEVICE_PARAMS;
    ASelParamsSize: dword;
    begin
    ASelParamsSize := SizeOf(BLUETOOTH_SELECT_DEVICE_PARAMS);
    FillChar(ASelParams, ASelParamsSize, 0);
    with ASelParams do 
    begin
    dwSize := ASelParamsSize;
    hwndParent := Handle;
    fShowRemembered := True;
    fAddNewDeviceWizard := True;
    end;

    BluetoothSelectDevices(@ASelParams);
    BluetoothSelectDevicesFree(@ASelParams);
    end 

    В этой части кода две новые функции.

    BluetoothSelectDevices - функция разрешает/запрещает обнаружение локального радиомодуля Bluetooth.

    Объявление функции: 

    function BluetoothSelectDevices(
    pbtsdp : PBLUETOOTH_SELECT_DEVICE_PARAMS): BOOL; stdcall; 

    Параметры: pbtsdp Описание смотрите ниже в описании структуры. 

    Возвращаемые значения:

    Если функция вернула TRUE, то пользователь выбрал устройства. Pbtsdp^.pDevices будет указывать на корректные данные. После вызова необходимо проверить флаги fAuthenticated и fRemembered, что бы удостовериться в корректности данных. Для освобождения памяти используйте функцию BluetoothSelectDevicesFree, только если функция вернет TRUE.

    Вернет FALSE если вызов прошел не удачно. Используйте GetLastError для получения дополнительных сведений. Возможные ошибки: 

    ERROR_CANCELLED - Пользователь отменил выбор устройства. 
    ERROR_INVALID_PARAMETER - Параметр pbsdp равен nil. 
    ERROR_REVISION_MISMATCH - Структура, переданная в pbsdp неизвестного или неверного размера. 

    BLUETOOTH_SELECT_DEVICE_PARAMS

    Объявление: 

    BLUETOOTH_SELECT_DEVICE_PARAMS = record
    dwSize : DWORD;
    cNumOfClasses : ULONG;
    prgClassOfDevices : PBlueToothCodPairs; 
    pszInfo : LPWSTR; 
    hwndParent : HWND; 
    fForceAuthentication : BOOL;
    fShowAuthenticated : BOOL;
    fShowRemembered : BOOL;
    fShowUnknown : BOOL;
    fAddNewDeviceWizard : BOOL;
    fSkipServicesPage : BOOL; 
    pfnDeviceCallback : PFN_DEVICE_CALLBACK;
    pvParam : Pointer;
    cNumDevices : DWORD;
    pDevices : __PBLUETOOTH_DEVICE_INFO; 
    end; 

    Члены: 

    wSize - Должен быть равен размеру структуры (dwSize := SizeOf(BLUETOOTH_RADIO_INFO)) 
    cNumOfClasses - Входной параметр. Количество записей в массиве prgClassOfDevice. Если 0, то ищутся все устройства. 
    prgClassOfDevices - Входной параметр. Массив COD (классов устройств), которые необходимо искать. 
    pszInfo - Входной параметр. Если не nil, то задает текст заголовка окна выбора устройства. 
    hwndParent - Входной параметр. Handle родительского окна для диалога выбора устройства. Если 0, то родителем будет Desktop. 
    fForceAuthentication - Входной параметр. Если TRUE, то требует принудительной авторизации устройств. 
    fShowAuthenticated - Входной параметр. Если TRUE, то авторизованные устройства будут доступны для выбора. 
    fShowRemembered - Входной параметр. Если TRUE, то запомненные устройства будут доступны для выбора. 
    fShowUnknown - Входной параметр. Если TRUE, то неизвестные (неавторизованные и не запомненные) устройства будут доступны для выбора. 
    fAddNewDeviceWizard - Входной параметр. Если TRUE, то запускает мастер добавления нового устройства. 
    fSkipServicesPage - Входной параметр. Если TRUE, то пропускает страницу Сервисы в мастере. 
    pfnDeviceCallback - Входной параметр. Если не nil, то является указателем на функцию обратного вызова, которая вызывается для каждого найденного устройства. Если функция вернет TRUE, то устройства добавляется в список, если нет, то устройство игнорируется. 
    pvParam - Входной параметр. Его значение будет передано функции pfnDeviceCallback в качестве параметра pvParam. 
    cNumDevices - Как входной параметр – количество устройств, которое требуется вернуть. Если 0, то нет ограничений. Как выходной параметр – количество возвращенных устройств (выбранных). 
    pDevices - Выходной параметр. Указатель на массив структур BLUETOOTH_DEVICE_INFO. Для его освобождения используйте функцию
    BluetoothSelectDevicesFree.

    Важно: В оригинале этот параметр объявлен как PBLUETOOTH_DEVICE_INFO. По этому поводу здесь много комментариев. 

    BluetoothSelectDevicesFree - функция должна вызываться, только если вызов BluetoothSelectDevices был успешен. Эта функция освобождает память и ресурсы, задействованные функцией BluetoothSelectDevices в структуре BLUETOOTH_SELECT_DEVICE_PARAMS.

    Объявление функции: 

    function BluetoothSelectDevices(
    pbtsdp : PBLUETOOTH_SELECT_DEVICE_PARAMS): BOOL; stdcall; 

    Параметры: pbtsdp Описание смотрите выше в описании структуры. 

    Возвращаемые значения: 

    TRUE - если вызов успешен, 
    FALSE - нечего освобождать. 

    Управление сервисами 

    Для управления сервисами Microsoft Bluetooth API предоставляет функцию:

    BluetoothSetServiceState - включает или выключает указанный сервис для устройства Bluetooth. Система проецирует сервис Bluetooth на соответствующий драйвер. При отключении сервиса – драйвер удаляется. При его включении – драйвер устанавливается. Если выполняется включение не поддерживаемого сервиса, то драйвер не будет установлен.

    Объявление функции: 

    function BluetoothSetServiceState(
    hRadio : Thandle;
    var pbtdi : PBLUETOOTH_DEVICE_INFO;
    const pGuidService : TGUID;
    dwServiceFlags : DWORD): DWORD; stdcall; 

    Параметры: 

    hRadio - Описатель радиомодуля. 
    pbtdi - Указатель на структуру BLUETOOTH_DEVICE_INFO. 
    pGuidService - GUID сервиса, который необходимо включить/выключить. 
    dwServiceFlags - Флаги управления сервисом:

    BLUETOOTH_SERVICE_DISABLE – отключает сервис;
    BLUETOOTH_SERVICE_ENABLE – включает сервис. 

    Возвращает ERROR_SUCCESS если вызов прошел успешно. Если вызов не удался вернет один из следующих кодов:

    ERROR_INVALID_PARAMETER - Неверные флаги в dwServiceFlags 
    ERROR_SERVICE_DOES_NOT_EXIST - Указанный сервис не поддерживается 

    Важно: В оригинале (см. примечание выше) функция выглядит вот так: 

    function BluetoothSetServiceState(
    hRadio : Thandle;
    pbtdi : PBLUETOOTH_DEVICE_INFO;
    const pGuidService : TGUID;
    dwServiceFlags : DWORD): DWORD; stdcall; 

    Это не верно, так как в документации Microsoft указано, что параметр pbtdi должен передаваться как указатель (что подразумевает запись PBLUETOOTH_DEVICE_INFO), но как я писал выше, этот тип ошибочен. Он не является указателем. Я изменил функцию так, как показано выше (так она и должна быть, если не менять определение типа). 

    Как использовать функцию? Давайте добавим к ActionList еще одну TAction с такими свойствами:
    Caption - Disable, Name - acEnable. И добавим на Panel еще одну кнопку TButton, установив у нее следующие свойства:
    Action - acEnable, Name - btEnable.

    В обработчике события OnUpdate для acEnable напишем вот такой код: 

    procedure TfmMain.acEnableUpdate(Sender: TObject);
    var
    SelectedNode: TTreeNode;
    SelectedItem: TListItem;
    begin
    SelectedNode := TreeView.Selected;
    SelectedItem := ListView.Selected;

    TAction(Sender).Enabled := Assigned(SelectedNode) and
    Assigned(SelectedItem) and
    (SelectedNode.ImageIndex = -2);
    end; 

    А в обработчике OnExecute для acEnable вот такой код: 

    procedure TfmMain.acEnableExecute(Sender: TObject);
    var
    GUID: TGUID;
    begin
    GUID := StringToGUID(ListView.Selected.Caption);
    BluetoothSetServiceState(TreeView.Selected.Parent.ImageIndex,
    BLUETOOTH_DEVICE_INFO(TreeView.Selected.Data^),
    GUID, 
    BLUETOOTH_SERVICE_DISABLE);
    end; 

    Важно: После нажатия на кнопку btEnable сервис будет удален из системы. Включить его можно будет через окно свойств устройства Bluetooth.

    Как определять отключенные сервисы рассмотрим в серии про передачу данных через Bluetooth.

    Удаление устройств 

    Для удаления устройств используется функция:

    BluetoothRemoveDevice - функция удаляет авторизацию между компьютером и устройством Bluetooth. Так же очищает кэш-записи об этом устройстве.

    Объявление функции: 

    function BluetoothRemoveDevice(
    var pAddress : BLUETOOTH_ADDRESS): DWORD; stdcall; 

    Параметры: 

    hAddress - Адрес устройства, которое удаляется. 

    Возвращаемые значения: 

    ERROR_SUCCESS - устройство удалено 
    ERROR_NOT_FOUND - устройство не найдено 

    Давайте попробуем. Добавим в ActionList TAction со следующими свойствами:
    Caption - Remove, Name - acRemove. И на Panel кнопку TButton со свойствами:
    Action - acRemove, Name - btRemove.

    В обработчике OnUpdate для acRemove напишем следующий код: 

    procedure TfmMain.acRemoveUpdate(Sender: TObject);
    begin
    TAction(Sender).Enabled := acProperty.Enabled;
    end; 

    А для события OnExecute вот такой код: 

    procedure TfmMain.acRemoveExecute(Sender: TObject);
    var
    Info: BLUETOOTH_DEVICE_INFO;
    Res: dword;
    begin
    Info := BLUETOOTH_DEVICE_INFO(ListView.Selected.Data^);
    Res := BluetoothRemoveDevice(Info.Address);
    if Res <> ERROR_SUCCESS then
    MessageDlg('Device not found', mtError, [mbOK], 0);
    TreeViewChange(TreeView, TreeView.Selected);
    end; 

    Процедура выполняется достаточно долго, так что не думайте, что программа зависла.

    Важно: Устройство удаляется из списка. Однако, если уже иметь адрес устройства, то можно получить о нем информацию.

    Есть еще одно функция, которая связана с BluetoothRemoveDevice. Это:

    BluetoothUpdateDeviceRecord - функция обновляет данные об устройстве в кэше.

    Объявление функции: 

    function BluetoothUpdateDeviceRecord(
    var pbtdi : BLUETOOTH_DEVICE_INFO): DWORD; stdcall; 

    Параметры: 

    pbtdu - Указатель на структуру BLUETOOTH_DEVICE_INFO. 

    В ней должны быть заполнены поля:
    dwSize – размер структуры;
    Address – адрес устройства;
    szName – новое имя устройства. 

    Возвращаемые значения: 

    ERROR_SUCCESS - Функция выполнена успешно 
    ERROR_INVALID_PARAMETER - Указатель pbtdi=nil. (Для варианта в Delphi не реально, так как указатель мы получаем из структуры, передавая ее как var-параметр). 
    ERROR_REVISION_MISMATCH - Размер структуры в dwSize не правильный 

    Попробуем использовать и ее. Схема стандартная: TAction к ActionList, TButton на
    Panel: 
    Caption - Update 
    Name - acUpdate 

    Action - acUpdate 
    Name - btUpdate 

    Код: 

    procedure TfmMain.acUpdateUpdate(Sender: TObject);
    begin
    TAction(Sender).Enabled := acProperty.Enabled;
    end; procedure TfmMain.acUpdateExecute(Sender: TObject);
    var
    Info: BLUETOOTH_DEVICE_INFO;
    Res: dword;
    NewName: string;
    begin
    if InputQuery('Имя устройства', 'Новое имя', NewName) then begin
    lstrcpyW(Info.szName, PWideChar(WideString(NewName)));
    Res := BluetoothUpdateDeviceRecord(Info);
    if Res <> ERROR_SUCCESS then RaiseLastOsError;
    TreeViewChange(TreeView, TreeView.Selected);
    end;
    end; 

    Как видите, все просто. 

    Итак, удалять устройства мы умеем. Давайте теперь научимся добавлять их. Для этого Bluetooth API предоставляет две функции:

    BluetoothAuthenticateDevice - отправляет запрос на авторизацию удаленному устройству Bluetooth. Есть два режима авторизации: "Wizrd mode" и "Blind Mode".

    "Wizard Mode" запускается, когда параметр pszPasskey = nil. В этом случае открывается окно "Мастера подключения". У пользователя будет запрошен пароль, который будет отправлен в запросе на авторизацию удаленному устройству. Пользователь будет оповещен системой об успешном или не успешном выполнении авторизации и получит возможность попытаться авторизировать устройства еще раз.

    "Blind Mode" вызывается, когда pszPasskey <> nil. В этом случае пользователь не увидит никакого мастера. Вам необходимо программно запросить код авторизации (pszPasskey) и уведомить пользователя о результате.

    Объявление функции: 

    function BluetoothAuthenticateDevice(
    hwndParent : HWND;
    hRadio : THandle;
    pbtdi : BLUETOOTH_DEVICE_INFO;
    pszPasskey : PWideChar;
    ulPasskeyLength : ULONG): DWORD; stdcall; 

    Параметры: 

    hwndParent - Handle родительского окна. Если 0, то родительским окном станет окно Desktop. 
    hRadio - Handle локального радиомодуля. Если 0, то авторизация будет проведена на всех радиомодулях. Если хотя бы один пройдет авторизацию, функция выполнится успешно. 
    pbdti - Информация об устройстве, на котором необходимо авторизироваться. 
    pszPasskey - PIN для авторизации. Если nil, то вызывается мастер авторизации (описано выше). Важно: pszPasskey не NULL-терминированная строка! 
    ulPasskeyLength - Длина строки в байтах. Должна быть меньше либо равна BLUETOOTH_MAX_PASSKEY_SIZE * SizeOf(WCHAR). 

    Возвращаемые значения: 

    ERROR_SUCCESS - Функция выполнена успешно 
    ERROR_CANCELLED - Пользователь отменил процесс авторизации 
    ERROR_INVALID_PARAMETER - Структура pbtdi не верна 
    ERROR_NO_MORE_ITEMS - Устройство в pbtdi уже авторизированно 

    Аналогичная функция:

    BluetoothAuthenticateMultipleDevices - позволяет авторизироваться сразу на нескольких устройствах при помощи одной копии "Мастера авторизации".

    Объявление функции: 

    function BluetoothAuthenticateMultipleDevices(
    hwndParent : HWND;
    hRadio : THandle;
    cDevices : DWORD;
    rgpbtdi : __PBLUETOOTH_DEVICE_INFO): DWORD; stdcall; 

    Параметры: 

    hwndParent - Handle родительского окна. Если 0, то родительским окном станет окно Desktop. 
    hRadio - Handle локального радиомодуля. Если 0, то авторизация будет проведена на всех радиомодулях. Если хотя бы один пройдет авторизацию, функция выполнится успешно. 
    cDevices - Количество элементов в массиве rgpbtdi. 
    rgpbtdi - Массив структур BLUETOOTH_DEVICE_INFO, в котором представлены устройства для авторизации. 

    Возвращаемые значения: 

    ERROR_SUCCESS - Функция выполнена успешно. Проверьте флаг fAuthenticated у каждого устройства, что бы знать, какие прошли авторизацию. 
    ERROR_CANCELLED - Пользователь отменил процесс авторизации. Проверьте флаг fAuthenticated у каждого устройства, что бы знать, какие прошли авторизацию. 
    ERROR_INVALID_PARAMETER - Один или несколько элементов массива rgpbtdi не верны. 
    ERROR_NO_MORE_ITEMS - Все устройства в массиве уже авторизированны. 

    Важно: В оригинале функция выглядит вот так: 

    function BluetoothAuthenticateMultipleDevices(
    hwndParent : HWND;
    hRadio : THandle;
    cDevices : DWORD;
    pbtdi : PBLUETOOTH_DEVICE_INFO): DWORD; stdcall; 

    Это не верно, так как в документации Microsoft указано, что параметр rgpbtdi должен передаваться как указатель (что подразумевает запись PBLUETOOTH_DEVICE_INFO), но как я писал выше, этот тип ошибочен. Он не является указателем. Я изменил функцию так, как показано выше. По поводу типа __PBLUETOOTH_DEVICE_INFO я писал выше. 

    Описывать с примером, как использовать эти функции не буду, так как они тривиальны (если вы прочитали все вышеизложенное). Остались последние три функции, которые мы не рассмотрели:

    BluetoothRegisterForAuthentication - регистрирует функцию обратного вызова, которая будет вызываться на запрос устройства об авторизации. Если несколько приложений зарегистрировало такую функцию, то будет вызвана функция в последнем приложении.

    Объявление функции: 

    function BluetoothRegisterForAuthentication(
    var pbtdi : PBLUETOOTH_DEVICE_INFO;
    var phRegHandle : HBLUETOOTH_AUTHENTICATION_REGISTRATION;
    pfnCallback : PFN_AUTHENTICATION_CALLBACK;
    pvParam : Pointer): DWORD; stdcall; 

    Параметры: 

    pbtdi - Указатель на BLUETOOTH_DEVICE_INFO. Используется адрес устройства, для которого регистрируется функция. Обратите внимание на параметр. В оригинале он опять передается не как указатель. 
    phRegHandle - Указатель, куда будет возвращен Handle регистрации, которой потом используется в BluetoothUnregisterAuthentication. 
    pfnCallback - Функция обратного вызова. 
    pvParam - Опциональный параметр, который без изменения передается в функцию обратного вызова. 

    Возвращаемые значения: 

    ERROR_SUCCESS - Функция выполнена успешно. 
    ERROR_OUTOFMEMORY - Недостаточно памяти. 

    BluetoothUnregisterAuthentication - удаляет функцию обратного вызова, зарегистрированную функцией BluetoothRegisterForAuthentication и закрывает Handle.

    Объявление функции: 

    function BluetoothUnregisterAuthentication(
    hRegHandle : HBLUETOOTH_AUTHENTICATION_REGISTRATION): BOOL; stdcall; 

    Параметры: 

    hRegHandle - Handle регистрации, полученный функцией BluetoothRegisterForAuthentication. 

    Возвращаемые значения:

    Вернет TRUE, если вызов успешен и FALSE в случае неудачи. Используйте GetLastError для получения дополнительной информации.

    BluetoothSendAuthenticationResponse - эта функция должна вызываться из функции обратного вызова при запросе авторизации удаленным устройством для передачи PIN.

    Объявление функции: 

    function BluetoothSendAuthenticationResponse(
    hRadio : THandle;
    pbtdi : PBLUETOOTH_DEVICE_INFO;
    pszPasskey : LPWSTR): DWORD; stdcall; 

    Параметры: 

    hRadio - Handle радиомодуля, для которого проводим авторизацию. Если 0, то пытаемся на всех. 
    pbtdi - Указатель на BLUETOOTH_DEVICE_INFO с данными об устройстве, от которого поступил запрос на авторизацию. Может быть тот же указатель, который передан в функцию обратного вызова. 
    pszPasskey - Указатель на UNICODE строку, в которой содержится ключ авторизации (PIN). 

    Возвращаемые значения: 

    ERROR_SUCCESS - Функция выполнена успешно. 
    ERROR_CANCELLED - Устройство отвергло авторизационный код (PIN). Так же, возможно, имеются проблемы со связью 
    E_FAIL - Устройство вернуло ошибку авторизации. 

    И, наконец, функция обратного вызова:

    PFN_AUTHENTICATION_CALLBACK

    Описание этой функции дано выше. Здесь приведу лишь определеннее.

    Объявление функции: 

    PFN_AUTHENTICATION_CALLBACK =
    function(pvParam : Pointer;
    pDevice : PBLUETOOTH_DEVICE_INFO): BOOL; stdcall; 

    Параметры: 

    pvParam - Указатель на параметр, который мы передали в BluetoothRegisterForAuthentication. 
    pDevice - Указатель на BLUETOOTH_DEVICE_INFO с данными об устройстве, от которого поступил запрос на авторизацию. 

    Заключение 

    На этот раз все. Мы рассмотрели все функции Bluetooth API от Microsoft. Также мы научились управлять устройствами и радиомодулями Bluetooth, проводить авторизацию и получать информацию об этих устройствах.

    Но актуальным остается вопрос, который мне многие задают. Как же все-таки передавать данные между устройствами
    Bluetooth? Ответ на этот вопрос читайте в следующей
    статье. Конечно, можно было бы всю эту информацию уместить в эти статьи, но объем ее не сравним с предоставленным здесь. Так что наберитесь терпения. Я постараюсь надолго не задерживать с выходом новой серии.
    Полностью рабочий пример, рассмотренный в этой статье, вы можете
    скачать здесь.

    Я буду рад любым замечаниям и пожеланиям по данной теме.

    P.S. Внимательно относитесь к сторонним библиотекам. Как видите, в JWALIB оказалось много ошибок, которые порой загоняют в тупик. Я минут 20 смотрел на Access Violation, пока не понял, в чем дело.

    Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии