如何使 Enter 键在 Delphi FireMonkey 应用程序中充当选项卡?

And*_*dam 3 delphi tabs enter firemonkey

以前,在 Delphi VCL 应用程序中,很容易“覆盖”组件的 onkeyup 或 onkeydown 事件上的击键,以使 Enter 键充当 TAB 键。FireMonkey 应用程序的工作方式与 VCL 不同,那么现在应该如何执行此操作呢?

And*_*dam 5

感谢 @Uwe Raabe 提供的简单解决方案,我正在编辑我的答案以提供另一个解决方案。我将把所有内容都留在这里,因为这个答案暴露了 Firemonkey 中的一些“魔法”,而这些“魔法”通常并不明显。

我需要在表单的 FormShow 事件上动态创建“TAB”功能,以节省实施时间。我需要创建一个类来处理 TNotifyEvent (OnClick)。这是我的另一个解决方案,我现在已经成功测试过。请注意,下面的代码将尝试删除 Enter 上的“默认”按钮操作,以便其正常工作。

type  
  TClickObject = class(TObject)
  public
    Form: TForm;
    procedure MyTabOnClick(Sender: TObject);
  end;

{ ClickClass }

procedure TClickObject.MyTabOnClick(Sender: TObject);
var
  ch: Char;
  key: Word;
begin
  if Form = nil then Exit;
  key := vkTab;
  ch := #9;
  Form.KeyDown(key, ch, []);
end;

function CreateTabButton(Form: TForm): TButton;
var
  Count: Integer;
  ClickObject: TClickObject;

begin
  //Make the click object
  ClickObject := TClickObject.Create;
  ClickObject.Form := Form;

  //Make other buttons not default
  for Count := 0 to Form.ComponentCount-1 do
  begin
    if (Form.Components[Count] is TButton) then //Extend for other buttons ?
    begin
      (Form.Components[Count] as TButton).Default := False;
    end;
  end;

  //Make a button far off the screen
  Result := TButton.Create(Form);
  Result.Parent := Form;
  Result.Default := True;
  Result.OnClick := ClickObject.MyTabOnClick;
  Result.Text := 'TAB';
  Result.Position.X := -10000;
  Result.Position.Y := -10000;
end;

//Form OnShow Event, declare tabButton as TButton in your Form then you can use it on other components like combo boxes where you want to fire tab / enter event

tabButton :=  CreateTabButton(Self);
Run Code Online (Sandbox Code Playgroud)

例如,TComboBox 与 Button 解决方案的配合不太好,下面是使其工作的示例

procedure TForm1.CommboBox1KeyUp(Sender: TObject; var Key: Word;
  var KeyChar: Char; Shift: TShiftState);
begin
  if (Key = 13) then
  begin
    tabButton.OnClick(self); //tabButton declared in the Form an initialized with CreateTabButton
  end;
end;
Run Code Online (Sandbox Code Playgroud)

以下代码是可从全局库或 TDataModule 中使用的过程,为您提供 Enter to Tab 功能。我在输入上使用了 onkeyup 事件来测试它。

procedure HandleEnterAsTab(Form: TForm; Sender: TObject; Key: Word);
var
  TabList: ITabList;
  CurrentControl, NextControl: IControl;
begin
  if (Key = vkReturn) then
  begin
    TabList := Form.GetTabList;
    CurrentControl := TControl(Sender);
    NextControl := TabList.FindNextTabStop(CurrentControl, True, False);
    if (NextControl = nil) then  //go to first item if reached end
    begin
      NextControl := TabList.GetItem(0);
    end;
    
    NextControl.SetFocus;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

以下是其使用的示例片段

procedure TForm1.Edit2KeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
  Shift: TShiftState);
begin
  HandleEnterAsTab(Form1, Sender, Key);
end;
Run Code Online (Sandbox Code Playgroud)

显然,您可以根据您的需要更改过程以不同的方式工作,但是我尝试通过使用 TComponent 和 TForm 作为获取 TabList 的容器来使其尽可能通用。