📄 fccalcedit.pas
字号:
begin
if (AllowNull = False) then begin
if cboShowDecimal in CalcOptions.Options then
Text := '0'+decimalseparator
else Text := '0';
end
else Text:='';
// FClearOnNextKey := True;
FDecimalEntered := False;
FSkipTextChangedFlag := False;
end;
procedure TfcCustomCalcEdit.CMTextChanged(var Message: TMessage);
begin
if FSkipTextChangedFlag then exit;
inherited;
end;
procedure TfcCustomCalcEdit.KeyUp(var Key: Word; Shift: TShiftState);
begin
inherited KeyUp(Key, Shift);
if FDropDownCalc <> nil then begin
FDropDownCalc.ResultKeyUp(FDropDownCalc,Key,Shift);
end
else begin
//10/1/2001-Added code to determine whether text can be cleared or not.
if (AllowNull = False) and (Text = '') then begin
FSkipTextChangedFlag := True;
if cboShowDecimal in CalcOptions.Options then Text := '0'+decimalseparator
else Text := '0';
FSkipTextChangedFlag := False;
SelectAll;
end;
end;
end;
procedure TfcCustomCalcEdit.KeyDown(var Key: Word; Shift: TShiftState);
var c:Char;
function IsValidDigit(Key:Char): boolean;
begin
Result := (key in ['0'..'9',',','.'])
or (((ord(key) >= VK_NUMPAD0) and (ord(key) <= VK_NUMPAD9)) or (ord(key)=VK_DECIMAL));
end;
function IsValidSpecialChar(Key:Word): boolean;
begin
Result := (key=vk_back) or (key=vk_delete) or (key=vk_escape);
end;
begin
if FClearOnNextKey and (key in [vk_next,vk_prior,vk_left,vk_right,vk_up,vk_down,vk_f2]) then begin
if (not (fcIsInwwGrid(Self)) and (not isDroppedDown)) then key:=0;
end;
inherited KeyDown(Key, Shift);
c:=char(Key);
if Key=vk_Return then
c := '='
else if isDroppedDown and (IsValidSpecialChar(Key)) then begin
if FDropDownCalc <> nil then
FDropDownCalc.ResultKeyDown(FDropDownCalc,key,shift);
end
else begin
//Code := MapVirtualKey(Key, 2);
//c:=char(code);
// 3/1/2002-PYW-Use new function to handle num pad keys in windows 98.
c := fcMessageCodeToChar( key );
if c='R' then c:='r'
else if c='M' then c:='m'
else if c='P' then c:='p'
else if (ssShift in Shift) then begin
case c of
'=':c:='+';
'2':c:='@';
'5':c:='%';
'8':c:='*';
'-':c:='_';
end;
end;
end;
if IsValidOperator(c) or (isValidDigit(c) and isDroppedDown) then begin
if not isDroppedDown and not ((c='=') and (cboCloseOnEquals in CalcOptions.Options) ) then begin
if (Text <> '') then begin
DropDown;
if (FDropDownCalc <> nil) then begin
FDropDownCalc.ResultKeyDown(FDropDownCalc,Key,Shift);
sleep(100);
FDropDownCalc.ResultKeyUp(FDropDownCalc,Key,Shift);
end;
end;
// FClearOnNextKey := True;
end
else begin
// 2/28/2002-PYW-Make sure calculator gets the equals. Otherwise in some cases
// the clearonnextkey flag in the calculator can get mismatched.
if (c='=') and (cboCloseOnEquals in CalcOptions.Options) then
begin
if not isDroppedDown then SelectAll
else CloseUp(True)
end
else if {((c<>'='))and }(FDropDownCalc <> nil) then
FDropDownCalc.ResultKeyDown(FDropDownCalc,Key,Shift);
{ if (c='=') then begin
SelectAll;//SelStart := Length(Text);
if (cboCloseOnEquals in CalcOptions.Options) then CloseUp(True)
else begin
if (FDropDownCalc <> nil) and (Text <> '') then begin
if ((not FDropDownCalc.LastOperatorEquals)
and (FDropDownCalc.LastOp <> btNone)) then begin
key := vk_return;
FDropDownCalc.ResultKeyDown(FDropDownCalc,key,[]);
end;
end;
end;
end;}
end;
Key := 0;
end;
(* if {(key=vk_Delete) or} (key=vk_escape) then begin
//Clear the displayed number.
Text := '0';
//Treat vk_Escape as C key like the windows calculator.
//The C key clears the current calculation.
if (FLastOperator = char(#0)) or (key=vk_Escape) then begin
ResetCalculator;
end;
SelectAll;
Key := 0;
end;
//Handle Memory Keys....
if not (ssCtrl in Shift) or (Text = '') then exit;
try
curValue := StrToFloat(Text);
except
curValue := 0;
end;
if (ssCtrl in Shift) and ((key = ord('M')) or (key=ord('m'))) then
FMemoryValue := curValue;
if (ssCtrl in Shift) and ((key = ord('L')) or (key=ord('l'))) then
FMemoryValue := 0.0;
if (ssCtrl in Shift) and ((key = ord('P')) or (key=ord('p'))) then
FMemoryValue := FMemoryValue + CurValue;
if (ssCtrl in Shift) and ((key = ord('R')) or (key=ord('r'))) then
begin
Text := FloatToStr(FMemoryValue);
end;
*)
end;
procedure TfcCustomCalcEdit.KeyPress(var Key: Char);
var temp:string;
prevselstart,startlength:integer;
testfloat:Extended;
function IsValidDigit(Key:Char): boolean;
begin
Result := (key in ['0'..'9',',','.'])
or ((ord(key) >= VK_NUMPAD0) and (ord(key) <= VK_NUMPAD9));
end;
function IsValidCalcChar(Key:Char): boolean;
begin
result:= isValidDigit(Key) or (key=#13) or
(key = #8) or (key=#46) or (Key=#27) or
isValidOperator(Key)
end;
function DecimalInStr: boolean;
begin
result := false;
if Pos(DecimalSeparator,Text)>0 then
result := true;
end;
function getfstr(val:extended):string;
var s,fmtstr:string;
i,places:integer;
begin
if Frac(val)=0 then //(Val - Trunc(Val)) = 0.0 then
result := FormatFloat('#,##0',Val)
else begin
// Limit to 15 significant digits
s:= FloatToStrF(Val, ffFixed, 15, 15);
// Now val is accurate to 15 digits precision, so now lets get it in our format
Val:= StrtoFloat(s);
s:= FormatFloat('#.##############', Val);
places := length(s)-pos(DecimalSeparator,S);
fmtstr := '#,##0.';
for i:=1 to places do
fmtstr := fmtstr+'0';
result := FormatFloat(fmtstr,Val);
end;
end;
begin
inherited KeyPress(Key);
//2/28/2002 - Clear DecimalEntered if Text Selected.
if SelLength > 0 then
begin
FDecimalEntered := False;
if (key<>#13) and ((cboCloseOnEquals in CalcOptions.Options) and (key<>'=')) then SelText:=''; //8/15/2002
end;
//8/15/2002 - Make sure FDecimalEntered is False if there is no Decimal in the String.
if not DecimalInStr then
FDecimalEntered := False;
if isDroppedDown then begin
if (Key<>#0) then SetModified(True) { RSW };
key:=#0;
exit;
end;
case Key of
'.',',':
if (Key='.') or (Key=',') then begin
if FClearOnNextKey then begin
FSkipTextChangedFlag := True;
Text:='';
FSkipTextChangedFlag := False;
FClearOnNextKey := False;
FDecimalEntered := False;
end;
//10/01/2001-Added check to see if current value is 0 then start text with 0 followed by decimal
if (not FDecimalEntered) {or (not DecimalInStr)} or (fcstrtofloat(text) = 0.0) then begin
FDecimalEntered := True;
if (Text = '') or (fcstrtofloat(text) = 0.0) then begin
Text := '0'+decimalseparator;
SelStart := Length(Text);
Key := #0;
end
else begin
if not Decimalinstr then Key := DecimalSeparator
else begin
selstart := Length(Text);
Key:=#0;
end;
if False and (cboDigitGrouping in CalcOptions.Options) then begin
prevselstart:=selstart;
temp := Copy(Text,1,selstart)+Key+Copy(Text,selstart+sellength+1,length(text)-(selstart+SelLength));
FSkipTextChangedFlag := True;
if not ((DecimalInStr) and ((Key = '0') or (Key=#96))) then begin
startlength := length(Temp);
Text := getfstr(fcStrToFloat(Temp))
end
else Text := Text+'0';
SetModified(True);
SelStart := prevselstart+1;//length(Text);
if startlength <> length(Text) then selstart := selstart+1;
FSkipTextChangedFlag := False;
Key:=#0;
end
end;
end
else begin
Key := #0;
Beep;
end;
end;
#8: begin
if (cboDigitGrouping in CalcOptions.Options) then begin
prevselstart:=selstart;
temp := Copy(Text,1,selstart-1)+Copy(Text,selstart+sellength+1,length(text)-(selstart+SelLength));
FSkipTextChangedFlag := True;
if (AnsiPos(DecimalSeparator,Temp)> 0) and
(AnsiPos(DecimalSeparator,Temp)< selstart) then Text := Temp
else begin
Text := getfstr(fcStrToFloat(temp));
DecimalEntered := False;
end;
FSkipTextChangedFlag := True;
SelStart := prevSelStart-1;
if SelStart=0 then selstart := 1;
SetModified(True);
Key:=#0;
end;
//2/28/2002 - PYW - Add checks to make sure FDecimalEntered is cleared.
if (sellength=0) and (Copy(Text,Length(Text),1) = DecimalSeparator) then
FDecimalEntered := False;
if (not (DecimalinStr)) then begin
if (cboShowDecimal in CalcOptions.Options) then begin
Text := Text+DecimalSeparator;
selstart:=Length(Text)-1;
end;
FDecimalEntered := False;
end;
end;
{ #46:begin
if True or (cboGrouping in CalcOptions.Options) then begin
prevselstart:=selstart;
temp := Copy(Text,1,selstart)+Copy(Text,selstart+sellength+1,length(text)-(selstart+SelLength));
FSkipTextChangedFlag := True;
Text := getfstr(fcStrToFloat(temp));
FSkipTextChangedFlag := True;
SelStart := prevSelStart;
SetModified(True);
Key:=#0;
end
end;}
'0'..'9':
begin
if FClearOnNextKey then begin
FSkipTextChangedFlag := True;
Text := '';
FDecimalEntered := False;
FSkipTextChangedFlag := False;
end;
FClearOnNextKey := false;
if (cboDigitGrouping in CalcOptions.Options) then begin
prevselstart:=selstart;
temp := Copy(Text,1,selstart)+Key+Copy(Text,selstart+sellength+1,length(text)-(selstart+SelLength));
if not fcStrToFloat2(temp, testFloat,'') then begin
Key:=#0;
exit;
end;
FSkipTextChangedFlag := True;
//12/12/2001-Handle additional Decimal cases when cboShowDecimal in Options.
if ((cboShowDecimal in CalcOptions.options)and not DecimalEntered) then begin
if (selstart = length(Text)) and (DecimalSeparator = Copy(Text,selstart,1)) then begin
Text := Text+Key;
startlength:=length(Temp);
end
else begin
startlength := length(Temp);
Text := getfstr(fcStrToFloat(Temp))
end;
end
else if (not ((DecimalInStr) and ((Key = '0') or (Key=#96)))) then begin
startlength := length(Temp);
Text := getfstr(fcStrToFloat(Temp))
end
else begin
Text := Text+'0';
startlength:=length(Temp);
end;
SetModified(True);
SelStart := prevselstart+1;//length(Text);
if startlength <> length(Text) then selstart := selstart+1;
FSkipTextChangedFlag := False;
Key:=#0;
end;
if (not (DecimalinStr)) then begin
FDecimalEntered := False;
if (cboShowDecimal in CalcOptions.Options) then begin
Text := Text+DecimalSeparator;
selstart:=Length(Text)-1;
end;
end;
end;
{ 'C': // Clear on 'C' character
// #27,#47:
begin
//If a vk_Escape (C) or a vk_delete (CE) was pressed the text needs to be reset to zero.
//Clear the displayed number.
ResetCalculator;
Text := '0';
//Treat vk_Escape as C key like the windows calculator.
//The C key clears the current calculation.
//if ord(key)=vk_Escape then
SelectAll;
Key := #0;
end}
else
begin
Key:=#0;
end;
end;
if (Key<>#0) then SetModified(True) { RSW };
end;
procedure TfcCustomCalcEdit.SetValue(Value:Double);
function getfstr(val:extended):string;
var s,fmtstr:string;
i,places:integer;
begin
if Frac(val)=0 then //(Val - Trunc(Val)) = 0.0 then
result := FormatFloat('#,##0',Val)
else begin
// Limit to 15 significant digits
s:= FloatToStrF(Val, ffFixed, 15, 15);
// Now val is accurate to 15 digits precision, so now lets get it in our format
Val:= StrtoFloat(s);
s:= FormatFloat('#.##############', Val);
places := length(s)-pos(DecimalSeparator,S);
fmtstr := '#,##0.';
for i:=1 to places do
fmtstr := fmtstr+'0';
result := FormatFloat(fmtstr,Val);
end;
end;
begin
if GetValue <> Value then begin
if Focused then begin
if (cboDigitGrouping in CalcOptions.Options) then
Text := getfstr(Value)
else Text := FloatToStr(Value); // Maybe use ---> s:= FormatFloat('#.################', Val);
end
else begin
// Text := FormatFloat(displayFormat,value);
Text := FormatFloat('',value);
end;
end;
end;
function TfcCustomCalcEdit.GetValue: Double;
begin
Result := fcStrToFloat( Text );
end;
procedure TfcCustomCalcEdit.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.Style :=(Params.Style and not (ES_AUTOVSCROLL or ES_WANTRETURN) or
WS_CLIPCHILDREN);
// if UseRightToLeftAlignment or LimitEditRect then
// Params.Style:= Params.Style or ES_MULTILINE;
Params.Style:= Params.Style or ES_WANTRETURN;
Params.ExStyle := Params.ExStyle or WS_EX_RIGHT;
end;
function TfcCustomCalcEdit.IsDroppedDown: Boolean;
begin
result := (fDropDownCalc<>nil) and fDropDownCalc.Visible;
end;
procedure TfcCustomCalcEdit.CMCancelMode(var Message: TCMCancelMode);
begin
if (Message.Sender <> Self) and (Message.Sender <> fDropDownCalc) and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -