Solved

1. Process the tab key

Posted on 2001-06-06
21
234 Views
Last Modified: 2011-09-20
If anyone can give me a quick code example to capture and handle when the tab key is pressed on a form or control I would be most gratefull.

It doesn't register in onkeypress or onkeydown so no "if key = vk_tab then..." or "if key = chr(vk_tab) then..." from point hunters please.

As I don't ask many questions I'm lumping lots on this one as I need a quick response.

Thanks.

Nick
0
Comment
Question by:excalibur256
  • 5
  • 4
  • 4
  • +5
21 Comments
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
use the onKeyDown or onKeyUp instead
0
 
LVL 17

Expert Comment

by:inthe
Comment Utility
hi,
here is one example:
Regards Barry

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Edit1: TEdit;
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormCreate(Sender: TObject);
   private
    procedure TabKey( Var msg: TCMDialogKey );
     message CM_DIALOGKEY;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.TabKey(var msg: TCMDialogKey);
begin
  if msg.Charcode <> VK_TAB then
   inherited;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_TAB then
    showmessage('tab presed');
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
keypreview := true;
end;

end.
0
 
LVL 27

Accepted Solution

by:
kretzschmar earned 300 total points
Comment Utility
hum, sorry, wrong suggestion,

but this should do it

unit tab_key_u;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    Procedure TabKeyMessageHandler(var Msg: TMsg; var Handled: Boolean);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

Procedure TForm1.TabKeyMessageHandler(var Msg: TMsg; var Handled: Boolean);
begin
  If Msg.Message = WM_KeyDown then
    If Msg.wParam = vk_tab then
      Showmessage('Tabbed pressed');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := TabKeyMessageHandler;
end;

end.

meikl ;-)
0
 
LVL 17

Expert Comment

by:inthe
Comment Utility
note see keystrokes/runtime:

http://www.efg2.com/Lab/Library/Delphi/Miscellany/

for other ways for catching system keys (like the arrows ctrl/esc) etc.
0
 
LVL 11

Expert Comment

by:robert_marquardt
Comment Utility
Simply catch it in the Application.OnMessage event.
Sort out WM_KEYDOWN with VK_TAB. Suppress the message by setting Handled to true in the event.
0
 
LVL 17

Expert Comment

by:inthe
Comment Utility
ps,
to actually use/process the tab to jump to next control change my keydown procedure to this:


procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_TAB then begin
 showmessage('tab pressed so i jump to next windowed control');
SendMessage(handle,WM_NEXTDLGCTL,0,0);
end;
  end;

0
 
LVL 4

Expert Comment

by:DMN
Comment Utility
Hope this is best solution :) :

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure FormKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }
    procedure WMGETDLGCODE(var Message:TMessage); message WM_GETDLGCODE;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WMGETDLGCODE;
begin
  inherited;
  Message.Result := Message.Result or DLGC_WANTTAB;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  KeyPreview := True;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key=VK_TAB then
    begin
      Key := 0;
      Caption := 'Keydown ';
    end;
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if Key=#9 then
    begin
      Key := #0;
      Caption := Caption + 'Keypress ';
    end;
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key=VK_TAB then
    begin
      Key := 0;
      Caption := Caption + 'Keyup';
    end;
end;

end.
0
 
LVL 4

Expert Comment

by:DMN
Comment Utility
Or it's not... Depends on what you want :)
0
 
LVL 13

Expert Comment

by:Epsylon
Comment Utility
How about this one:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TForm1 = class(TForm)
    procedure CMDialogKey(var Msg: TWMKey); message CM_DIALOGKEY;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.CMDialogKey(var Msg: TWMKey);
begin
  case Msg.CharCode of
    VK_TAB:
      ShowMessage('You pressed my Tab key!');
  end;
end;

end.
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Heh... 300 points seem to be pretty attractive...   :-)
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 13

Expert Comment

by:Epsylon
Comment Utility
ehhh... don't touch them   :o)
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
puh, eps is about catching me :-)
0
 

Expert Comment

by:NikiNN
Comment Utility
Hi, Excalibur256
I try following and it's working:

unit tabkeyU;

interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
  private
    { Private declarations }
    procedure WMM(var Message: TMessage); message CN_KEYDOWN;
  public
    { Public declarations }
  end;

var  Form1: TForm1;

implementation
{$R *.DFM}

procedure TForm1.WMM(var Message: TMessage);
begin
  label1.caption:=inttostr(TWMKey(Message).CharCode);
end;

end.
0
 
LVL 17

Expert Comment

by:inthe
Comment Utility
good grief theres always one isnt there ...


NikiNN ,
the object is many people post comments and user selects most appropriate as answer.if you post as answer you are "locking" the q from others seeing it.

0
 

Expert Comment

by:NikiNN
Comment Utility
Hi, inthe

I am realy sorry. I am new in this comunity and i missed some things.
Thanks.
0
 
LVL 1

Author Comment

by:excalibur256
Comment Utility
Right, I have actually combined the aswers from inthe and kretzschmar to produce a hybrid as inthe's actual capture method was better but kretzschmar's method of handling was better, although I decided to store the old application onmessage in a tmessageevent and restore it afterwards.

Here's the relavant hybrid code for anyone interested.

The purpose being to allow users to tab through a TDBCtrlGrid as though it were part of the normal form.

//from form declarations
private
oldMsg : TMessageEvent;
procedure TabKey(var Msg: TMsg; var Handled: Boolean);

//from implementation
...

procedure TfrmX.FormCreate(Sender: TObject);
begin
oldhandler := application.OnMessage;
application.OnMessage := TabKey;
end;

procedure TfrmX.TabKey(var msg: TMsg; var Handled: Boolean);
begin
 If Msg.Message = WM_KeyDown then
   If (msg.wParam = vk_tab) and ((ActiveControl = MyDBCtrlGrid) or ((activecontrol = LastDBEditOnGrid)and(MyDBCtrlGrid.PanelIndex = MyDBCtrlGrid.PanelCount-1))) then
   begin
     Handled := True;
   if (activecontrol = MyDBCtrlGrid)(GetKeyState(vk_shift) >= 0) then
     MyDBCtrlGrid.DoKey(gkEditMode);
   if activecontrol = LastDBEditOnGrid then
     NextBtnOnMainForm.SetFocus;
   end else
     Handled := false;
end;

procedure TfrmBooking.FormDestroy(Sender: TObject);
begin
  application.OnMessage := oldHandler;
end;

I am giving the main points from this question to kretzschmar as inthe has such a stupidly high amount already. If inthe would like to post on my extra points question then he will be awarded those points.

Thanks everyone for you answers, I'm sure many if not all of them would have worked but as kretzschmar and inthe were first they get it.

Nick
0
 
LVL 1

Author Comment

by:excalibur256
Comment Utility
I do not appreciate someone locking up the question. Especially when so many people have aleady given working answers as comments. I appreciate that NikiNN actually states that it's working but I suspect most other people tested as well.
0
 
LVL 1

Author Comment

by:excalibur256
Comment Utility
The main reason for combining the two code samples was that inthe's produced a windows ding every time tab was pressed(and it only went one forward as it didn't include shift-key handling).
0
 
LVL 1

Author Comment

by:excalibur256
Comment Utility
inthe ... for the other 200 points I was offering (I don't normally need to ask questions and surfing around decreases productivity which is why I was giving away so many on here) the question title is

xtra pts 4 tabkey question

in case you want to search for it.
0
 
LVL 1

Author Comment

by:excalibur256
Comment Utility
remove "one" from 2 comments up ie "it only went forward"
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
wow, thanks :-))
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now