【问题标题】:Prevent TouchKeyboard from grabbing the focus防止 TouchKeyboard 抓住焦点
【发布时间】:2011-08-30 21:15:42
【问题描述】:

我用 Delphi 为平板电脑编写了一个小应用程序。所以没有键盘。应用程序中有一个小表单,用户可以在其中输入驱动程序名称。我想在表单上放一个 TouchKeyboard,但由于表单本身很小,无法容纳虚拟键盘。我可以使键盘的尺寸变小,但在这种情况下打字会很困难。因此,我决定编写另一个仅由键盘组成的应用程序。当主应用程序中的 DBEdit 获得焦点时,我想执行 Touchkeyboard 应用程序,而当 DBEdit 失去焦点时,关闭 Touchkeyboard 应用程序。我的问题之一是如何防止 Touchkeyboard 在启动时抓住焦点。另一个是我如何在主应用程序下方显示触控键盘。提前致谢。

【问题讨论】:

  • 嗨。我更新了我的答案,如果您只是复制程序,它应该可以正常工作。

标签: delphi keyboard focus virtual


【解决方案1】:

您不需要其他应用程序。只需创建另一种形式,这样您就可以更好地处理焦点和隐藏。我不确定你所说的“就在”你的应用程序是什么意思,但我想你的意思是窗口的位置应该在应用程序窗口的下方。看到这个sn-p:

有两种形式:MainForm 和 KeyboardForm。

unit MainFormUnit;
uses (...),KeyboardForm;

(...)
var KeybdShown: boolean = false;


procedure TMainForm.InputEditEnter(Sender: TObject); // OnEnter event
begin
  if not KeybdShown then begin
    KeybdShown:=true;
    KeyboardForm.Top:=Top+ClientHeight;
    KeyboardForm.Left:=Left;

    KeyboardForm.ShowKeyboard(InputEdit); //Shows the keyboard form and sends our edit as parameter
  end;
end;

procedure TMainForm.InputEditExit(Sender: TObject); // OnExit event
begin
  KeyboardForm.Hide;
  KeybdShown:=false;
end;

...

unit KeyboardFormUnit;
var FocusedControl: TObject;
implementation
uses MainFormUnit;

procedure TKeyboardForm.FormKeyPress(Sender: TObject; var Key: Char);
var VKRes: SmallInt;
    VK: byte;
    State: byte;
begin
  VKRes:=VkKeyScanEx(Key, GetKeyboardLayout(0)); // Gets Virtual key-code for the Key
  vk:=vkres; // The virtualkey is the lower-byte
  State:=VKRes shr 8; // The state is the upper-byte

  (FocusedControl as TEdit).SetFocus; // Sets focus to our edit
  if (State and 1)=1 then keybd_event(VK_SHIFT,0,0,0); //   These three procedures
  if (State and 2)=2 then keybd_event(VK_CONTROL,0,0,0); // send special keys(Ctrl,alt,shift)
  if (State and 4)=4 then keybd_event(VK_MENU,0,0,0); //    if pressed

  keybd_event(VK,0,0,0); // sending of the actual keyboard button
  keybd_event(VK,0,2,0);

  if (State and 1)=1 then keybd_event(VK_SHIFT,0,2,0);
  if (State and 2)=2 then keybd_event(VK_CONTROL,0,2,0);
  if (State and 4)=4 then keybd_event(VK_MENU,0,2,0);
  Key:=#0;
end;

procedure TKeyboardForm.ShowKeybd(Focused: TObject);
begin
  FocusedControl:=Focused;
  Show;
end;

这基本上就是您处理显示/隐藏表单所需的全部内容。由于 KeyboardForm 未在启动时显示,因此它不会获得焦点(除非 Edit 将 TabOrder 设置为 0 且 TabStop 为 true - 然后 OnEnter 事件在应用程序启动时触发)。

工作原理

  • 当您选择编辑时,会调用 ShowKeyboard 函数,并将编辑作为参数传递
  • 显示触摸键盘,每次单击都会触发 TKeyboardForm 的 OnKeyPress 事件(!!!将 KeyPreview 设置为 true)
  • 字符被解码为实际的键盘按钮(Shift、Alt、Control 和其他按钮的组合)
  • 这些解码的击键被发送到编辑

注意:可以使用 SendInput() 代替 keybd_event。

【讨论】:

  • 谢谢你,你真是太好了。我不敢相信我会这么愚蠢,想用两个不同的应用程序来做这件事。
  • 我按照你说的做了。当我输入 dbedit 时,表单出现,但是每当我点击键盘表单上的任何键时,键盘表单都会抓住焦点。我无法输入任何内容
  • 好的。我从来没有对这个组件做过任何事情,所以我不得不更多地研究它。我更新了代码(或者我将在几秒钟内更新),所以看看它。
【解决方案2】:

Responses对我提供的Delphi键盘的成功尝试可能感兴趣。

【讨论】:

    【解决方案3】:

    有关虚拟键盘设计的非常有趣的文章和讨论,请参阅http://www.virtual-keyboard-design.com

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      • 1970-01-01
      相关资源
      最近更新 更多