限制並方便用戶輸入(2002/12/03 三金 版權所有)
防止用戶誤輸入是軟件開發的一項必不可少的工作,除才之外,還要為用戶
的使用提供最大方便。當然,我們可以利用或開發新的組件,以完成這些功能。
但是,在團隊開發中,每個成員都用自己認為不錯的組件開發自己所承擔的模
塊,會給軟件的後期維護帶來麻煩。交工的時候,項目負責人可不買你的帳。如
果你用函數調用來完成這些功能,老蓋也管不著。下面就是針對常用delphi組件
的限制用戶輸入函數,但願網友們能用的上。
(一)TEdit、TDBEdit、TComboBox、TDBComboBox的輸入
分三種類型限制:
(1)任意輸入
(2)整數輸入
(3)浮點數輸入
限制的項目如下:
(1)整數輸入只能輸入數字0-9、+、-
(2)浮點輸入只能輸入數字0-9、+、-、.
(3)+和-只能有其一,並且只能出現在最前面
(4).只能有一個
(5)限制小數位數
函數如下:
procedure MxFormatKeyPress(Text:string;SelStart,SelLength:integer;
var Key:Char;EditType:integer;Digits:integer);
begin
if (Key=#27) or (Key=#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;
//控制+-
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;
//控制.
if (Key = .) and (EditType=3 ) then begin
if (Pos(.,Text) > 0) and (not((SelStart
if SelStart=0 then Key:=#0;
if (Digits>0) and (SelStart+SelLength
if (pos(.,Text )>0 ) and (SelStart>=pos(.,Text)) then
if length(Text)-pos(.,Text )>=Digits then Key:=#0;
end;
此函數在所限制組件的OnKeyPress事件中調用。Key即為OnKeyPress攜帶的
Key:Char參數;EditType為限制的類型:1-任意輸入;2-整數輸入;3-浮點輸入;
Digits為浮點數輸入時小數的位數,如果是零,則可輸入任意位數。另外,此
函數只適用於有Text、SelStart、SelLength等屬性的TWinControl類的派生類。
具體限制各組件的二級函數如下:
限制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;
限制TComboBox:
procedure MxFormatComboKeyPress(Combo:TComboBox;var Key:Char;EditType:integer;
Digits:integer);
begin
MxFormatKeyPress(Combo.Text,Combo.SelStart,Combo.SelLength,Key,EditType,Digits);
end;
限制TDBComboBox:
procedure MxFormatDBComboKeyPress(Combo:TDBComboBox;var Key:Char;
EditType:integer;Digits:integer);
begin
MxFormatKeyPress(Combo.Text,Combo.SelStart,Combo.SelLength,Key,EditType,Digits);
end;
調用示例:
假如Form1上有一ComboBox1,讓用戶只輸入浮點數,並且小數位數為兩位。則
可以在ComboBox1的OnKeyPress事件中調用上面的函數,代碼如下:
procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char);
begin
MxFormatComboKeyPress(Combobox1,Key,3,0);
end;
如果你的窗體上有多各TComboBox,並且限制類型一致,則不必每個TComboBox都
書寫代碼,只需為其中一個編寫事件處理代碼,其它作連接即可。
procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char);
begin
MxFormatComboKeyPress(Sender as TComboBox,Key,3,0);
end;
其它組件調用方法同上。
(二)時間的輸入
限制類型:
(1)時分
(2)時分秒
組件采用TMaskEdit,數據敏感采用TDBEdit。
限制項目如下:
(1)小時只能輸入0-23
(2)分鐘不超過59
(3)秒不超過59
(4)用戶只能全刪,而不能只刪某一位數據
(5)箭頭鍵可以更改時間
需要在組件的OnKeyPress和OnKeyDown事件中分別書寫代碼。
procedure MxFormatTimeKeyPress(ctl:TCustomMaskEdit;TimeFormat:integer;
var Key:Char;dts:TDataSource);
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 ) then exit;
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]) then CharValid := False;
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])) then CharValid := False;
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 then begin
Key:=#0;exit;
end;
if dts<>nil then dts.DataSet.Edit;
if not (SelStartSave in [2,5]) then TextSave[SelStartSave+1]:=Key;
if SelLengthSave>1 then begin
for i:=SelStartSave+2 to SelStartSave+SelLengthSave do
if i in [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 ) ) then
TextSave[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;
//此函數分割時間,因為有時候會遇到非法的時間字符串,所以不采用DecodeTime。
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;
//此函數檢查字符串是否為合法的時間
function TimeValid(TimeStr:string;TimeFormat:integer):boolean;