Solved

1. Process the tab key

Posted on 2001-06-06
21
242 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
ID: 6159368
use the onKeyDown or onKeyUp instead
0
 
LVL 17

Expert Comment

by:inthe
ID: 6159395
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
ID: 6159404
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 17

Expert Comment

by:inthe
ID: 6159409
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
ID: 6159410
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
ID: 6159417
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
ID: 6159433
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
ID: 6159439
Or it's not... Depends on what you want :)
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 6159456
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
ID: 6159485
Heh... 300 points seem to be pretty attractive...   :-)
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 6159508
ehhh... don't touch them   :o)
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6159526
puh, eps is about catching me :-)
0
 

Expert Comment

by:NikiNN
ID: 6159750
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
ID: 6159773
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
ID: 6159861
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
ID: 6160004
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
ID: 6160022
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
ID: 6160042
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
ID: 6160054
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
ID: 6160064
remove "one" from 2 comments up ie "it only went forward"
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6160614
wow, thanks :-))
0

Featured Post

Secure Your Active Directory - April 20, 2017

Active Directory plays a critical role in your company’s IT infrastructure and keeping it secure in today’s hacker-infested world is a must.
Microsoft published 300+ pages of guidance, but who has the time, money, and resources to implement? Register now to find an easier way.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

749 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