The OnUserRule and OnTextChangedAt events of the TLMDMaskEdit control
Once again, many thanks to Roddy Pratt for the subject of this post.
The OnUserRule event serves to check if entered symbol is correct for a given place when MaskType = meMask and there is an “r” letter in the mask. For example, if Mask = ‘rr’, following OnUserRule handler allows to enter “aa”, “ab”, “ba”, “bb” strings only:
procedure TForm1.LMDMaskEdit1UserRule(Sender: TObject; var Ok: Boolean; c: WideChar; at: Integer); begin ok := ( c = 'a' ) or ( c = 'b' ); end;
While implementing some kind of tricky user rule, it is very easy to yield to temptation of changing text with OnUserRule event.
This is what should never be done unless you have some free hours to debug unexpected behavior of your construction.
So, the message of this post is: do not use the OnUserRule event for changing the Text while it is being checked.
You should use the OnTextChangedAt for this purposes.
Here is an example of how to modify text while user is entering characters: LMDMaskEdit control with a custom rule ( Mask = ‘rr’ ) that allows entry of 2-digit numbers between 00 and 23 (including bounds). If a number is greater than 23 is entered, then the units digit is automatically set to 3.
procedure TForm1.LMDMaskEdit1UserRule(Sender: TObject; var Ok: Boolean;
c: WideChar; at: Integer);
begin
case at of
1: ok := ( Pos(AnsiChar(c), '012' ) > 0);
2: ok := ( (Pos(AnsiChar(LMDMaskEdit1.Text[1]), '012' )
> 0) ) and
( (Pos(AnsiChar(c), '0123456789' ) > 0) ) ;
end;
end;
procedure TForm1.LMDMaskEdit1TextChangedAt(sender: TObject; At: Integer);
begin
if (at = 2) and (Pos(LMDMaskEdit1.BlankChar,
LMDMaskEdit1.Text) = 0) then
if strtoint(LMDMaskEdit1.Text) > 23 then
LMDMaskEdit1.Text := '23';
end;
Note that LMDMaskEdit1.TextChangedAt can be simplified in this example if
BlankChar = ’0′:
procedure TForm1.LMDMaskEdit1TextChangedAt(sender: TObject; At: Integer);
begin
if (at = 2) then
if strtoint(LMDMaskEdit1.Text) > 23 then
LMDMaskEdit1.Text := '23';
end;
