2967:Validating input in TEdit components
KEYWORDS: validate edit tedit text onexit edit AREA: VCL Programming
Q: How can I validate input in my TEdit components?
A: Assuming you're using regular TEdit components,
during OnExit, you will see irregular behavior from
controls if you attempt to change focus at that time.
The solution is to post a message to your form in the TEdit's
OnExit event handler. This user-defined posted message will
indicate that the coast is clear to begin validating input.
Since posted messages are placed at the end of the message
queue, this gives Windows the opportunity to complete the
focus change before you attempt to change the focus back to
another control.
Attached is a unit and text representation of a DFM (form)
file which demonstrates this technique.
{ *** BEGIN CODE FOR UNIT5.PAS *** }
unit Unit5;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, Mask;
const
{ User-defined message }
um_ValidateInput = wm_User + 100;
type
TForm5 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Button1: TButton;
procedure EditExit(Sender: TObject);
procedure EditEnter(Sender: TObject);
private
Refocusing: TObject;
{ User-defined message handler }
procedure ValidateInput(var M: TMessage); message um_ValidateInput;
end;
var
Form5: TForm5;
implementation
{$R *.DFM}
procedure TForm5.ValidateInput(var M: TMessage);
var
E : TEdit;
begin
{ The following line is my validation. I want to make sure }
{ the first character is a lower case alpha character. Note }
{ the typecast of lParam to a TEdit. }
E := TEdit(M.lParam);
if not (E.Text[1] in ['a'..'z']) then begin
Refocusing := E; { Avoid a loop }
ShowMessage('Bad input'); { Yell at the user }
TEdit(E).SetFocus; { Set focus back }
end;
end;
procedure TForm5.EditExit(Sender: TObject);
begin
{ Post a message to myself which indicates it's time to }
{ validate the input. Pass the TEdit instance (Self) as }
{ the message lParam. }
if Refocusing = nil then
PostMessage(Handle, um_ValidateInput, 0, longint(Sender));
end;
procedure TForm5.EditEnter(Sender: TObject);
begin
if Refocusing = Sender then
Refocusing := nil;
end;
end.
{ *** END CODE FOR UNIT5.PAS *** }
{ *** BEGIN CODE FOR UNIT5.DFM *** }
object Form5: TForm5
Left = 489
Top = 303
Width = 318
Height = 205
Caption = 'Form5'
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'System'
Font.Style = []
PixelsPerInch = 96
TextHeight = 16
object Edit1: TEdit
Left = 32
Top = 32
Width = 121
Height = 24
TabOrder = 0
Text = 'Edit1'
OnEnter = EditEnter
OnExit = EditExit
end
object Edit2: TEdit
Left = 160
Top = 32
Width = 121
Height = 24
TabOrder = 1
Text = 'Edit2'
OnEnter = EditEnter
OnExit = EditExit
end
object Edit3: TEdit
Left = 32
Top = 64
Width = 121
Height = 24
TabOrder = 2
Text = 'Edit3'
OnEnter = EditEnter
OnExit = EditExit
end
object Edit4: TEdit
Left = 160
Top = 64
Width = 121
Height = 24
TabOrder = 3
Text = 'Edit4'
OnEnter = EditEnter
OnExit = EditExit
end
object Button1: TButton
Left = 112
Top = 136
Width = 89
Height = 33
Caption = 'Button1'
TabOrder = 4
end
end
{ *** END CODE FOR UNIT5.DFM *** }
TI