I’m trying to make a simple edit component that accepts 24h time format with autocorrection to the needed format which is HH:MM.
and my approach as follow:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
var
i : integer;
s: string;
begin
Edit1.MaxLength:= 5;
i := length(Edit1.Text)+1;
case i of
1: begin
if Not (Key in [#8, '0'..'2']) then
Edit1.Text := '';
end;
2: begin
if Not (Key in [#8, '0'..'3']) then
Edit1.Text := '';
end;
3: begin
if (Key in [#8, '0'..'9']) then
begin
s := Edit1.Text;
Insert(':', s, 3);
Edit1.Text := s;
end
else
end;
end;
end;
but I do not seem figuring the flow correctly although I’m still trying so I though If someone could figure this out please?
Big note: I do not want to use Masks! or DateTimePickers! I need just to intercept the keys to build the input as above.
9
You need to think very carefully about how you want the behaviour of this to appear to the user. AmigoJack mentioned the issue of pasting text into the box, and your response was to solve each issue separately. However, the best way to solve that issue might be to completely change your approach. It’s best to figure out all of these issues at the start.
The first problem I see with your code is that when your event handler gets the second acceptable key, the edit is cleared!
The next problem I see is that if you have both the hour digits and the user types a colon, nothing happens, and they get frustrated. So, an alternative is to add the colon after they type the second digit rather than when they type the third digit.
But what if you do that, so the edit now has '01:'
, and they want to change the 1? Do they backspace once to delete the '1'
, or twice to delete the colon and the '1'
? If the colon is there before they type anything (i.e. '__:__'
where the underscores are spaces), that might solve that problem (people are used to such things when typing credit card expiry dates, for example).
Another problem is that they may use the left arrow key to go back to the ‘1’. So they would then be trying to change the second character of a 3- or 4-character string, but your method assumes that they are adding a character to the end rather than changing an existing character.
A good approach may be to not process the key strokes, but to check the entire string after each change. This may also make it easier to handle pasting.
Perhaps something like this:
- After each change, take a copy of the existing text.
- Check each character for acceptability.
- If any character is not acceptable, revert that character to the one in the copy you’ve taken. And perhaps issue a beep so that they know that what they did is unacceptable.
Chances are, there are situations I haven’t covered, so you’d need to refine this more, but this may be a starting point.
1
If you want to prohibit a key, setting Edit.Text to ” not the right way to go. Instead you should set AKey to #0.
Doing it the way you do, the invalid key will simply replace the original text.
1