⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fccalcedit.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
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 + -