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

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


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

猜你喜欢

转载自blog.csdn.net/pulledup/article/details/106766589