Поместим на форму компонент 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, пока не понял, в чем дело.