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

发布于 2025-01-13 19:29:37 字数 131 浏览 1 评论 0原文

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

Previously in Delphi VCL applications it was easy to "over ride" the key strokes on either the onkeyup or onkeydown events of components to make the Enter key behave as a TAB key. FireMonkey applications work differently from VCL, so how should one do this now?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忆梦 2025-01-20 19:29:37

感谢 @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);

例如,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;

以下代码是一个过程,可以从全局库或 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;

下面是它的使用示例片段

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

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

I'm editing my answer to provide another solution thanks to the simple solution provided by @Uwe Raabe. I'm leaving everything here as this answer exposes some of the "magic" in Firemonkey which often isn't obvious.

I needed to create the "TAB" functionality dynamically on FormShow event of a Form to save myself time on implementation. I needed to make a class to handle the TNotifyEvent (OnClick). Here is my other solution which I have tested now with success. Please note the code below will attempt to remove "Default" button action on Enter so it works.

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);

The TComboBox for example does does not place nice with the Button solution, here is an example of making it work

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;

The following code is a procedure which can be used from a global library or TDataModule to provide you with the Enter to Tab functionality. I used the onkeyup events on inputs to test it.

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;

The following is an example snippet of it's use

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

Obviously you could change the procedure to work differently according to your needs however I have tried to make it as generic as possible by using TComponent and TForm as the container for getting the TabList.

陌上芳菲 2025-01-20 19:29:37

正如我在评论中已经提到的,另一种方法是在表单上放置一个 TButton ,设置 TabStop = FalseDefault = True。使其变小并将其隐藏在另一个控件下。

在按钮的 OnClick 事件中执行以下代码:

var
  ch: Char;
  key: Word;
begin
  key := vkTab;
  ch := #9;
  KeyDown(key, ch, []);
end;

请注意,具有焦点的任何其他按钮都优先于该按钮,因此保留了预期的行为。

As I already mentioned in a comment, another way is to drop a TButton on the form, set TabStop = False and Default = True. The make it small and hide it under another control.

In the OnClick event of the button execute the following code:

var
  ch: Char;
  key: Word;
begin
  key := vkTab;
  ch := #9;
  KeyDown(key, ch, []);
end;

Note that any other button having focus takes precedence over this, so the expected behavior is preserved.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文