В данной статье мы рассмотрим, как настроить уведомления для новых NFC-токенов в Delphi с использованием функции RegisterDeviceNotification. Мы обсудим, как правильно определить GUID, тип устройства и обработку уведомлений, а также рассмотрим возможные решения для устранения проблем.
Введение
Функция RegisterDeviceNotification используется для регистрации уведомлений о событиях устройств в системе Windows. Это полезно, например, для отслеживания подключения и отключения внешних устройств, таких как NFC-токены. В Delphi эта функция доступна через WinAPI, и её использование требует правильного настройки параметров, таких как GUID и тип устройства.
Проблемы и вопросы
1. Правильный ли GUID?
Ваш вопрос касается того, правильно ли выбран GUID для NFC-токена. В Device Manager вы взяли GUID для неизвестного смарт-кард токена (NFC-токена). Однако для RegisterDeviceNotification требуется GUID интерфейса устройства, а не класса устройства.
2. Тип устройства DBT_DEVTYP_DEVICEINTERFACE
Вы задаетесь вопросом, правильно ли выбран тип устройства DBT_DEVTYP_DEVICEINTERFACE. Этот тип используется для регистрации уведомлений о событиях интерфейсов устройств. Для NFC-токенов, как правило, используется GUID интерфейса, который можно найти в свойствах устройства.
Решение
1. Определение GUID интерфейса
Для определения GUID интерфейса устройства можно использовать утилиту USB Device Tree Viewer, если устройство является USB-устройством. В Device Manager найдите свойства устройства и в разделе "Дополнительные параметры" найдите GUID интерфейса. Для NFC-токенов это может быть GUID_DEVINTERFACE_SCFILTER.
2. Использование правильного GUID интерфейса
В вашем коде вы используете testguid со значением {990a2bd7-e738-46c7-b26f-1cf8fb9f1391}, который, как выяснилось, является GUID класса устройства, а не интерфейса. Для NFC-токенов правильный GUID интерфейса может быть, например, GUID_DEVINTERFACE_SCFILTER.
3. Обработка уведомлений
Когда вы получаете сообщение WM_DEVICECHANGE, важно правильно обрабатывать различные типы событий. В вашем коде вы обрабатываете три типа событий: DBT_DEVNODES_CHANGED, DBT_DEVICEARRIVAL и DBT_DEVICEREMOVECOMPLETE. Однако, если у вас нет пути устройства (Device Path), то уведомления об интерфейсе устройства не будут отправляться.
Пример кода
Давайте рассмотрим пример кода, который демонстрирует правильное использование RegisterDeviceNotification для NFC-токенов.
uses
Windows, Messages, SysUtils, Classes, Forms, StdCtrls;
type
TMainF = class(TForm)
BRegisterDeviceNotification: TButton;
MOutput: TMemo;
procedure BRegisterDeviceNotificationClick(Sender: TObject);
procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainF: TMainF;
const
GUID_DEVINTERFACE_SCFILTER: TGUID = '{990a2bd7-e738-46c7-b26f-1cf8fb9f1391}';
procedure Register;
implementation
{$R *.dfm}
procedure TMainF.BRegisterDeviceNotificationClick(Sender: TObject);
var
x: DEV_BROADCAST_DEVICEINTERFACE;
begin
FillChar(x, SizeOf(x), 0);
x.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
x.dbcc_classguid := GUID_DEVINTERFACE_SCFILTER;
x.dbcc_size := SizeOf(x);
x.dbcc_name := 'SCFILTERCID_804f0ca00000030603000300000000'; // Убедитесь, что вы правильно указали Device Path
if not Assigned(RegisterDeviceNotification(Handle, @x, DEVICE_NOTIFY_WINDOW_HANDLE)) then
RaiseLastOSError;
end;
procedure TMainF.WMDeviceChange(var Msg: TMessage);
var
x: PDEV_BROADCAST_DEVICEINTERFACE;
begin
x := PDEV_BROADCAST_DEVICEINTERFACE(Msg.LParam);
case Msg.WParam of
DBT_DEVNODES_CHANGED: begin
MOutput.Lines.Add('Device changed: ' + FormatDateTime('yyyymmdd hh:nn:ss.zzz', Now));
MOutput.Lines.Add(GUIDToString(x.dbcc_classguid));
end;
DBT_DEVICEARRIVAL: begin
MOutput.Lines.Add('Device arrived: ' + FormatDateTime('yyyymmdd hh:nn:ss.zzz', Now));
MOutput.Lines.Add(GUIDToString(x.dbcc_classguid));
end;
DBT_DEVICEREMOVECOMPLETE: begin
MOutput.Lines.Add('Device removed: ' + FormatDateTime('yyyymmdd hh:nn:ss.zzz', Now));
MOutput.Lines.Add(GUIDToString(x.dbcc_classguid));
end;
end;
end;
initialization
Application.Initialize;
Application.CreateForm(TMainF, MainF);
Application.Run;
end.
Объяснение кода
GUID интерфейса: В примере используется GUID_DEVINTERFACE_SCFILTER, который соответствует NFC-токенам.
Device Path: Убедитесь, что вы правильно указали Device Path в поле dbcc_name. Это путь к интерфейсу устройства, который можно найти в свойствах устройства в Device Manager.
Обработка уведомлений: В обработчике WMDeviceChange мы проверяем тип события и добавляем соответствующее уведомление в TMemo.
Альтернативные решения
Если у вас нет пути устройства (Device Path), можно использовать CM_Register_Notification для регистрации уведомлений по Device Instance ID. Это более современный способ, который поддерживается начиная с Windows 8. Однако это требует более сложной настройки и работы с уведомлениями в отдельном потоке.
В данной статье мы рассмотрели, как правильно настроить уведомления для новых NFC-токенов в Delphi с использованием RegisterDeviceNotification. Мы обсудили, как определить правильный GUID интерфейса, тип устройства и обработку уведомлений. Также были предложены альтернативные решения для случаев, когда у вас нет пути устройства. Надеюсь, эта информация поможет вам успешно интегрировать уведомления об устройствах в ваши приложения на Delphi.
В статье рассматривается настройка уведомлений для новых NFC-токенов в Delphi с использованием функции `RegisterDeviceNotification`, включая определение GUID интерфейса устройства, обработку различных типов событий и альтернативные решения.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.