Author: William Gerbert
How to use only numerical input in a TEdit
Answer:
If you want to limit the input of a TEdit to numerical strings only, you can
discard the "invalid" characters in its OnKeyPress event handler.
Let's assume that you only want to allow positive integer numbers. The code for the
OnKeyPress event handler is as follows:
1
2 procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
3 begin
4 // #8 is Backspace
5 if not (Key in [#8, '0'..'9']) then
6 begin
7 ShowMessage('Invalid key');
8 // Discard the key
9 Key := #0;
10 end;
11 end;
If you also want numbers with a decimal fraction, you must allow a POINT or a
COMMA, but only once. For an international version that looks at the correct
decimal separator, the code could be as follows:
12
13 procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
14 begin
15 if not (Key in [#8, '0'..'9', DecimalSeparator]) then
16 begin
17 ShowMessage('Invalid key: ' + Key);
18 Key := #0;
19 end
20 else if (Key = DecimalSeparator) and
21 (Pos(Key, Edit1.Text) > 0) then
22 begin
23 ShowMessage('Invalid Key: twice ' + Key);
24 Key := #0;
25 end;
26 end;
And here's a full blown version of the event handler, accepting a decimal separator
and negative numbers (minus sign: only accepted once, has to be the first
character):
27
28 procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
29 begin
30 if not (Key in [#8, '0'..'9', '-', DecimalSeparator]) then
31 begin
32 ShowMessage('Invalid key: ' + Key);
33 Key := #0;
34 end
35 else if ((Key = DecimalSeparator) or (Key = '-')) and
36 (Pos(Key, Edit1.Text) > 0) then
37 begin
38 ShowMessage('Invalid Key: twice ' + Key);
39 Key := #0;
40 end
41 else if (Key = '-') and
42 (Edit1.SelStart <> 0) then
43 begin
44 ShowMessage('Only allowed at beginning of number: ' + Key);
45 Key := #0;
46 end;
47 end;
How about giving that same behaviour to several TEdits on the same form, say 10 of
them? In the Object Inspector, you change the name of the event handler of Edit1
from Edit1KeyPress to Edit1_10KeyPress or something similar. Delphi automatically
changes the name in the code editor, don't worry.
Then, for each next TEdit, you select its OnKeyPress event and you select
Edit1_10KeyPress from the listbox next to the event.
Finally, we have to slightly adapt the code. Intead of pointing to Edit1, we must
point to "the TEdit that generated the event", in other words: the edit-box where
the cursor was when a key was depressed. When you look at the template for the
event handler that Delphi made, you see the parameter Sender: that's a pointer to
the component that generated the event. But we are not allowed to use it straight
away in our code, we must specify that we're dealing with a component of the type
TEdit. That's done with the code Sender as TEdit:
48
49 procedure TForm1.Edit1_10KeyPress(Sender: TObject; var Key: Char);
50 begin
51 if not (Key in [#8, '0'..'9', '-', DecimalSeparator]) then
52 begin
53 ShowMessage('Invalid key: ' + Key);
54 Key := #0;
55 end
56 else if ((Key = DecimalSeparator) or (Key = '-')) and
57 (Pos(Key, (Sender as TEdit).Text) > 0) then
58 begin
59 ShowMessage('Invalid Key: twice ' + Key);
60 Key := #0;
61 end
62 else if (Key = '-') and
63 ((Sender as TEdit).SelStart <> 0) then
64 begin
65 ShowMessage('Only allowed at beginning of number: ' + Key);
66 Key := #0;
67 end;
68 end;
|