Limit and convenient user input (2002/12/03 three gold copyright)
Preventing user malfunctioning is an essential job of software development, except for users, but also to provide the user's use of the most convenient. Of course, we can use or develop new components to complete these features. However, in the team development, each member uses the module you undertake with the components you think, and will bring trouble to the later maintenance of the software. When I am working, the project leader may not buy your account. If you use a function call to complete these features, the old cover is not tuned. Below is a limiting user input function for common Delphi components, I hope that netizens can use it. (1) TEDIT, TDBEDIT, TCOMBOBOX, TDBCOMBOBOX input division three types: (1) Any input (2) Integer input (3) The project of floating point number input restrictions is as follows: (1) Integer input can only enter digital 0- 9, , - (2) Floating point input can only enter numbers 0-9, , - ,. (3) and - can only have one, and can only appear at the forefront (4). Only One (5) limiting the number of digits is as follows: Procedure MxFormatKeyPress (Text: String; SELSTART, SELLENGTH: Integer; var Key: char; edittype: integer; digits: integer; begin if (key = # 27) OR # 8) or (edittype = 1) Then exit; if edittype = 2 Then if not (Key In ['0' .. '9', ' ', '-']) Then Key: = # 0; if EditType = 3 Then if not (key in ['0' .. '9', ' ', '-', '.']) THEN Key: = # 0; // Control - IF (Key = '-' ) or (key = ' ') THEN BEGIN IF ((POS ('-', text)> 0) or (POS ( ', Text)> 0)))) and (selLength = 0) Then key: = # 0; if SELSTART> 0 THEN Key: = # 0; end; // Control. IF (key = '.') And (edittype = 3) THEN BEGIN IF (POS ('.', Text)> 0) and ( Not ((SELSTART)
= POS ('.', Text))))))))..
If SELSTART = 0 THEN Key: = # 0;
IF (DIGITS> 0) and (SELSTART SELLENGTH
0) And (edittype = 3) THEN
IF (POS ('.', Text)> 0) and (selstart> = POS ('.', text)) THEN
If Length (TEXT) -POS ('.', Text)> = DIGITS THEN Key: = # 0;
This function calls in the onkeypress event of the restriction component. Key is on ONKEYPRESS
Key: char parameters; edittype is the type of limit: 1 - any input; 2-integer input; 3-floating point input;
DIGITS is a bit number of decimals when the floating point number is input. If it is zero, you can enter any bit number. In addition, this
The function applies only to derived classes of the TwinControl class with properties such as Text, Selstart, Sellength.
Specifically limit the secondary functions of each component as follows:
Limit TEDIT, TDBEDIT:
Procedure mxformateditKeyPress (Edit: tcustomedit; var key: char; edittype: integer;
Digits: integer;
Begin
MxFormatKeyPress (Edit.Text, Edit.selstart, Edit.sellength, Key, EditType, DIGITS)
END;
Limit TcomboBox:
Procedure MXFORMATCOMBOKEYPRESS (Combo: TcomboBox; var key: char; edittype: integer;
Digits: integer;
Begin
MxFormatKeyPress (Combo.Text, Combo.selstart, Combo.sellength, Key, Edittype, Digits);
END;
Limit TDBCOMBOBOX:
Procedure MXFORMATDBCOMBOKEYPRESS (COMBO: TDBCOMBOBOX; VAR Key: char;
EditType: Integer; Digits: Integer;
Begin
MxFormatKeyPress (Combo.Text, Combo.selstart, Combo.sellength, Key, Edittype, Digits);
END;
Call example:
If there is a ComboBox1 on Form1, let the user only enter the floating point number and the number of digits is two. then
The above functions can be called in the ComboBox1 onKeyPress event, the code is as follows:
Procedure TFORM1.COMBOBOX1KEYPRESS (Sender: Tobject; Var Key: char);
Begin
MXFORMATCOMBOKEYPRESS (ComboBOBOX1, KEY, 3, 0);
END;
If there are multiple TcomboBox on your form, and the limit type is consistent, you don't have to have every Tcombobox
Write code, just write event processing code for one of them, others can be connected.
Procedure TFORM1.COMBOBOX1KEYPRESS (Sender: Tobject; Var Key: char);
Begin
MXFORMATCOMBOKEYPRESS (Sender AS Tcombobox, Key, 3,0);
END;
Other components call methods are the same.
(2) Input of time
Limit type:
(1) Time
(2) time second
The components use Tmaskedit, data sensitive uses TDBEDIT.
The limit items are as follows:
(1) You can only enter 0-23 hours
(2) No more than 59 minutes
(3) seconds no more than 59
(4) Users can only delete, and cannot only delete a bit data (5) arrow keys can change time
You need to write code separately in the onkeypress and onkeydown events of the component.
Procedure MXFORMATTIMEKEYPRESS (CTL: TCUSTOMMASKEDIT; TIMEFORMAT: Integer;
Var key: char; dts: tdataasource;
VAR
Textsave: String;
EditingPos: Integer; // 1-H 2-m 3-S
i: integer;
Numchars: set of char;
SELSTARTSAVE, SELLENGTHSAVE: Integer;
Charvalid: boolean;
Begin
Numchars: = ['0' .. '9'];
IF key = ^ v then key: = # 0;
IF NOT (Key In Numchars).
Textsave: = CTL.Text;
SELSTARTSAVE: = CTL.SELSTART;
SELLENGTHSAVE: = CTL.Sellength;
Case CTL.SELSTART OF
0,1: editingpos: = 1;
3,4: editingpos: = 2;
6,7: editingpos: = 3;
Else EditingPos: = 0;
END;
///
CHARVALID: = True;
Case EditingPOS of
1: Begin
If SELSTARTSAVE = 0 THEN BEGIN
IF not (Key In ['0' .. '2']).................
IF (Key = '2') and (Textsave [2] in ['4' .. '9']) THEN
CHARVALID: = false;
END;
IF (SELSTARTSAVE = 1) and (Textsave [1] = '2') and
(NOT (Key In ['0' .. '3'))..).
END;
2: if (selstartsave = 3) and not (key in ['0' .. '5']) THEN CHARVALID: = FALSE
3: IF (selstartsave = 6) and not (key in ['0' .. '5']) THEN CHARVALID: = FALSE
END;
IF not charvalid the begin
Key: = # 0; exit;
END;
IF DTS <> nil dam.dataset.edit;
IF not (SELSTARTSAVE IN [2, 5]) TEXTSAVE [SELSTARTSAVE 1]: = KEY;
IF Sellength> 1 THEN Begin
For i: = sleelstartsave 2 to Selstartsave SelLengthsave DO
IF [1, 2, 4, 5, 7, 8] THEN TEXTSAVE [I]: = '0';
SELLENGTHSAVE: = 1;
END;
For i: = 1 to Length (Textsave) DO
IF (I IN [1, 2, 4, 5, 7, 8]) and (NOT (Textsave [I] in Numchars) Thentextsave [i]: = '0';
IF SELSTARTSAVE IN [1,4] THEN
SELSTARTSAVE: = SELSTARTSAVE 2
Else if selstartsave = length (Textsave) -1 Then
SELSTARTSAVE: = SELSTARTSAVE
Else SELSTARTSAVE: = SELSTARTSAVE 1;
/
CTL.TEXT: = Textsave;
CTL.SELSTART: = SELSTARTSAVE;
CTL.Sellength: = SELLENGTHSAVE;
Key: = # 0;
END;
// This function segmentation time, because sometimes it will encounter illegal time strings, so DECODETIME is not used.
Function MXSPLITSTR (SourceStr, Splitstr: String; Var ResultArray: Array Of String): Integer;
VAR
i: integer;
Strtmp: String;
Begin
Strtmp: = SourceStr;
I: = 0;
While Pos (Splitstr, Strtmp)> 0 do begin
ResultArray [I]: = Copy (StrtMP, 1, POS (Splitstr, StrtMP) - 1);
Strtmp: = COPY (StrtMP, POS (Splitstr, Strtmp) Length (splitstr), Length (Strtmp) -
POS (Splitstr, Strtmp);
i: = i 1;
END;
ResultArray [I]: = strtmp;
Result: = i 1;
END;
// This function checks if the string is a legal time.
Function TimeValid (TimeStr: String; TimeFormat: Integer): boolean;
VAR
H, M, S: String;
Ary: array [0..2] of string;
Splitret: integer;
i: integer;
Begin
RESULT: = true;
Splitret: = MXSPLITSTR (TimeStr, ':', ARY);
IF splitret <2 THEN Begin
Result: = FALSE; EXIT;
END;
For i: = 0 to 2 do begin
IF Length (Ary [i])> 2 THEN Begin
Result: = FALSE; EXIT;
END;
Ary [I]: = TRIM (Ary [i]);
END;
H: = ary [0]; m: = ary [1];
If TimeFormat = 3 THEN S: = ary [2];
///
IF (h = '') or (strt (h)> 23) THEN Begin
Result: = FALSE; EXIT;
END;
IF (m = ') or (Strtoint (M)> 59) THEN Begin
Result: = FALSE; EXIT;
END;
IF (TimeFormat = 3) THEN
IF (s = '') or (STRTOINT (S)> 59) THEN BEGIN
Result: = FALSE;
END;
END;
// This function adds and subtails to time second
Function Inctime (atime: tdatetime; hours, minutes, seconds,
Msecs: integer; tdatetime;
Begin
Result: = ATIME (Hours Div 24) ((Hours MOD 24) * 3600000
Minutes * 60000 seconds * 1000 msecs) / msecsperday;
If Result <0 Then Result: = Result 1;
END;
// Duration secondary decreased secondary function
Function TimeAdd (TimeStr: String; TimeFormat: Integer;
HSTEP, MSTEP, SSTEP: Integer: String;
VAR
DT: TDATETIME;
Begin
IF not timevalid (TimeStr, TimeFormat)
If TimeFormat = 2 Then Begin Result: = '00:00'; EXIT; END
Else Begin Result: = '00: 00: 00'; EXIT; END;
DT: = STRTOTIME (TIMESTR);
if TimeFormat = 2 THEN
Result: = formatdatetime ('HH: mm', INCTIME (DT, HStep, MSTEP, SSTEP, 0))
Else
Result: = formatdatetime ('hh: mm: ss', INCTIME (DT, HStep, MSTEP, SSTEP, 0))
END;
// Limit the iNkeyDown
Procedure MXFORMATTIMEKEYDOWN (CTL: TCUSTOMMASKEDIT; TIMEFORMAT: Integer;
VAR Key: Word; Shift: TshiftState; DTS: TDataSource;
VAR
Textsave: String;
SELSTARTSAVE, SELLENGTHSAVE: Integer;
EditingPos: Integer; // 1-H 2-m 3-S
i: integer;
Begin
IF (SSSHIFT in shift) and (Key <> vk_delete).
IF not (key in [vk_delete, vk_back, vk_up, vk_down]).
IF (DTS <> NIL) and (not dts.dataset.act) kiln.
IF (DTS <> nil) and (not dts.dataset.modified) THEN
DTS.DataSet.EDIt;
//
Textsave: = CTL.Text;
SELSTARTSAVE: = CTL.SELSTART;
SELLENGTHSAVE: = CTL.Sellength;
Case Selstartsave of
0,1: editingpos: = 1;
3,4: editingpos: = 2;
6,7: editingpos: = 3;
Else EditingPos: = 0;
END;
If SELSTARTSAVE = Length (Textsave) THEN
EDITIPOS: = TimeFormat;
IF key = vk_delete the begin
If Sellength, IFTH (Textsave) TEXTSAVE: = ''
Else Beginif Not (SELSTARTSAVE IN [2, 5]) TEXTSAVE [SELSTARTSAVE 1]: = '0';
IF Sellength> 1 THEN Begin
For i: = sleelstartsave 2 to Selstartsave SelLengthsave DO
IF [1, 2, 4, 5, 7, 8] THEN TEXTSAVE [I]: = '0';
SELLENGTHSAVE: = 1;
END;
END;
Key: = 0;
END;
IF key = vk_back the begin
If Sellength, IFTH (Textsave) TEXTSAVE: = ''
Else if selLengthsave <= 1 THEN BEGIN
IF not (SELSTARTSAVE IN [3,6]) THEN BEGIN
Textsave [SELSTARTSAVE]: = '0';
SELSTARTSAVE: = SELSTARTSAVE-1;
ELSE BEGIN
Textsave [SELSTARTSAVE-1]: = '0';
SELSTARTSAVE: = SELSTARTSAVE-2;
END;
SELLENGTHSAVE: = 1;
ELSE BEGIN
For i: = sleelstartsave 1 To Selstartsave SelLengthsave DO
IF [1, 2, 4, 5, 7, 8] THEN TEXTSAVE [I]: = '0';
SELLENGTHSAVE: = 1;
END;
Key: = 0;
END;
///
IF (key = vk_up) or (key = vk_down) THEN BEGIN
if Trim (TEXTSAVE) = ':' Then Begin
If TimeFormat = 2 THEN TEXTSAVE: = '00:00'
Else Textsave: = '00:00:00'
ELSE BEGIN
IF key = vk_up then
Case EditingPOS of
1: Textsave: = TimeAdd (Textsave, TimeFormat, 1,0,0);
2: Textsave: = TimeAdd (Textsave, TimeFormat, 0, 1, 0);
3: Textsave: = TimeAdd (Textsave, TimeFormat, 0, 0, 1);
END;
IF key = vk_down then
Case EditingPOS of
1: Textsave: = TimeAdd (Textsave, TimeFormat, -1, 0, 0);
2: Textsave: = TimeAdd (Textsave, TimeFormat, 0, -1, 0);
3: Textsave: = TimeAdd (Textsave, TimeFormat, 0,0, -1);
END;
END;
END;
///
CTL.TEXT: = Textsave;
CTL.SELSTART: = SELSTARTSAVE;
CTL.Sellength: = SELLENGTHSAVE;
END;
The TIMEFORMAT parameter of the above function represents the type of time: 1- Time: Division; 2- Time: Score: Second
To complete the input limit on time, simply call two functions of the MXFORMATTIMEKEYPRESS, MXFORMATTIMEKEYDOWN.
Call example:
(1) Tmaskedit
Procedure TFORM1.MASKEDIT1KEYDOWN (Sender: TOBJECT; VAR Key: Word;
Shift: tshiftstate;
Begin
MxFormattimeKeyDown (Sender As TCUSTOMMASKEDIT, 2, KEY, SHIFT, NIL);
END;
Procedure TFORM1.MASKEDIT1KEYPRESS (Sender: Tobject; VAR Key: char);
Begin
MXFormattimeKeyPress (Sender As TCUSTOMMASKEDIT, 2, KEY, NIL);
END;
And, Tmaskedit's editmask attribute is set to '99: 99 '
(2) TDBEDIT
Procedure TFORM1.DBEDIT1KEYPRESS (Sender: Tobject; Var Key: char);
Begin
MXFormattimeKeyPress (Sender As TCUSTOMMASKEDIT, 2, KEY, (Sender as tdbedit); DataSource
END;
Procedure TFORM1.DBEDIT1KEYDOWN (Sender: Tobject; Var Key: Word;
Shift: tshiftstate;
Begin
MxFormattimeKeyDown (Sender AS TCUSTOMMASKEDIT, 2, KEY, SHIFT, (Sender as tdbedit); DataSource
END;
After the data source connected in tdbedit is opened, set the editmask property of the connected field to 99:99:
DbEdit1.field.editmask: = '99:99;
(3) input of the date
Use the RX date components TDATEEDIT, TDBDATEEDIT. If you haven't installed yet, please download it on this site.
There is no need to limit the date of the date, just convenient for users' input. That is: the arrow keys can change the corresponding
Date elements because the RX five times. The function is as follows:
Procedure mxspinRxdateEdit; Key: word; shift: tshiftstate;
DTS: TDataSource);
VAR
DateStr, Mark, Str: string;
Markpos1, Markpos2: Integer
Dateord: TDATEORDER;
Dateflag, Step: integer;
OldselStart: Integer;
Begin
IF shift <> [].
IF not (Key In [VK_UP, VK_DOWN]) THEN EXIT;
IF (DTS <> NIL) and (not dts.dataset.act) kiln.
IF (DTS <> nil) and (not dts.dataset.modified) THEN
DTS.DataSet.EDIt;
OldselStart: = edit.selstart;
DateStr: = Edit.editText;
Mark: = GetDatemark (dateStr);
Markpos1: = POS (Mark, DateStr);
Str: = COPY (DateStr, Markpos1 1, Length (datestr) -markpos1); Markpos2: = Markpos1 POS (Mark, Str);
Dateord: = getDateOrder (shortdateformat);
Dateflag: = getDateflag (Markpos1, Markpos2, Edit.selstart, Dateord);
IF key = vk_up then step: = 1
Else if key = vk_down kiln step: = - 1
Else Step: = 0;
Case Dateflag of
1: edit.date: = Incyear (Edit.date, STEP);
2: edit.date: = Incmonth (Edit.date, STEP);
3: edit.date: = incday (edit.date, step);
END;
Edit.selstart: = OldselStart;
END;
This function calls in the component's onkeyDown event, for TDateEdit, the Datasoure parameter is NIL.
Recreate the unit Tooledit and Dateutil that references the RX.
Call example:
Procedure TFORM1.DATEEDIT1KEYDOWN (Sender: TOBJECT; VAR Key: Word;
Shift: tshiftstate;
Begin
MxspinRxDateEdit (Sender As TCUStomdateEdit, Key, Shift, NIL);
END;
Procedure TFORM1.DBDATEEDIT1KEYDOWN (Sender: TOBJECT; VAR Key: Word;
Shift: tshiftstate;
Begin
MxspinRxDateEdit (Sender As TCUStomdateEdit, Key, Shift, (Sender as TdbdateEdit); DataSource
END;
More articles, please visit the three gold homepage http://vip.6to23.com/tianmingxin