Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

1. Process the tab key

Posted on 2001-06-06
21
Medium Priority
?
257 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 1200 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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
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

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!

Question has a verified solution.

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

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…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
Suggested Courses

704 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