Delphi Clinic C++Builder Gate Training & Consultancy Delphi Notes Weblog Dr.Bob's Webshop
Bob Swart (aka Dr.Bob) - Medical Officer Delphi 6 Developer's Guide
 Dr.Bob's Tip-Of-The-Hat #2
See Also: Delphi Papers, Columns and other Tip-Of-The-Hats

Enter as TAB
Some of my applications have forms with many data-entry controls on them. And some of the users of these forms used to face the same problem: they were using the Enter key to move from one data-entry control to another (much like in the old DOS days). But now, inside this new Delphi for Windows application, the Enter key results on some computers in a loud Beep, and they needed to use the TAB key to move from one data-entry control to another, which proved to be counter-productive for these people. Of course, I could not expect every end-user to forget his or her old habits (I still have a few my own left), so the Tip-Of-The-Hat question was raised: How can I use the Enter key as TAB?

There are actually two solutions: one for specific controls, and one for all controls on a given form. The first solution is easiest, as we only need to modify the controls OnKeyPress event. If you have a TEdit component, for example, you need to write the following code in the OnKeyPress event handler:

  procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
  begin
    if Key = #13 then
      SelectNext(Sender AS TWinControl, True, True)
  end;
This code first checks to see if the Key that was entered was indeed the Enter key (#13), and then calls the SelectNext method of the Form, passing the current control (Sender AS TWinControl) as argument. The second argument is set to True and determines if we want to move forward or backwards. Say you want to use Ctrl-B (or #2) to go back to the previous control, then you can write the following code in your event handler:
  procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
  begin
    if Key = #13 then
      SelectNext(Sender AS TWinControl, True, True) // Forward
    else
      if Key = #2 then
        SelectNext(Sender AS TWinControl, False, True) // Backward
  end;
This causes the Enter key to behave like TAB (move forward) and Ctrl-B as Shift-TAB (move back). To use this event handler for more than one component, just select all controls on the form you'd like to exhibit this behavior (except for the Buttons who do not have a KeyPress event hanlder), go to the Object Inspector and set their OnKeyPress handler to EditKeyPress. Each control you selected will now process Enter as TAB.

If you'd like to handle this at the form (as opposed to control) level, first remove the previous OnKeyPress code, and set the Form's KeyPreview property to True. Next, write the following code for the OnKeyPress event handler of the entire Form:

  procedure TForm1.Form1KeyPress(Sender: TObject; var Key: Char);
  begin
    if Key = #13 then
      SelectNext(ActiveControl AS TWinControl, True, True) // Forward
    else
      if Key = #2 then
        SelectNext(ActiveControl AS TWinControl, False, True) // Backward
  end;
In Borland C++Builder you would have to enter the following code to get the same effect (and also set the KeyPreview property to true):
  void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key)
  {
    if (Key == 13)
      SelectNext(ActiveControl, true, true);
    else
      if (Key == 2)
        SelectNext(ActiveControl, false, true);
  }
This will cause each control on the form (that can) to process Enter as TAB (move forward) and Ctrl+B as Shift-TAB (move back).

Epilogue
Even after you've implemented the solution above to allow the Enter key to work as TAB, there may still be an unwanted problem left: the Beep! Although we respond to the Enter key by selecting the next control, the Beep is still heard on some computers. We must explicitly remove the #13 key value, and replace it with a dummy #0 character to make sure the Beep is eliminated. The source code for the Form's OnKeyPress event handler will thus have to be implemented as follows:

  procedure TForm1.Form1KeyPress(Sender: TObject; var Key: Char);
  begin
    if Key = #13 then
    begin
      Key := #0; // Eat the Beep
      SelectNext(ActiveControl AS TWinControl, True, True) // Forward
    end
    else
      if Key = #2 then
        SelectNext(ActiveControl AS TWinControl, False, True) // Backward
  end;
This will cause each control on the form (that can) to process Enter as TAB, without a Beep.


This webpage © 2001-2009 by Bob Swart (aka Dr.Bob - www.drbob42.com). All Rights Reserved.