In my TEdit field I have text in the form
.
My idea is:
When a user enters the control using TAB from
Oh and in a Key Press event you can set the Key to 0
EDIT The following is a call stack capturing a KeyDown event for a TAB key
Form1.TForm1.GetTab((45061, 9, 0, 983041, 0))
:0101f444 TForm1.GetTab
:004dca20 TWinControl.WndProc + $500
:004ef754 TCustomForm.WndProc + $558
:004d86b3 TControl.Perform + $27
:004ded6a TWinControl.CNKeyDown + $D6
:004dca20 TWinControl.WndProc + $500
:004dc147 TWinControl.MainWndProc + $2F
:004306ea StdWndProc + $16
:7e418734 USER32.GetDC + 0x6d
:7e418816 ; C:\WINDOWS\system32\USER32.dll
:7e41b4c0 ; C:\WINDOWS\system32\USER32.dll
:7e41b50c ; C:\WINDOWS\system32\USER32.dll
:7c90eae3 ntdll.KiUserCallbackDispatcher + 0x13
:7e42f3cc USER32.SendMessageA + 0x49
As you can see it doesn go through KeyDown as normal keys do but instead calls BroadCast
to send the message out....
So you'll need a message catcher
Procedure GetTab( var Message: TCMDialogkey ); message CM_DIALOGKEY;
to catch it.
You might want to look at TJvIPAddress in JvComCtrls. I guess searching for TabThroughFields and VK_TAB should put you on track.
You are better to write your own TEdit descendant that processes WM_GETDLGCODE message. The general idea is:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TMyEdit = class(TEdit)
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
end;
type
TForm1 = class(TForm)
Edit2: TEdit;
procedure FormCreate(Sender: TObject);
procedure FormKeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
FMyEdit: TMyEdit;
FDone: Boolean;
procedure MyEditEnter(Sender: TObject);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TMyEdit }
procedure TMyEdit.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
inherited;
Message.Result:= Message.Result or DLGC_WANTTAB;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FMyEdit:= TMyEdit.Create(Self);
FMyEdit.Left:= 40;
FMyEdit.Top:= 40;
FMyEdit.Parent:= Self;
FMyEdit.Text:= '45..90';
FMyEdit.OnEnter:= MyEditEnter;
KeyPreview:= True;
end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if (Key = #9) and (ActiveControl = FMyEdit) then begin
if FDone then begin
Perform(CM_DialogKey, VK_TAB, 0);
end
else begin
FMyEdit.SelStart:= 4;
FMyEdit.SelLength:= 2;
end;
FDone:= not FDone;
Key:= #0;
end;
end;
procedure TForm1.MyEditEnter(Sender: TObject);
begin
FDone:= False;
FMyEdit.SelStart:= 0;
FMyEdit.SelLength:= 2;
end;
end.
Updated: The same idea without making a TEdit descendant class:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
procedure Edit2Enter(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormKeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
FDone: Boolean;
FOldWndProc: TWndMethod;
procedure Edit2WindowProc(var Message: TMessage);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Edit2Enter(Sender: TObject);
begin
FDone:= False;
Edit2.SelStart:= 0;
Edit2.SelLength:= 2;
end;
procedure TForm1.Edit2WindowProc(var Message: TMessage);
begin
if Message.Msg = WM_GETDLGCODE then
Message.Result:= Message.Result or DLGC_WANTTAB
else
if Assigned(FOldWndProc) then FOldWndProc(Message);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
KeyPreview:= True;
Edit2.Text:= '45..90';
FOldWndProc:= Edit2.WindowProc;
Edit2.WindowProc:= Edit2WindowProc;
end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if (Key = #9) and (ActiveControl = Edit2) then begin
if FDone then begin
Perform(CM_DialogKey, VK_TAB, 0);
end
else begin
Edit2.SelStart:= 4;
Edit2.SelLength:= 2;
end;
FDone:= not FDone;
Key:= #0;
end;
end;
end.