delphi XE模拟Android手机PDA设备的虚拟键盘按键及扫码过程输入焦点及信号接收

今天,群里有几位同学讨论这个问题,汇总了一下,分享出来,供同学们学习研究。

一、直接上代码示例

1、屏蔽应用Terminated ;如果按了虚拟键:返回键; 如果按了物理菜单键

procedure TfmxTestGYListview1.FormKeyUp(
  Sender: TObject; var Key: Word;
  var KeyChar: Char; Shift: TShiftState);
var
  CanUse: Boolean;
begin
  if Key = vkHardwareBack then // 如果按了虚拟键:返回键
  begin
    Key := 0; //:屏蔽应用Terminated

// CanUse := true; Key := GoBack(CanUse); // 调用返回功能,包括退出功能
    Image_0201Click(Sender);
  end;
  if Key = vkMenu then // 如果按了物理菜单键
  begin
    if PopupMenu.Visible = true then
      HidePopupMenu
    else
      Image_0202Click(Sender); // 显示快捷菜单
    Key := 0;  //:屏蔽应用Terminated
    exit;
  end;
end;

2、控制TEdit和TMemo的虚拟键盘

二、取数原理

System.UITypes.pas 第197行-384行

const
  { Virtual Keys, Standard Set }
  vkLButton          = $01;  {   1 }
  vkRButton          = $02;  {   2 }
  vkCancel           = $03;  {   3 }
  vkMButton          = $04;  {   4 }
  vkXButton1         = $05;  {   5 }
  vkXButton2         = $06;  {   6 }
  vkBack             = $08;  {   8 }
  vkTab              = $09;  {   9 }
  vkLineFeed         = $0A;  {  10 }
  vkClear            = $0C;  {  12 }
  vkReturn           = $0D;  {  13 }
  vkShift            = $10;  {  16 }
  vkControl          = $11;  {  17 }
  vkMenu             = $12;  {  18 }
  vkPause            = $13;  {  19 }
  vkCapital          = $14;  {  20 }
  vkKana             = $15;  {  21 }
  vkHangul           = $15;  {  21 }
  vkJunja            = $17;  {  23 }
  vkFinal            = $18;  {  24 }
  vkHanja            = $19;  {  25 }
  vkKanji            = $19;  {  25 }
  vkConvert          = $1C;  {  28 }
  vkNonConvert       = $1D;  {  29 }
  vkAccept           = $1E;  {  30 }
  vkModeChange       = $1F;  {  31 }
  vkEscape           = $1B;  {  27 }
  vkSpace            = $20;  {  32 }
  vkPrior            = $21;  {  33 }
  vkNext             = $22;  {  34 }
  vkEnd              = $23;  {  35 }
  vkHome             = $24;  {  36 }
  vkLeft             = $25;  {  37 }
  vkUp               = $26;  {  38 }
  vkRight            = $27;  {  39 }
  vkDown             = $28;  {  40 }
  vkSelect           = $29;  {  41 }
  vkPrint            = $2A;  {  42 }
  vkExecute          = $2B;  {  43 }
  vkSnapshot         = $2C;  {  44 }
  vkInsert           = $2D;  {  45 }
  vkDelete           = $2E;  {  46 }
  vkHelp             = $2F;  {  47 }
  { vk0 thru vk9 are the same as ASCII '0' thru '9' ($30 - $39) }
  vk0                = $30;  {  48 }
  vk1                = $31;  {  49 }
  vk2                = $32;  {  50 }
  vk3                = $33;  {  51 }
  vk4                = $34;  {  52 }
  vk5                = $35;  {  53 }
  vk6                = $36;  {  54 }
  vk7                = $37;  {  55 }
  vk8                = $38;  {  56 }
  vk9                = $39;  {  57 }
  { vkA thru vkZ are the same as ASCII 'A' thru 'Z' ($41 - $5A) }
  vkA                = $41;  {  65 }
  vkB                = $42;  {  66 }
  vkC                = $43;  {  67 }
  vkD                = $44;  {  68 }
  vkE                = $45;  {  69 }
  vkF                = $46;  {  70 }
  vkG                = $47;  {  71 }
  vkH                = $48;  {  72 }
  vkI                = $49;  {  73 }
  vkJ                = $4A;  {  74 }
  vkK                = $4B;  {  75 }
  vkL                = $4C;  {  76 }
  vkM                = $4D;  {  77 }
  vkN                = $4E;  {  78 }
  vkO                = $4F;  {  79 }
  vkP                = $50;  {  80 }
  vkQ                = $51;  {  81 }
  vkR                = $52;  {  82 }
  vkS                = $53;  {  83 }
  vkT                = $54;  {  84 }
  vkU                = $55;  {  85 }
  vkV                = $56;  {  86 }
  vkW                = $57;  {  87 }
  vkX                = $58;  {  88 }
  vkY                = $59;  {  89 }
  vkZ                = $5A;  {  90 }
  vkLWin             = $5B;  {  91 }
  vkRWin             = $5C;  {  92 }
  vkApps             = $5D;  {  93 }
  vkSleep            = $5F;  {  95 }
  vkNumpad0          = $60;  {  96 }
  vkNumpad1          = $61;  {  97 }
  vkNumpad2          = $62;  {  98 }
  vkNumpad3          = $63;  {  99 }
  vkNumpad4          = $64;  { 100 }
  vkNumpad5          = $65;  { 101 }
  vkNumpad6          = $66;  { 102 }
  vkNumpad7          = $67;  { 103 }
  vkNumpad8          = $68;  { 104 }
  vkNumpad9          = $69;  { 105 }
  vkMultiply         = $6A;  { 106 }
  vkAdd              = $6B;  { 107 }
  vkSeparator        = $6C;  { 108 }
  vkSubtract         = $6D;  { 109 }
  vkDecimal          = $6E;  { 110 }
  vkDivide           = $6F;  { 111 }
  vkF1               = $70;  { 112 }
  vkF2               = $71;  { 113 }
  vkF3               = $72;  { 114 }
  vkF4               = $73;  { 115 }
  vkF5               = $74;  { 116 }
  vkF6               = $75;  { 117 }
  vkF7               = $76;  { 118 }
  vkF8               = $77;  { 119 }
  vkF9               = $78;  { 120 }
  vkF10              = $79;  { 121 }
  vkF11              = $7A;  { 122 }
  vkF12              = $7B;  { 123 }
  vkF13              = $7C;  { 124 }
  vkF14              = $7D;  { 125 }
  vkF15              = $7E;  { 126 }
  vkF16              = $7F;  { 127 }
  vkF17              = $80;  { 128 }
  vkF18              = $81;  { 129 }
  vkF19              = $82;  { 130 }
  vkF20              = $83;  { 131 }
  vkF21              = $84;  { 132 }
  vkF22              = $85;  { 133 }
  vkF23              = $86;  { 134 }
  vkF24              = $87;  { 135 }

vkCamera           = $88;  { 136 }
  vkHardwareBack     = $89;  { 137 }

vkNumLock          = $90;  { 144 }
  vkScroll           = $91;  { 145 }
  vkLShift           = $A0;  { 160 }
  vkRShift           = $A1;  { 161 }
  vkLControl         = $A2;  { 162 }
  vkRControl         = $A3;  { 163 }
  vkLMenu            = $A4;  { 164 }
  vkRMenu            = $A5;  { 165 }

vkBrowserBack      = $A6;  { 166 }
  vkBrowserForward   = $A7;  { 167 }
  vkBrowserRefresh   = $A8;  { 168 }
  vkBrowserStop      = $A9;  { 169 }
  vkBrowserSearch    = $AA;  { 170 }
  vkBrowserFavorites = $AB;  { 171 }
  vkBrowserHome      = $AC;  { 172 }
  vkVolumeMute       = $AD;  { 173 }
  vkVolumeDown       = $AE;  { 174 }
  vkVolumeUp         = $AF;  { 175 }
  vkMediaNextTrack   = $B0;  { 176 }
  vkMediaPrevTrack   = $B1;  { 177 }
  vkMediaStop        = $B2;  { 178 }
  vkMediaPlayPause   = $B3;  { 179 }
  vkLaunchMail       = $B4;  { 180 }
  vkLaunchMediaSelect= $B5;  { 181 }
  vkLaunchApp1       = $B6;  { 182 }
  vkLaunchApp2       = $B7;  { 183 }

vkSemicolon        = $BA;  { 186 }
  vkEqual            = $BB;  { 187 }
  vkComma            = $BC;  { 188 }
  vkMinus            = $BD;  { 189 }
  vkPeriod           = $BE;  { 190 }
  vkSlash            = $BF;  { 191 }
  vkTilde            = $C0;  { 192 }
  vkLeftBracket      = $DB;  { 219 }
  vkBackslash        = $DC;  { 220 }
  vkRightBracket     = $DD;  { 221 }
  vkQuote            = $DE;  { 222 }
  vkPara             = $DF;  { 223 }

vkOem102           = $E2;  { 226 }
  vkIcoHelp          = $E3;  { 227 }
  vkIco00            = $E4;  { 228 }
  vkProcessKey       = $E5;  { 229 }
  vkIcoClear         = $E6;  { 230 }
  vkPacket           = $E7;  { 231 }
  vkAttn             = $F6;  { 246 }
  vkCrsel            = $F7;  { 247 }
  vkExsel            = $F8;  { 248 }
  vkErEof            = $F9;  { 249 }
  vkPlay             = $FA;  { 250 }
  vkZoom             = $FB;  { 251 }
  vkNoname           = $FC;  { 252 }
  vkPA1              = $FD;  { 253 }
  vkOemClear         = $FE;  { 254 }
  vkNone             = $FF;  { 255 }

FMX.Types.pas 第568行~615行

TVirtualKeyboardType = (Default, NumbersAndPunctuation, NumberPad, PhonePad, Alphabet, URL, NamePhonePad,
    EmailAddress, DecimalNumberPad);

TVirtualKeyboardTypeHelper = record helper for TVirtualKeyboardType
  const
    vktDefault = TVirtualKeyboardType.Default deprecated 'Use TVirtualKeyboardType.Default';
    vktNumbersAndPunctuation = TVirtualKeyboardType.NumbersAndPunctuation deprecated 'Use TVirtualKeyboardType.NumbersAndPunctuation';
    vktNumberPad = TVirtualKeyboardType.NumberPad deprecated 'Use TVirtualKeyboardType.NumberPad';
    vktPhonePad = TVirtualKeyboardType.PhonePad deprecated 'Use TVirtualKeyboardType.PhonePad';
    vktAlphabet = TVirtualKeyboardType.Alphabet deprecated 'Use TVirtualKeyboardType.Alphabet';
    vktURL = TVirtualKeyboardType.URL deprecated 'Use TVirtualKeyboardType.URL';
    vktNamePhonePad = TVirtualKeyboardType.NamePhonePad deprecated 'Use TVirtualKeyboardType.NamePhonePad';
    vktEmailAddress = TVirtualKeyboardType.EmailAddress deprecated 'Use TVirtualKeyboardType.EmailAddress';
  end;

TVirtualKeyboardState = (AutoShow, Visible, Error, Transient);

TVirtualKeyboardStateHelper = record helper for TVirtualKeyboardState
  const
    vksAutoShow = TVirtualKeyboardState.AutoShow deprecated 'Use TVirtualKeyboardState.AutoShow';
    vksVisible = TVirtualKeyboardState.Visible deprecated 'Use TVirtualKeyboardState.Visible';
    vksError = TVirtualKeyboardState.Error deprecated 'Use TVirtualKeyboardState.Error';
    vksTransient = TVirtualKeyboardState.Transient deprecated 'Use TVirtualKeyboardState.Transient';
  end;

TVirtualKeyboardStates = set of TVirtualKeyboardState;

TReturnKeyType = (Default, Done, Go, Next, Search, Send);

TReturnKeyTypeHelper = record helper for TReturnKeyType
  const
    rktDefault = TReturnKeyType.Default deprecated 'Use TReturnKeyType.Default';
    rktDone = TReturnKeyType.Done deprecated 'Use TReturnKeyType.Done';
    rktGo = TReturnKeyType.Go deprecated 'Use TReturnKeyType.Go';
    rktNext = TReturnKeyType.Next deprecated 'Use TReturnKeyType.Next';
    rktSearch = TReturnKeyType.Search deprecated 'Use TReturnKeyType.Search';
    rktSend = TReturnKeyType.Send deprecated 'Use TReturnKeyType.Send';
  end;

IVirtualKeyboardControl = interface
    ['{41127080-97FC-4C30-A880-AB6CD351A6C4}']
    procedure SetKeyboardType(Value: TVirtualKeyboardType);
    function GetKeyboardType: TVirtualKeyboardType;
    property KeyboardType: TVirtualKeyboardType read GetKeyboardType write SetKeyboardType;
    //
    procedure SetReturnKeyType(Value: TReturnKeyType);
    function GetReturnKeyType: TReturnKeyType;
    property ReturnKeyType: TReturnKeyType read GetReturnKeyType write SetReturnKeyType;
    //
    function IsPassword: Boolean;
  end;

三、TEdit、TMemo等输入组件的焦点与虚拟键盘隐藏

1、

procedure TFormlogin_allinone_beijing.Image_0201Click(Sender: TObject);
begin
  if Assigned(self.Focused) then // 如果你的该页面有编辑控件,一定要加上这个,按返回键可以去掉键盘框
  begin
    if ((self.Focused.GetObject is TEdit) or (self.Focused.GetObject is TMemo)) then
    begin
      self.Focused := nil; // 退出键盘显示
      exit;
    end;
  end;

2、

procedure TForm_ship.EditShowEnter(Sender: TObject);
begin
  VKAutoShowMode := TVKAutoShowMode.Always; // 此窗口弹出输入法
  //VKAutoShowMode := TVKAutoShowMode.Never; // 此窗口不弹出输入法
end;

unit FMX.VirtualKeyboard.Android;

function TVirtualKeyboardAndroid.IsAutoShow: Boolean;
begin
  Result := VKAutoShowMode in [TVKAutoShowMode.Always, TVKAutoShowMode.DefinedBySystem];
end;

unit FMX.Types;

TVKAutoShowModeHelper = record helper for TVKAutoShowMode
  const
    vkasDefinedBySystem = TVKAutoShowMode.DefinedBySystem deprecated 'Use TVKAutoShowMode.DefinedBySystem';
    vkasNever = TVKAutoShowMode.Never deprecated 'Use TVKAutoShowMode.Never';
    vkasAlways = TVKAutoShowMode.Always deprecated 'Use TVKAutoShowMode.Always';
  end;

3、应用案例: PDA扫码

PDA接收扫码结果有两种方式,(1、焦点录入,就是要先点击一下输入框,让输入框处于焦点等待输入模式,扫码时就等同于键入录入后按回车键::::我的意见,这种模式下,不要去获取焦点、焦点等待、模拟回车键,直接:扫码完成后(要用到线程来负责扫码,扫码成功后直接同步UI赋值给TEdit)立即赋值给TEdit,TEdit(最好换位TText或TLabel等非输入组件)组件接收赋值的OnChange事件,翻译并显示出条码等后续处理。
(2、广播模式,不需要点击输入框,无焦点状态下由APP负责侦听扫描结果并处理。相当于 Android下的一个 TNotification服务。

其实呢,无论 焦点模式也好、广播推送通知模式也好,其背后的本质还是线程及线程的同步问题,如果熟悉 线程及线程的同步问题,事件及其事件通知,就变得简单啦。扫码及其通知的过程:进入匿名线程,扫码开始,扫码成功后:线程同步UI通知接收组件的OnChange事件显示条码,条码显示的接收组件OnChange等等事件被触发有怎样怎样.......

四、关联

1、        delphi系统键盘输入捕获或手势捕获  https://blog.csdn.net/pulledup/article/details/104374215

喜欢的话,就在下面点个赞、收藏就好了,方便看下次的分享:

delphi XE模拟Android手机PDA设备的虚拟键盘按键及扫码过程输入焦点及信号接收相关推荐

  1. android 导航 美国,变美了 Android N或用全新虚拟导航按键

    原标题:变美了 Android N或用全新虚拟导航按键 变美了 Android N或用全新虚拟导航按键 [IT168 资讯]虽然距离谷歌Android N系统的发布已经有一段时间了,不过该系统目前仍旧 ...

  2. 我把3个镜头手机拍的照片发微信群,哥们说,现在手机摄像头越来越多,我有一个扫码就够了...

    为了测试一加8的超广角摄影效果,我在深圳福田区拍了一张图 我哥们看到这张图,感叹手机镜头畸变的同时,又讲出了无数普通手机用户的心声: 现在手机摄像头越来越多,我有一个扫码就够了 手机为什么会有越来越多 ...

  3. C++模拟游戏中鼠标点击和键盘按键

    游戏中模拟键盘输入,有时回被系统屏蔽,Java等语言都试过很多方法,好像都没用,所以下面给出一种C++实现方法 #include <iostream> #include <windo ...

  4. 使用Java自动化方法模拟Android手机点击、触屏事件

    最近有一个测试需求,需要重复性的滑动手机.对手机进行触摸.点击操作等,所以就需要实现一个Android模拟人工操作的功能.一开始想写一个APK,但在实现过程中遇上了麻烦,好像需要系统应用权限等,笔者本 ...

  5. 手机屏幕纸java_使用Java自动化方法模拟Android手机点击、触屏事件

    最近有一个测试需求,需要重复性的滑动手机.对手机进行触摸.点击操作等,所以就需要实现一个Android模拟人工操作的功能.一开始想写一个APK,但在实现过程中遇上了麻烦,好像需要系统应用权限等,笔者本 ...

  6. html5手机底部输入框,html5 虚拟键盘弹出挡住底部的输入框解决方案

    问题描述: 我们使用 h5 做移动网站开发时,如果文本框在页面的下方,当输入信息弹出的软键盘会将输入框挡住(Android 会有这个问题,IOS会自动将整个页面上移),IOS中软键盘关闭后,页面上移的 ...

  7. 自动化方法模拟Android手机点击、触屏事件

    使用apk来自动化测试,需要手机有root权限,所以采用写java程序,利用adb shell来实现自动化测试. 一.所需知识 最基础的adb shell 指令.input tab 等. 二.所需环境 ...

  8. android手机查看设备ID,deviceID

    在手机拨号盘上敲下面的号 *#06# 太阳系 - http://blog.csdn.net/fellting

  9. 按键android手机排行榜,【直板全键盘手机推荐】直板键盘手机排行榜

    <[直板全键盘手机推荐]直板键盘手机排行榜>由会员分享,可在线阅读,更多相关<[直板全键盘手机推荐]直板键盘手机排行榜(7页珍藏版)>请在人人文库网上搜索. 1.直板全键盘手机 ...

最新文章

  1. ASP.NET Core 新核心对象WebHost(一)
  2. servlet post 返回值是一个对象_Servlet第二天
  3. 实验1 最小生成树问题【Kruskal+Prim】
  4. Linux进程全解5——父子进程对文件的操作
  5. php 隐藏图片地址
  6. 【Python】表白程序
  7. 国庆佳节,我们有好礼相送!
  8. 欺骗神经网络_可以欺骗神经网络吗?
  9. i7 8750h支持linux,6核神U!i7-8750H游戏本评测:碾压7代
  10. python开机自启切换每日必应壁纸
  11. 2016计算机课程设计,2016年ps课程设计心得体会范文
  12. 【Mac OS】如何快速复制文件或文件夹路径
  13. 应用在汽车倒车影像中的环境光传感芯片
  14. Codeforces Round #552 (Div. 3) E stl模拟 F dp G gcd
  15. 还在为网速烦恼?你可能没有使用华为云CDN加速服务
  16. 药品查询开发接口正式发布
  17. 剑指offer笔记(七) 第47题至第53题
  18. [前端bug词典]Already included file name ‘文件路径‘
  19. “Big O”符号的简单英文解释是什么?
  20. 2022年化工自动化控制仪表考试总结及化工自动化控制仪表证考试

热门文章

  1. 史上最全Xshell and Xftp 工具的使用
  2. 最新新农村别墅自建房CAD设计施工图纸+2000套
  3. java什么是双亲委派,为什么它可以保证安全?
  4. 【参数不确定】敏感性分析(sensitivity analysis)
  5. 考研备考教学视频分享
  6. 优秀的程序员文章积累
  7. Linux wine 字体发虚,解决QQ(wine)因字体卡死宋体发虚太难看的一种方法
  8. Jeff Dean的激荡人生:我和Sanjay在同一台电脑上写代码
  9. 微耕门禁、Monitor监控等设备的二次开发
  10. 高端课后晚托品牌“文启优思”获数千万A+轮融资,源道投资、高思教育、柏宏锐尔合投...