本文共 10842 字,大约阅读时间需要 36 分钟。
=Pos('.',Text) ))) then Key:=#0;
if SelStart=0 then Key:=#0; if (Digits>0) and (SelStart+SelLength0) and (EditType=3) then 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: T; 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:TData);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 EditingPof 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;varh,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 (strtoint(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; exit; end;end;//此函数对时分秒进行加减运算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;//时分秒加减运算的二级函数function TimeAdd(TimeStr:string;TimeFormat:integer; HStep,MStep,SStep:integer):string;var dt:Tdatetime;begin if not TimeValid(TimeStr,TimeFormat) then 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;//限制组件的OnKeyDownprocedure MxFormatTimeKeyDown(ctl:TCustomMaskEdit;TimeFormat:integer; var Key:;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 ) then exit; if not (Key in [vk_delete,vk_back,vk_up,vk_down] ) then exit; if (dts<>nil ) and (not dts.DataSet.Active ) then exit; 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 EditingPos:=TimeFormat; if Key=vk_delete then begin if SelLengthSave=length(TextSave) then TextSave:='' else begin if not (SelStartSave in [2,5]) then TextSave[SelStartSave+1]:='0'; 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; end; Key:=0; end; if Key=vk_back then begin if SelLengthSave=length(TextSave) then TextSave:='' else if SelLengthSave<=1 then begin if not (SelStartSave in [3,6]) then begin TextSave[SelStartSave]:='0'; SelStartSave:=SelStartSave-1; end else begin TextSave[SelStartSave-1]:='0'; SelStartSave:=SelStartSave-2; end; SelLengthSave:=1; end else begin for i:=SelStartSave+1 to SelStartSave+SelLengthSave do if i in [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' end 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;以上函数的TimeFormat参数代表时间的类型:1-时:分;2-时:分:秒要完成对时间的输入限制,只需调用上面的MxFormatTimeKeyPress,MxFormatTimeKeyDown两个函数。调用示例:(1)TMaskEditprocedure 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;并且,TMaskEdit的EditMask属性设为'99:99'(2)TDBEditprocedure 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;在TDBEdit所连接的数据源打开后,设定所连字段的EditMask属性为99:99: DBEdit1.Field.EditMask :='99:99';(三)日期的输入采用Rx的日期组件TDateEdit、TDBDateEdit。如果你还没,请在本站。无需对日期的输入作限制,只需方便用户的输入。即:箭头键可以改变相应的日期元素,因为Rx五次功能。函数如下:procedure MxSpinRxDateEdit(Edit:TCustomDateEdit;Key:word;Shift:TShiftState; dts:TDataSource);var DateStr,Mark,str:string; MarkPos1,MarkPos2:integer; DateOrd:TDateOrder; DateFlag,step:integer; OldSelStart:integer;begin if Shift<>[] then exit; if not (Key in [vk_up,vk_down] ) then exit; if (dts<>nil ) and (not dts.DataSet.Active ) then exit; 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 then 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;此函数在组件的OnKeyDown事件中调用,对于TDateEdit,DataSoure参数为nil。记着引用Rx的单元ToolEdit和DateUtil。调用示例: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;更多文章请访问三金主页
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10748419/viewspace-976161/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/10748419/viewspace-976161/