'How do I make Enter key behave as a tab in a Delphi FireMonkey Application?
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?
Solution 1:[1]
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.
Solution 2:[2]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Uwe Raabe |
