读取NFC标签内的网址并打开网页

本示例适配的读卡器:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.52de2c1bOBKs2M&ft=t&id=615391857885

检测读卡器上的NFC标签类型

Delphi 复制代码
Function checkcardtype:integer;   //检测NFC标签类型
var
  status:byte;//存放返回值
  mypiccserial:array[0..7] of byte;//卡序列号
  mypiccseriallen:array[0..1] of byte;
  mypicckey:array[0..5] of byte;  //认证密码
  mypicdata:array[0..47] of byte;  //块内数据
  myctrlword,blockaddr,blocksize:byte;  //控制字,读操作起始块地址,读写块数
  pdevicenumber:array[0..3] of byte;
  i:integer;
begin
  Result:=-1;
  myctrlword:=0;
  status:=pcdgetdevicenumber(@pdevicenumber);
  if status=0 then
  begin
      status := piccreadex_ntag(myctrlword,@mypiccserial,@mypicckey,4,1,@mypicdata); //forumtype2 Ntag2标签
      if status=0 then
          Result:=1
      else
      begin
           status := iso15693readex(myctrlword,0,1,1,@mypiccserial,@mypicdata);//forumtype5 15693标签
           if status=0 then
               Result:=2
           else
           begin
                myctrlword:=23;
                mypicckey[0]:=$FF;mypicckey[1]:=$FF;mypicckey[2]:=$FF;mypicckey[3]:=$FF;mypicckey[4]:=$FF;mypicckey[5]:=$FF;
                status := piccreadex(myctrlword,@mypiccserial,0,1,@mypicckey,@mypicdata); //MifareClassic,以出厂状态密码一认证
                if status=0 then
                    Result:=3
                else
                begin
                    myctrlword:=23;
                    mypicckey[0]:=$A0;mypicckey[1]:=$A1;mypicckey[2]:=$A2;mypicckey[3]:=$A3;mypicckey[4]:=$A4;mypicckey[5]:=$A5;
                    status := piccreadex(myctrlword,@mypiccserial,0,1,@mypicckey,@mypicdata); //MifareClassic ,以出厂状态密码二认证
                    if status=0 then
                        Result:=3
                    else
                    begin
                        myctrlword:=0;
                        status := forumtype4request(myctrlword, @mypiccserial, @mypiccseriallen); //forumtype4 标签
                        if (status=0) or (status=52) then
                            Result:=4
                        else
                        begin
                            Result:=-1;
                        end;
                    end;
                end;
           end;
      end;
   end
   else
      Result:=23;
end;

读取不同类型的标签内NDEF信息,解析获取网址及文本

Delphi 复制代码
function ReadTag(funcname: string):string;   //读取不同类型标签的NDEF信息
var
  cardtyep:integer;
  status:byte;
  afi:byte;
  myctrlword:byte;
  revstrlen: Integer;
  recordnumber: Integer;
  mypiccserial:array[0..7] of byte;
  mypiccseriallen:array[0..0] of byte;
  oldpicckey:array[0..5] of byte;
  newpicckey:array[0..5] of byte;
  mypiccdata: array[0..2048] of Byte;
  ndefstr:string;
  dispinf:string;
  cardno:string;
  uristr:string;
  i:integer;
  uribegin:Integer;
begin
     status:=255;

     cardtyep:=checkcardtype;//判断发卡器上标签类型

     case  cardtyep of
          1:
          begin //读forumtype2 Ntag2标签
              myctrlword:=0;
              status := forumtype2_read_ndeftag(myctrlword, @mypiccserial, @oldpicckey);
          end;
          2:
          begin  //读forumtype5 15693标签
              myctrlword:=0;
              afi:=0;
              status := forumtype5_read_ndeftag(myctrlword, afi, @mypiccserial);
          end;
          3:
          begin  //读MifareClassic标签
              myctrlword:=$80+$10;
              status:= piccread_ndeftag(myctrlword, @mypiccserial, @oldpicckey);
          end;
          4:
          begin  //读forumtype4 标签
              myctrlword:=0;
              status := forumtype4_read_ndeftag(myctrlword, @mypiccserial,@mypiccseriallen, @oldpicckey);
          end;
          else
              Result:=''; // funcname+',ReturnCode:008';
     end;

     if status=0 then
     begin
          tagbuf_read(@mypiccdata, @revstrlen, @recordnumber);
          ndefstr:='';
          for i:=0 to revstrlen-1 do  ndefstr:=ndefstr+chr(mypiccdata[i]);
          uribegin:=Pos('URI field:',ndefstr);
          if uribegin>0 then
          begin
              Result:='';
              for i:=uribegin+9 to revstrlen-1 do
              begin
                   if (mypiccdata[i]=13) and (mypiccdata[i+1]=10 ) then
                   begin
                       ReadTextOrURI:=2;
                       Exit;
                   end
                   else
                       Result:=Result+chr(mypiccdata[i]);
              end;
          end
          else
          begin
              uribegin:=Pos('text:',ndefstr);
              if uribegin>0 then
              begin
                  Result:='';
                  for i:=uribegin+5 to revstrlen-1 do
                  begin
                       if (mypiccdata[i+1]=13) and (mypiccdata[i+2]=10 ) then
                       begin
                           ReadTextOrURI:=1;
                           Exit;
                       end
                       else
                           Result:=Result+chr(mypiccdata[i]);
                  end;
              end;
          end;
     end;
end;

将读取到的网址及文本输出,如果是网址使用默认浏览器打开该网址

Delphi 复制代码
procedure TForm1.tmr1Timer(Sender: TObject);
var
    status:byte;//存放返回值
    myareano:byte;//区号
    authmode:byte;//密码类型,用A密码或B密码
    myctrlword:byte;//控制字
	  mypicckey:array[0..5] of byte;//密码
    mypiccserial:array[0..3] of byte;//卡序列号
    mypiccdata:array[0..47] of byte;//卡数据缓冲
    strls:string;
    i:Integer ;
    cardnumber:Longword;
begin
    try

        if Reading= True then
        begin
            ReadTextOrURI:=0;
            tagbuf_forumtype4_clear();            //清空NDEF数据缓冲
            tagbuf_clear();
            strls:=ReadTag('');

            if Length(strls)>0 then
            begin
                picchalt;

                if CheckBox1.Checked =True then
                begin
                   pcdbeep(12);
                end;
                if ((ReadTextOrURI=1) or (CheckBox4.Checked =True))  then  SendKeys(strls);  //模拟键盘输出网址
                if ((ReadTextOrURI=2) and (CheckBox2.Checked =True)) then ShellExecute(Handle, nil, PChar(strls), nil, nil, SW_SHOWNORMAL);  //系统默认浏览器打开网页

                tmr1.Interval :=strtoint(Edit1.Text);
            end
            else
                tmr1.Interval :=100;
        end;
      finally

      end;
end;

模拟键盘输出字符串信息

Delphi 复制代码
procedure SendKeys(sSend:string);
var
    i:integer;
    focushld,windowhld:hwnd;
    threadld:dword;
    ch: byte;
begin
  windowhld:=GetForegroundWindow;           //获得前台应用程序的活动窗口的句柄

  threadld:=GetWindowThreadProcessId(Windowhld,nil);        //获取与指定窗口关联在一起的一个进程和线程标识符

  AttachThreadInput(GetCurrentThreadId,threadld,true);
    //通常,系统内的每个线程都有自己的输入队列。          //
    //AttachThreadInput允许线程和进程共享输入队列。        //
    //连接了线程后,输入焦点、窗口激活、鼠标捕获、键盘状态 //
    //以及输入队列状态都会进入共享状态          //
  Focushld:=getfocus;
    //获得拥有输入焦点的窗口的句柄
  AttachThreadInput(GetCurrentThreadId,threadld,false );
  if focushld = 0 then Exit;
    //如果没有输入焦点则退出发送过程
  i := 1;
  while i <= Length(sSend) do
    //该过程发送指定字符串(中英文皆可以)
  begin  
    ch := byte(sSend[ i ]);
    if Windows.IsDBCSLeadByte(ch) then
    begin
      Inc(i);
      SendMessage(focushld, WM_IME_CHAR, MakeWord(byte(sSend[ i ]), ch), 0);
      //Sleep(1);
    end
    else
      SendMessage(focushld, WM_IME_CHAR, word(ch), 0);
      Inc(i);
    //  Sleep(1);
  end;
  postmessage(focushld,WM_keydown,13,0);  
    //发送一个虚拟Enter按键
end;
相关推荐
FliPPeDround3 天前
浏览器扩展 E2E 测试的救星:vitest-environment-web-ext 让你告别繁琐配置
e2e·浏览器·测试
SuperEugene3 天前
浏览器存储:localStorage / sessionStorage / cookie 应该怎么用
前端·javascript·面试·浏览器
宁雨桥3 天前
浏览器渲染原理
前端·浏览器·原理
YZ0995 天前
2026年如何批量保存小红书作者主页的视频、图片和文案?
经验分享·浏览器·插件
程序员ys5 天前
网页白屏的原理与优化
前端·性能优化·浏览器
huohaiyu5 天前
从URL到页面的完整解析流程
前端·网络·chrome·url
Wect7 天前
从输入URL到页面显示的完整技术流程
前端·面试·浏览器
NEXT067 天前
从输入 URL 到页面展示的完整链路解析
网络协议·面试·浏览器
CappuccinoRose10 天前
CSS 语法学习文档(十五)
前端·学习·重构·渲染·浏览器
REDcker11 天前
Media Source Extensions (MSE) 详解
前端·网络·chrome·浏览器·web·js