The best way for TEdit Number validation by type number

Mahdi78IT developping
CERTIFIED EXPERT
Published:
Hello everybody

This Article will show you how to validate number with TEdit control,

What's the TEdit control?

TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text.

Usually, programmer use OnKeyPress event to validate number input (Integer for example) like the following example

 
procedure TForm1.Edit12KeyPress(Sender: TObject; var Key: Char);
                      begin
                        if not (Key in [#8, '0'..'9']) then Key := #0;
                      end;

Open in new window


What problems aren't covered by OnKeyPress event?

OnKeyPress event analyzes keyboard inputs, but doesn't work with Copy/Paste or Ctrl + V keyboard shortcut, for that i found that, OnChange event is better to catch any kinds of inputs.

My idea basing on Undo and ClearUndo procedures of TEdit Control.

What's Undo and ClearUndo procedure?

Undo and ClearUndo procedure used by components belong to TCustomEdit class (such TEdit, TMaskedit, TMemo, TRichEdit...), we call Undo procedure to cancel all changes made to the TCustomEdit text since the last call to the ClearUndo procedure, and we call ClearUndo to commit changes to TCustomEdit text, after the excecuting of ClearUndo procedure,  Undo procedure does nothing until the TCustomEdit text has.a new changes.

The method I will use with OnChange event work like the following statement:

if TEdit input change is valid value then ClearUndo else Undo

Validate Number by type

The following example show you how to validate an Integer.
 
procedure TForm1.Edit1Change(Sender: TObject);
                      var Nbr: Integer;
                      begin
                      if TEdit(Sender).Text = '-' then Exit;
                      if TEdit(Sender).Text = '' then
                        begin
                        TEdit(Sender).Text := '0';
                        TEdit(Sender).SelectAll;
                        end
                      else if not TryStrToInt(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
                        else if (Nbr >= Low(Integer)) and (Nbr <= High(Integer)) then
                                TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
                      end;

Open in new window


Explanation

1) To allow input of "-" sign we will add this line (Integer is signed number)
if TEdit(Sender).Text = "-" then Exit;

2) When we clear TEdit we need to put "0"
TEdit(Sender).Text := '0';

3) When value of TEdit is null we need to make the control ready to clear '0' when user type another number
TEdit(Sender).SelectAll;

4) To check if the input is valid integer
if not TryStrToInt(TEdit(Sender).Text, Nbr)

5) To check if the integer value is Int32 (-2147483648..2147483647)
if (Nbr >= Low(Integer)) and (Nbr <= High(Integer)) then

Validate char input

In this part I will use the event to validate input string, the following example will check if input char allowed or not.for example (allowed chars are 'M','A','H','D','I','7','8')
 
procedure TForm1.Edit12Change(Sender: TObject);
                      Const AllowedStr = 'MAHDI78';
                      var I: Integer;
                      begin
                      for I := 1 to Length(TEdit(Sender).Text) do
                        begin
                        if (Pos(TEdit(Sender).Text[I], AllowedStr) = 0) then
                          begin
                          TEdit(Sender).Undo;
                          Exit;
                          end;
                        end;
                      TEdit(Sender).ClearUndo;
                      end;

Open in new window

   

Validate format

In this part the event will validate input format, the following example will check format ('ss-nssn-nn') the input value should be for example "AE-5DR8-34".
   
procedure TForm1.Edit13Change(Sender: TObject);
                      Const AllowedFormat = 'ss-nssn-nn'; // for Example AE-5DR8-34
                      var I : Integer;
                        P: PChar;
                      begin
                      if Length(TEdit(Sender).Text) > Length(AllowedFormat) then
                        begin
                        TEdit(Sender).Undo;
                        Exit;
                        end;
                      
                        P := PChar(TEdit(Sender).Text);
                        I := 1;
                        while P^ <> #0 do
                        begin
                        if AllowedFormat[I] = 's' then
                           begin
                           if not (P^ in ['A'..'Z']) then
                             begin
                             TEdit(Sender).Undo;
                             Beep; Exit;
                             end;
                           end else
                               if AllowedFormat[I] = 'n' then
                                begin
                                if not (P^ in ['0'..'9']) then
                                   begin
                                   TEdit(Sender).Undo;
                                   Beep; Exit;
                                   end;
                                end else if AllowedFormat[I] <> Char(P^) then
                                         begin
                                         TEdit(Sender).Undo;
                                         Beep; Exit;
                                         end;
                          Inc(P);
                          Inc(I);
                        end;
                      TEdit(Sender).ClearUndo;
                      end;

Open in new window


For more examples with (Smallint, ShortInt, Int64, Currency...) check the following sample

PAS unit
 
unit Unit1;
                      
                      /// Posted by Mahdi78 member in Experts-Exchage.com
                      /// Email mahdi_kamel@yahoo.fr
                      
                      interface
                      
                      uses
                        Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
                        Dialogs, StdCtrls;
                      
                      type
                        TForm1 = class(TForm)
                          Edit1: TEdit;
                          Edit2: TEdit;
                          Edit3: TEdit;
                          Edit4: TEdit;
                          Label1: TLabel;
                          Label2: TLabel;
                          Label3: TLabel;
                          Label4: TLabel;
                          Label5: TLabel;
                          Label6: TLabel;
                          Label7: TLabel;
                          Label8: TLabel;
                          Edit5: TEdit;
                          Edit6: TEdit;
                          Edit7: TEdit;
                          Edit8: TEdit;
                          Label9: TLabel;
                          Label10: TLabel;
                          Label11: TLabel;
                          Label12: TLabel;
                          Label13: TLabel;
                          Label14: TLabel;
                          Label15: TLabel;
                          Label16: TLabel;
                          Edit9: TEdit;
                          Label17: TLabel;
                          Label18: TLabel;
                          Label19: TLabel;
                          Label20: TLabel;
                          Edit10: TEdit;
                          Label21: TLabel;
                          Edit11: TEdit;
                          Label22: TLabel;
                          Edit12: TEdit;
                          Label23: TLabel;
                          Label24: TLabel;
                          Edit13: TEdit;
                          Label25: TLabel;
                          Label26: TLabel;
                          procedure Edit2Change(Sender: TObject);
                          procedure Edit3Change(Sender: TObject);
                          procedure Edit4Change(Sender: TObject);
                          procedure Edit5Change(Sender: TObject);
                          procedure Edit6Change(Sender: TObject);
                          procedure Edit7Change(Sender: TObject);
                          procedure Edit8Change(Sender: TObject);
                          procedure Edit9Change(Sender: TObject);
                          procedure Edit10Change(Sender: TObject);
                          procedure Edit11Change(Sender: TObject);
                          procedure Edit1Change(Sender: TObject);
                          procedure Edit12Change(Sender: TObject);
                          procedure Edit13Change(Sender: TObject);
                        private
                          { Private declarations }
                        public
                          { Public declarations }
                        end;
                      
                      var
                        Form1: TForm1;
                      
                      implementation
                      
                      uses math;
                      
                      {$R *.dfm}
                      
                      procedure TForm1.Edit10Change(Sender: TObject);
                      var Nbr: Extended;
                      begin
                      if TEdit(Sender).Text = '-' then Exit;
                      if (TEdit(Sender).Text = '') then
                        begin
                        TEdit(Sender).Text := '0';
                        TEdit(Sender).SelectAll;
                        end
                      else if not TryStrToFloat(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
                        else if (Nbr >= -2.9 * Power(10, -39) ) and (Nbr <= 1.7 * Power(10, 38)) then
                                TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
                      end;
                      
                      procedure TForm1.Edit11Change(Sender: TObject);
                      var Nbr: Currency;
                      begin
                      if TEdit(Sender).Text = '-' then Exit;
                      if (TEdit(Sender).Text = '') then
                        begin
                        TEdit(Sender).Text := '0';
                        TEdit(Sender).SelectAll;
                        end
                      else if not TryStrToCurr(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
                        else if (Nbr >= -922337203685477.5808) and (Nbr <= 922337203685477.5807) then
                                TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
                      end;
                      
                      procedure TForm1.Edit12Change(Sender: TObject);
                      Const AllowedStr = 'MAHDI78';
                      var I: Integer;
                      begin
                      for I := 1 to Length(TEdit(Sender).Text) do
                        begin
                        if (Pos(TEdit(Sender).Text[I], AllowedStr) = 0) then
                          begin
                          TEdit(Sender).Undo;
                          Exit;
                          end;
                        end;
                      TEdit(Sender).ClearUndo;
                      end;
                      
                      procedure TForm1.Edit13Change(Sender: TObject);
                      Const AllowedFormat = 'ss-nssn-nn'; // for Example AE-5DR8-34
                      var I : Integer;
                        P: PChar;
                      begin
                      if Length(TEdit(Sender).Text) > Length(AllowedFormat) then
                        begin
                        TEdit(Sender).Undo;
                        Exit;
                        end;
                      
                        P := PChar(TEdit(Sender).Text);
                        I := 1;
                        while P^ <> #0 do
                        begin
                        if AllowedFormat[I] = 's' then
                           begin
                           if not (P^ in ['A'..'Z']) then
                             begin
                             TEdit(Sender).Undo;
                             Beep; Exit;
                             end;
                           end else
                               if AllowedFormat[I] = 'n' then
                                begin
                                if not (P^ in ['0'..'9']) then
                                   begin
                                   TEdit(Sender).Undo;
                                   Beep; Exit;
                                   end;
                                end else if AllowedFormat[I] <> Char(P^) then
                                         begin
                                         TEdit(Sender).Undo;
                                         Beep; Exit;
                                         end;
                          Inc(P);
                          Inc(I);
                        end;
                      TEdit(Sender).ClearUndo;
                      end;
                      
                      procedure TForm1.Edit1Change(Sender: TObject);
                      var Nbr: Integer;
                      begin
                      if TEdit(Sender).Text = '-' then Exit;
                      if TEdit(Sender).Text = '' then
                        begin
                        TEdit(Sender).Text := '0';
                        TEdit(Sender).SelectAll;
                        end
                      else if not TryStrToInt(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
                        else if (Nbr >= Low(Integer)) and (Nbr <= High(Integer)) then
                                TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
                      end;
                      
                      procedure TForm1.Edit2Change(Sender: TObject);
                      var Nbr: Integer;
                      begin
                      if (TEdit(Sender).Text = '') or (TEdit(Sender).Text = '-') then
                        begin
                        TEdit(Sender).Text := '0';
                        TEdit(Sender).SelectAll;
                        end
                      else if not TryStrToInt(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
                        else if (Nbr >= Low(Byte)) and (Nbr <= High(Byte)) then
                                TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
                      end;
                      
                      procedure TForm1.Edit3Change(Sender: TObject);
                      var Nbr: Integer;
                      begin
                      if TEdit(Sender).Text = '-' then Exit;
                      if TEdit(Sender).Text = '' then
                        begin
                        TEdit(Sender).Text := '0';
                        TEdit(Sender).SelectAll;
                        end
                      else if not TryStrToInt(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
                        else if (Nbr >= Low(Shortint)) and (Nbr <= High(Shortint)) then
                                TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
                      end;
                      
                      procedure TForm1.Edit4Change(Sender: TObject);
                      var Nbr: Integer;
                      begin
                      if TEdit(Sender).Text = '-' then Exit;
                      if TEdit(Sender).Text = '' then
                        begin
                        TEdit(Sender).Text := '0';
                        TEdit(Sender).SelectAll;
                        end
                      else if not TryStrToInt(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
                        else if (Nbr >= Low(Smallint)) and (Nbr <= High(Smallint)) then
                                TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
                      end;
                      
                      procedure TForm1.Edit5Change(Sender: TObject);
                      var Nbr: Integer;
                      begin
                      if (TEdit(Sender).Text = '') or (TEdit(Sender).Text = '-') then
                        begin
                        TEdit(Sender).Text := '0';
                        TEdit(Sender).SelectAll;
                        end
                      else if not TryStrToInt(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
                        else if (Nbr >= Low(Word)) and (Nbr <= High(Word)) then
                                TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
                      end;
                      
                      procedure TForm1.Edit6Change(Sender: TObject);
                      var Nbr: Int64;
                      begin
                      if (TEdit(Sender).Text = '') or (TEdit(Sender).Text = '-') then
                        begin
                        TEdit(Sender).Text := '0';
                        TEdit(Sender).SelectAll;
                        end
                      else if not TryStrToInt64(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
                        else if (Nbr >= Low(Cardinal)) and (Nbr <= High(Cardinal)) then
                                TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
                      end;
                      
                      procedure TForm1.Edit7Change(Sender: TObject);
                      var Nbr: Int64;
                      begin
                      if TEdit(Sender).Text = '-' then Exit;
                      if TEdit(Sender).Text = '' then
                        begin
                        TEdit(Sender).Text := '0';
                        TEdit(Sender).SelectAll;
                        end
                      else if not TryStrToInt64(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
                        else if (Nbr >= Low(Int64)) and (Nbr <= High(Int64)) then
                                TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
                      end;
                      
                      procedure TForm1.Edit8Change(Sender: TObject);
                      var Nbr: Int64;
                      begin
                      if (TEdit(Sender).Text = '') or (TEdit(Sender).Text = '-') then
                        begin
                        TEdit(Sender).Text := '0';
                        TEdit(Sender).SelectAll;
                        end
                      else if not TryStrToInt64(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
                        else if (Nbr >= Low(Longword)) and (Nbr <= High(Longword)) then
                                TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
                      end;
                      
                      procedure TForm1.Edit9Change(Sender: TObject);
                      var Nbr: Extended;
                      begin
                      if (TEdit(Sender).Text = '') then
                        begin
                        TEdit(Sender).Text := '0';
                        TEdit(Sender).SelectAll;
                        end
                      else if not TryStrToFloat(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
                        else if (Nbr >= 0 ) and (Nbr <= (1.7 * Power(2, 64)) - 1) then
                                TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
                      end;
                      
                      end.

Open in new window

 

DFM unit
   
object Form1: TForm1
                        Left = 0
                        Top = 0
                        Caption = 'Form1'
                        ClientHeight = 441
                        ClientWidth = 804
                        Color = clBtnFace
                        Font.Charset = DEFAULT_CHARSET
                        Font.Color = clWindowText
                        Font.Height = -11
                        Font.Name = 'Tahoma'
                        Font.Style = []
                        OldCreateOrder = False
                        PixelsPerInch = 96
                        TextHeight = 13
                        object Label1: TLabel
                          Left = 33
                          Top = 32
                          Width = 36
                          Height = 13
                          Caption = 'Integer'
                        end
                        object Label2: TLabel
                          Left = 33
                          Top = 60
                          Width = 22
                          Height = 13
                          Caption = 'Byte'
                        end
                        object Label3: TLabel
                          Left = 33
                          Top = 86
                          Width = 38
                          Height = 13
                          Caption = 'Shortint'
                        end
                        object Label4: TLabel
                          Left = 33
                          Top = 114
                          Width = 36
                          Height = 13
                          Caption = 'Smallint'
                        end
                        object Label5: TLabel
                          Left = 33
                          Top = 141
                          Width = 26
                          Height = 13
                          Caption = 'Word'
                        end
                        object Label6: TLabel
                          Left = 33
                          Top = 168
                          Width = 39
                          Height = 13
                          Caption = 'Cardinal'
                        end
                        object Label7: TLabel
                          Left = 33
                          Top = 195
                          Width = 26
                          Height = 13
                          Caption = 'Int64'
                        end
                        object Label8: TLabel
                          Left = 33
                          Top = 221
                          Width = 47
                          Height = 13
                          Caption = 'Longword'
                        end
                        object Label9: TLabel
                          Left = 522
                          Top = 32
                          Width = 132
                          Height = 13
                          Caption = '-2147483648..2147483647'
                        end
                        object Label10: TLabel
                          Left = 522
                          Top = 59
                          Width = 32
                          Height = 13
                          Caption = '0..255'
                        end
                        object Label11: TLabel
                          Left = 522
                          Top = 86
                          Width = 48
                          Height = 13
                          Caption = '-128..127'
                        end
                        object Label12: TLabel
                          Left = 522
                          Top = 114
                          Width = 72
                          Height = 13
                          Caption = '-32768..32767'
                        end
                        object Label13: TLabel
                          Left = 522
                          Top = 140
                          Width = 44
                          Height = 13
                          Caption = '0..65535'
                        end
                        object Label14: TLabel
                          Left = 522
                          Top = 169
                          Width = 74
                          Height = 13
                          Caption = '0..4294967295'
                        end
                        object Label15: TLabel
                          Left = 522
                          Top = 198
                          Width = 74
                          Height = 13
                          Caption = '-2^63..2^63-1'
                        end
                        object Label16: TLabel
                          Left = 522
                          Top = 221
                          Width = 74
                          Height = 13
                          Caption = '0..4294967295'
                        end
                        object Label17: TLabel
                          Left = 33
                          Top = 248
                          Width = 33
                          Height = 13
                          Caption = 'UInt64'
                        end
                        object Label18: TLabel
                          Left = 522
                          Top = 248
                          Width = 52
                          Height = 13
                          Caption = '0..2^64'#8211'1'
                        end
                        object Label19: TLabel
                          Left = 33
                          Top = 280
                          Width = 33
                          Height = 13
                          Caption = 'Real48'
                        end
                        object Label20: TLabel
                          Left = 522
                          Top = 280
                          Width = 150
                          Height = 13
                          Caption = '-2.9 x 10^'#8211'39 .. 1.7 x 10^38  '
                        end
                        object Label21: TLabel
                          Left = 32
                          Top = 312
                          Width = 44
                          Height = 13
                          Caption = 'Currency'
                        end
                        object Label22: TLabel
                          Left = 522
                          Top = 312
                          Width = 251
                          Height = 13
                          Caption = '-922337203685477.5808.. 922337203685477.5807'
                        end
                        object Label23: TLabel
                          Left = 537
                          Top = 352
                          Width = 162
                          Height = 13
                          Caption = 'AllowedStr = '#39'M'#39','#39'A'#39','#39'H'#39','#39'D'#39','#39'I'#39','#39'7'#39','#39'8'#39
                        end
                        object Label24: TLabel
                          Left = 32
                          Top = 352
                          Width = 23
                          Height = 13
                          Caption = 'Char'
                        end
                        object Label25: TLabel
                          Left = 34
                          Top = 398
                          Width = 34
                          Height = 13
                          Caption = 'Format'
                        end
                        object Label26: TLabel
                          Left = 537
                          Top = 398
                          Width = 177
                          Height = 13
                          Caption = 'ss-nssn-nn  for example AE-5DR8-34'
                        end
                        object Edit1: TEdit
                          Left = 112
                          Top = 29
                          Width = 400
                          Height = 21
                          TabOrder = 0
                          Text = '0'
                          OnChange = Edit1Change
                        end
                        object Edit2: TEdit
                          Left = 112
                          Top = 56
                          Width = 400
                          Height = 21
                          TabOrder = 1
                          Text = '0'
                          OnChange = Edit2Change
                        end
                        object Edit3: TEdit
                          Left = 112
                          Top = 83
                          Width = 400
                          Height = 21
                          TabOrder = 2
                          Text = '0'
                          OnChange = Edit3Change
                        end
                        object Edit4: TEdit
                          Left = 112
                          Top = 110
                          Width = 400
                          Height = 21
                          TabOrder = 3
                          Text = '0'
                          OnChange = Edit4Change
                        end
                        object Edit5: TEdit
                          Left = 112
                          Top = 137
                          Width = 400
                          Height = 21
                          TabOrder = 4
                          Text = '0'
                          OnChange = Edit5Change
                        end
                        object Edit6: TEdit
                          Left = 112
                          Top = 164
                          Width = 400
                          Height = 21
                          TabOrder = 5
                          Text = '0'
                          OnChange = Edit6Change
                        end
                        object Edit7: TEdit
                          Left = 112
                          Top = 191
                          Width = 400
                          Height = 21
                          TabOrder = 6
                          Text = '0'
                          OnChange = Edit7Change
                        end
                        object Edit8: TEdit
                          Left = 112
                          Top = 218
                          Width = 400
                          Height = 21
                          TabOrder = 7
                          Text = '0'
                          OnChange = Edit8Change
                        end
                        object Edit9: TEdit
                          Left = 112
                          Top = 245
                          Width = 400
                          Height = 21
                          TabOrder = 8
                          Text = '0'
                          OnChange = Edit9Change
                        end
                        object Edit10: TEdit
                          Left = 112
                          Top = 277
                          Width = 400
                          Height = 21
                          TabOrder = 9
                          Text = '0'
                          OnChange = Edit10Change
                        end
                        object Edit11: TEdit
                          Left = 112
                          Top = 309
                          Width = 400
                          Height = 21
                          TabOrder = 10
                          Text = '0'
                          OnChange = Edit11Change
                        end
                        object Edit12: TEdit
                          Left = 112
                          Top = 352
                          Width = 400
                          Height = 21
                          TabOrder = 11
                          OnChange = Edit12Change
                        end
                        object Edit13: TEdit
                          Left = 112
                          Top = 395
                          Width = 400
                          Height = 21
                          TabOrder = 12
                          OnChange = Edit13Change
                        end
                      end

Open in new window

2
15,359 Views
Mahdi78IT developping
CERTIFIED EXPERT

Comments (9)

aikimarkGet vaccinated; Social distance; Wear a mask
CERTIFIED EXPERT
Top Expert 2014

Commented:
>>...i think it work like the following example
It doesn't.  I found this Trying article very helpful to explain what is going on
http://www.prototypical.co.uk/pdf/trying.pdf

They showed the two Sysutils functions.
function StrToInt(const S: string): Integer;
var
  E: Integer;
begin
  Val(S, Result, E);
  if E <> 0 then
    ConvertErrorFmt(@SInvalidInteger, [S]);
end;

function TryStrToInt(const S: string; out Value: Integer): Boolean;
var
  E: Integer;
begin
  Val(S, Value, E);
  Result := E = 0;
end

Open in new window


When you use any of the Try conversion functions, you do not have to include a range check, since it is implicit by the successful conversion.
Mark WillsTopic Advisor
CERTIFIED EXPERT
Distinguished Expert 2018

Commented:
I think the "Try" prefix on those functions reflects the boolean nature of those functions and not how they work internally. So, you can use in a similar way as the try/except block by encapsulating within an If/then/else block.

So, instead of (plagiarising from the article link above) :
try
            ResultLabel.Caption := IntToStr(StrToInt(StrEdit.Text));
except on E : EConvertError do
            ResultLabel.Caption := StrEdit.Text + ‘ is not a valid integer’;
end;

Open in new window

you can now do with the "Try..." functions :
if TryStrToInt(StrEdit.Text,TempInt) then begin
            ResultLabel.Caption := IntToStr(TempInt);
end else begin
            ResultLabel.Caption := StrEdit.Text + ‘ is not a valid integer’;
end;

Open in new window


But that is a bit of a moot point in some regards, and I think the Article is a good reminder of where we should actually check content changes, and that would be on the OnChange event so it does capture every user change instance...

The only "gotcha" with that event is when you want to force a value programmatically that might contradict what a user can do (regardless of how they do it). On those rare occassions I have sometimes had to introduce a "ForceChange" type flag to override the normal OnChange processing (bit yucky, but effective all the same).

All in all a good article and thanks for sharing. Voted Yes.

Cheers,
Mark Wills
Mahdi78IT developping
CERTIFIED EXPERT

Author

Commented:
@mark_wills
You're welcome and thank you for participation,

>> The only "gotcha" with that event is when you want to force a value programmatically ...

I agree with you, but in my code force change couldn't work, and couldn't pass through TryStrToInt function and Undo procedure,

Look this scenario:

1- User made changes, if the changes is true TEdit will keep it by ClearUndo procedure by clearing previous undo
2- TEdit will never accept invalid force changes and it will clear them by Undo procedure and replace them with last true change which kept by ClearUndo procedure, else if some of force changes is true, will keep it by ClearUndo
aikimarkGet vaccinated; Social distance; Wear a mask
CERTIFIED EXPERT
Top Expert 2014

Commented:
Where is the cursor after the undo?
Mahdi78IT developping
CERTIFIED EXPERT

Author

Commented:
And even after the ClearUndo, the cursor tun into ghost :D
It's enough to add the following code in the end of event

SetCursorPos(Mouse.CursorPos.X, Mouse.CursorPos.Y);

View More

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.