1. Process the tab key

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
LVL 1
excalibur256Asked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
kretzschmarConnect With a Mentor Commented:
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
 
kretzschmarCommented:
use the onKeyDown or onKeyUp instead
0
 
intheCommented:
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
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
intheCommented:
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
 
robert_marquardtCommented:
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
 
intheCommented:
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
 
DMNCommented:
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
 
DMNCommented:
Or it's not... Depends on what you want :)
0
 
EpsylonCommented:
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
 
MadshiCommented:
Heh... 300 points seem to be pretty attractive...   :-)
0
 
EpsylonCommented:
ehhh... don't touch them   :o)
0
 
kretzschmarCommented:
puh, eps is about catching me :-)
0
 
NikiNNCommented:
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
 
intheCommented:
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
 
NikiNNCommented:
Hi, inthe

I am realy sorry. I am new in this comunity and i missed some things.
Thanks.
0
 
excalibur256Author Commented:
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
 
excalibur256Author Commented:
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
 
excalibur256Author Commented:
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
 
excalibur256Author Commented:
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
 
excalibur256Author Commented:
remove "one" from 2 comments up ie "it only went forward"
0
 
kretzschmarCommented:
wow, thanks :-))
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.