1,183
社区成员
发帖
与我相关
我的任务
分享
unit Unit3;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Winapi.Networking.Proximity, Vcl.StdCtrls, Vcl.ComCtrls, Winapi.WinRT,
System.Win.ComObj, Winapi.Foundation.Types, Winapi.Storage.Streams,
Winapi.CommonTypes, System.Win.WinRT;
const
MsgTypes: array[0..4] of string = ('NDEF', 'Pairing:Bluetooth', 'WindowsUri',
'WindowsMime', 'WriteableTag');
type
TMessageReceivedHandler = class(TInterfacedObject, MessageReceivedHandler)
public
procedure Invoke(Sender: IProximityDevice; message: IProximityMessage); safecall;
end;
TDeviceArrivedEventHandler = class(TInterfacedObject, DeviceArrivedEventHandler)
public
procedure Invoke(Sender: IProximityDevice); safecall;
end;
TDeviceDepartedEventHandler = class(TInterfacedObject, DeviceDepartedEventHandler)
public
procedure Invoke(Sender: IProximityDevice); safecall;
end;
TForm3 = class(TForm)
rbOutput: TRichEdit;
btnInit: TButton;
btnQuit: TButton;
ComboBox1: TComboBox;
procedure btnInitClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btnQuitClick(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
Device: TProximityDevice;
NFCReader: IProximityDevice;
FDeviceArrivedHandler: DeviceArrivedEventHandler;
FDeviceDepartedHandler: DeviceDepartedEventHandler;
token: EventRegistrationToken;
FMsgHandler: TMessageReceivedHandler;
FMsgType: string;
public
{ Public declarations }
end;
procedure ReceiveMessage(Sender: IProximityDevice; message: IProximityMessage);
procedure myDeviceArrived(Sender: IProximityDevice);
procedure myDeviceDeparted(Sender: IProximityDevice);
function StringToHSTRING(Value: string): HSTRING;
function HSTRINGToString(Src: HSTRING): string;
procedure Log(Str: string);
var
Form3: TForm3;
implementation
{$R *.dfm}
procedure TForm3.btnInitClick(Sender: TObject);
var
MsgType: string;
h: HSTRING;
SubscribeID: Int64;
launchArgs, praid, appName, launchAppMessage: string;
begin
try
Device := TProximityDevice.Create;
Log('Device.GetDeviceSelector:' + IntToStr(Device.GetDeviceSelector));
NFCReader := Device.GetDefault;
if (not Assigned(NFCReader)) then
begin
FreeAndNil(NFCReader);
FreeAndNil(Device);
Log('no reader');
Exit;
end;
Log('Device.GetDefault.DeviceId:' + IntToStr(NFCReader.DeviceId));
MsgType := ComboBox1.Text;
h := StringToHSTRING(MsgType);
Log(Format('h:%s>>>%s', [MsgType, IntToStr(h)]));
FMsgHandler := TMessageReceivedHandler.Create;
SubscribeID := Form3.NFCReader.SubscribeForMessage(h, Form3.FMsgHandler);
Log('SubscribeForMessage-ID:' + IntToStr(SubscribeID));
FDeviceArrivedHandler := TDeviceArrivedEventHandler.Create;
token := NFCReader.add_DeviceArrived(FDeviceArrivedHandler);
Log('add_DeviceArrived-token' + IntToStr(token.Value));
FDeviceDepartedHandler := TDeviceDepartedEventHandler.Create;
token := NFCReader.add_DeviceDeparted(FDeviceDepartedHandler);
Log('add_DeviceDeparted-token' + IntToStr(token.Value));
except
on E: Exception do
begin
Log('error:' + E.ClassName + '///' + E.Message);
end;
end;
end;
procedure TForm3.btnQuitClick(Sender: TObject);
begin
FreeAndNil(FMsgHandler);
FreeAndNil(FDeviceArrivedHandler);
FreeAndNil(FDeviceDepartedHandler);
FreeAndNil(NFCReader);
FreeAndNil(Device);
end;
procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
btnQuitClick(nil);
inherited;
end;
procedure TForm3.FormShow(Sender: TObject);
var
I: Integer;
begin
inherited;
for I := 0 to Length(MsgTypes) - 1 do
begin
ComboBox1.Items.Add(MsgTypes[I]);
end;
end;
procedure myDeviceArrived(sender: IProximityDevice);
var
SubscribeID: Int64;
iidCount: Cardinal;
iids: PGUID;
ret: HRESULT;
begin
Log('myDeviceArrived-DeviceId:' + IntToStr(sender.DeviceId));
Log('myDeviceArrived-MaxMessageBytes:' + IntToStr(sender.MaxMessageBytes));
Log('myDeviceArrived-BitsPerSecond:' + UIntToStr(sender.BitsPerSecond));
ret := sender.GetIids(iidCount, iids);
//
Log('myDeviceArrived-iidCount:' + IntToStr(iidCount));
Log('myDeviceArrived-iids:' + GUIDToString(iids^));
Log('myDeviceArrived-ret:' + IntToStr(ret));
end;
procedure myDeviceDeparted(sender: IProximityDevice);
var
SubscribeID: Int64;
begin
Log('myDeviceArrived-DeviceId:' + IntToStr(sender.DeviceId));
Log('myDeviceArrived-MaxMessageBytes:' + IntToStr(sender.MaxMessageBytes));
Log('myDeviceArrived-BitsPerSecond:' + UIntToStr(sender.BitsPerSecond));
SubscribeID := sender.SubscribeForMessage(HSTRING(LongInt(@Form3.FMsgType)),
Form3.FMsgHandler);
Log('12-SubscribeID' + IntToStr(SubscribeID));
end;
{ TDeviceArrivedEventHandler }
procedure TDeviceArrivedEventHandler.Invoke(sender: IProximityDevice);
begin
myDeviceArrived(sender);
end;
procedure ReceiveMessage(sender: IProximityDevice; message: IProximityMessage);
var
str: string;
begin
str := Format('[%s]msg[%s]:%s', [IntToStr(sender.DeviceId), IntToStr(message.MessageType),
string(message.DataAsString)]);
Log(str);
end;
{ TMessageReceivedHandler }
procedure TMessageReceivedHandler.Invoke(sender: IProximityDevice; message:
IProximityMessage);
begin
Log('111');
ReceiveMessage(sender, message);
end;
{ TDeviceDepartedEventHandler }
procedure TDeviceDepartedEventHandler.Invoke(sender: IProximityDevice);
begin
myDeviceDeparted(sender);
end;
function StringToHSTRING(Value: string): HSTRING;
begin
if not Succeeded(WindowsCreateString(PWideChar(Value), Length(Value), Result)) then
raise Exception.CreateFmt('Unable to create HString for %s', [Value]);
end;
function HSTRINGToString(Src: HSTRING): string;
var
c: Cardinal;
begin
c := WindowsGetStringLen(Src);
Result := WindowsGetStringRawBuffer(Src, @c);
end;
procedure Log(str: string);
begin
Form3.rbOutput.Lines.Insert(0, str);
end;
end.
这是新改之后的代码
DeviceArrived和DeviceDeparted 刷卡进入和离开事件都能监听到 但是不知道怎么获取卡号
SubscribeForMessage设置成功了 但是刷卡没反应
测试结果是这样的:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Winapi.Networking.Proximity, Vcl.StdCtrls, Vcl.ComCtrls, Winapi.WinRT;
type
TMessageReceivedHandler = class(TInterfacedObject, MessageReceivedHandler)
public
procedure Invoke(sender: IProximityDevice; message: IProximityMessage); safecall;
end;
TForm1 = class(TForm)
Label1: TLabel;
cbReader: TComboBox;
rbOutput: TRichEdit;
btnInit: TButton;
btnConnect: TButton;
btnActive: TButton;
SendGroup: TGroupBox;
tbData: TMemo;
btnClear: TButton;
btnReset: TButton;
btnQuit: TButton;
procedure btnInitClick(sender: TObject);
procedure FormClose(sender: TObject; var Action: TCloseAction);
procedure btnQuitClick(sender: TObject);
procedure FormCreate(sender: TObject);
private
{ Private declarations }
Device: TProximityDevice;
NFCReader: IProximityDevice;
SubscribedMessageId: Int64;
MessageReceivedHandler: TMessageReceivedHandler;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btnInitClick(Sender: TObject);
var
h: HSTRING;
begin
try
Device := TProximityDevice.Create;
rbOutput.Lines.Add('Device.GetDeviceSelector:' + IntToStr(Device.GetDeviceSelector));
NFCReader := Device.GetDefault;
if (not Assigned(NFCReader)) then
begin
FreeAndNil(NFCReader);
FreeAndNil(Device);
rbOutput.Lines.Add('no reader');
Exit;
end;
rbOutput.Lines.Add('Device.GetDefault.DeviceId' + IntToStr(NFCReader.DeviceId));
// TODO: 这个HSTRING 为啥是数字的? 微软那边不是字符串么
// h := HSTRING(1);
rbOutput.Lines.Add('h>>>');
if (not Assigned(MessageReceivedHandler)) then
begin
MessageReceivedHandler := TMessageReceivedHandler.Create;
rbOutput.Lines.Add('MessageReceivedHandler.Create>>>');
end;
if (SubscribedMessageId = -1) then
begin
// TODO: 这行有问题 会报错
SubscribedMessageId := NFCReader.SubscribeForMessage(h, MessageReceivedHandler);
end;
rbOutput.Lines.Add('SubscribedMessageId:' + IntToStr(SubscribedMessageId));
except
on E: Exception do
begin
rbOutput.Lines.Add('error:' + E.ClassName + '///' + E.Message);
end;
end;
end;
procedure TForm1.btnQuitClick(Sender: TObject);
begin
rbOutput.Lines.Add('FreeAndNil(MessageReceivedHandler)');
try
FreeAndNil(MessageReceivedHandler);
except
on E: Exception do
begin
rbOutput.Lines.Add('error:' + E.ClassName + '///' + E.Message);
end;
end;
rbOutput.Lines.Add('FreeAndNil(NFCReader)');
try
FreeAndNil(NFCReader);
except
on E: Exception do
begin
rbOutput.Lines.Add('error:' + E.ClassName + '///' + E.Message);
end;
end;
rbOutput.Lines.Add('FreeAndNil(Device)');
try
FreeAndNil(Device);
except
on E: Exception do
begin
rbOutput.Lines.Add('error:' + E.ClassName + '///' + E.Message);
end;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
rbOutput.Lines.Add('FreeAndNil(MessageReceivedHandler)');
try
FreeAndNil(MessageReceivedHandler);
except
on E: Exception do
begin
rbOutput.Lines.Add('error:' + E.ClassName + '///' + E.Message);
end;
end;
rbOutput.Lines.Add('FreeAndNil(NFCReader)');
try
FreeAndNil(NFCReader);
except
on E: Exception do
begin
rbOutput.Lines.Add('error:' + E.ClassName + '///' + E.Message);
end;
end;
rbOutput.Lines.Add('FreeAndNil(Device)');
try
FreeAndNil(Device);
except
on E: Exception do
begin
rbOutput.Lines.Add('error:' + E.ClassName + '///' + E.Message);
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
inherited;
SubscribedMessageId := 1;
end;
{ TMessageReceivedHandler }
procedure TMessageReceivedHandler.Invoke(sender: IProximityDevice; message:
IProximityMessage);
begin
inherited;
Form1.rbOutput.Lines.Add('[' + IntToStr(sender.DeviceId) + ']msg:' + string(message.DataAsString));
end;
end.