Delphi FMX 编辑控件不一致 - 如何制作快速输入表单?

Delphi FMX edit controls inconsistencies - How to make a fast-entry form?

我编写了一个 Delphi FMX 表单,用于在 Android 应用程序上输入数据。这由几个垂直排列并与水平中心对齐的控件组成。这些控件也都放置在 TVertScrollBox 上,因此可以将控件滚动到(和离开)视图。有几个 TEdits、2 个 TCombobox 和 1 个 TComboEdit。我还在我的表单中添加了以下代码

procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word;
  var KeyChar: Char; Shift: TShiftState);
begin
  if Key = vkReturn then
  begin
    Key := vkTab;
    KeyDown(Key, KeyChar, Shift);
  end;
end;

现在这对 TEdit 控件非常有用,因为用户可以使用回车键(通常我将 TEdit.ReturnKeyType 属性 设置为 Next)来导航控件列表,输入数据每个并按回车键将焦点移动到下一个。

这里有2个问题。

  1. 只要控件是TCombobox,虚拟键盘就会消失。换句话说,TCombobox 上没有 .keyboardtype.ReturnKeyType 属性。因此,在从下拉列表中 select 为组合框输入一个条目后,他们必须手动 "reach in" 和 select 下一个控件。他们经常错过。

  2. TEditCombo 确实是一个奇怪的后代。它有 .Keyboardtype 属性,但没有 .ReturnKeyType 属性。这让我的用户非常困惑,因为尽管他们可以在此组合框中键入内容,但当此控件像在 TEdits 上那样获得焦点时,return 键不会说 "Next"。

如何使此窗体上的所有控件都显示键盘并让 "return key" 移动到下一个控件,而不考虑当前控件或下一个控件的类型?

我是否有幸使用 VCL 编写了 Windows 应用程序?

在组合框和 TComboEdits 上,添加以下事件处理程序:

procedure TForm1.ComboBox1CanFocus(Sender: TObject; var ACanFocus: Boolean);
begin
  Combobox1.DropDown;
end;

procedure TForm1.ComboBox1Exit(Sender: TObject);
var
  keyboard: IFMXVirtualKeyboardService;
begin
  keyboard := TPlatformServices.Current.GetPlatformService(IFMXVirtualKeyboardService) as IFMXVirtualKeyboardService;
  if keyboard.HideVirtualKeyboard then
    Label1.text := 'hidden';
end;

procedure TForm1.ComboBox1KeyDown(Sender: TObject; var Key: Word;
  var KeyChar: Char; Shift: TShiftState);
begin
  label1.Text := IntToStr(Key);
  if Key = vkReturn then
  begin
    Key := vkTab;
    KeyDown(Key, KeyChar, Shift);
  end;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char;
  Shift: TShiftState);
begin
  label1.Text := IntToStr(Key);
  if Key = vkReturn then
  begin
    Key := vkTab;
    KeyDown(Key, KeyChar, Shift);
  end;
end;

procedure TForm1.ComboBox1ClosePopup(Sender: TObject);
var
  keyboard: IFMXVirtualKeyboardService;
  MS: TmessageSender;
begin
  keyboard := TPlatformServices.Current.GetPlatformService(IFMXVirtualKeyboardService) as IFMXVirtualKeyboardService;
  if keyboard.showVirtualKeyboard(ComboBox1) then
    Label1.Text := 'Shown';
  MS := tmessageSender.Create;
  try
    Ms.SendMessage<TReturnKeyType>(MM_EDIT_RETURNKEYTYPE_CHANGED, TReturnKeyType.Next);
  finally
    MS.Free;
  end;
end;

它是这样工作的:

当组合框获得焦点时,它会立即下降。

用户从下拉列表中选择一个项目后,立即显示键盘,并且 return 键显示更改为 "Next"。

组合框的 keydown 事件处理程序似乎拦截了 return 键,因为 FMX 表单中没有 .keypreview 属性,所以它有自己的事件处理程序 "change" 将 return 键转换为 Tab 键,以便下一个控件(按 Tab 键顺序)获得焦点。

当组合框退出时,键盘被隐藏。

我抄袭了 FMX.Edit.pas 单元的 SendMessage 代码。好像还行。