cxcalc.pas

来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,899 行 · 第 1/4 页

PAS
1,899
字号
  Color := clBtnFace;
  ParentColor := False;
  TabStop := True;
  FAutoFontSize := True;
  FBorderStyle := bsNone;
  FBeepOnError := True;
  FDownButton := cbNone;
  FActiveButton := cbNone;
  FPressedButton := cbNone;
  FFocusRectVisible := True;
  FOperator := cbEqual;
  FPrecision := cxDefCalcPrecision;
  Keys := [kAll, kArrows, kChars, kTab];
  CreateLayout;
end;

function TcxCustomCalculator.GetButtonKindAt(X, Y : Integer) : TcxCalcButtonKind;
var i : TcxCalcButtonKind;
begin
  Result := cbNone;
  for i := cbBack to cbEqual do
    if PtInRect(FButtons[i].BtnRect, Point(X, Y)) then
    begin
      Result := i;
      Exit;
    end;
end;

function TcxCustomCalculator.GetPainter: TcxCustomLookAndFeelPainterClass;
begin
  Result := TcxStandardLookAndFeelPainter;
end;

procedure TcxCustomCalculator.Paint;
var
  i : TcxCalcButtonKind;
  State: TcxButtonState;
begin
  if not HandleAllocated then Exit;
    with Canvas do
    begin
      {Fill Background}
      Brush.Color := Self.Color;
      if IsPopupControl then
        GetPainter.DrawWindowContent(Self.Canvas, ClientRect)
      else
        GetPainter.DrawWindowContent(Self.Canvas, BoundsRect);
      {Draw buttons}
      Font := Self.Font;
      if AutoFontSize then
      begin
        Font.Size := FCalcFontSize;
        if Font.Size >= cxCalcMinBoldFontSize then
          Font.Style := [fsBold]
        else
          Font.Style := [];
      end;
      Brush.Color := Self.Color;
    end;

    for i := cbBack to cbEqual do
      with FButtons[i] do
      if RectVisible(Canvas.Handle, BtnRect) then
      begin
        if Grayed or not Enabled then State := cxbsDisabled
        else if Down then State := cxbsPressed
        else if (FActiveButton = i) and (FDownButton <> i) then State := cxbsHot
        else if IsFocused and (i = cbEqual) then State := cxbsDefault
        else State := cxbsNormal;
        with GetPainter, Canvas do
        begin
          DrawButton(Self.Canvas, BtnRect, '', State);
          Font.Color := FontColor;
          Brush.Style := bsClear;
          if State = cxbsPressed then
          begin
            OffsetRect(BtnRect, ButtonTextShift, ButtonTextShift);
            DrawText(Text, BtnRect, cxAlignHCenter or cxAlignVCenter or cxSingleLine or
              cxShowPrefix, State <> cxbsDisabled);
            OffsetRect(BtnRect, -ButtonTextShift, -ButtonTextShift);
          end
          else
            DrawText(Text, BtnRect, cxAlignHCenter or cxAlignVCenter or cxSingleLine or
              cxShowPrefix, State <> cxbsDisabled);
          Brush.Style := bsSolid;
        end;
        if FFocusRectVisible and IsFocused and (i = cbEqual) then
        begin
          InflateRect(BtnRect, -3, -3);
          Canvas.DrawFocusRect(BtnRect);
          InflateRect(BtnRect, 3, 3);
        end;
      end;
end;

procedure TcxCustomCalculator.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do
  begin
    Style := Style or WS_TABSTOP or WS_CLIPCHILDREN;
    WindowClass.Style := WindowClass.Style and not CS_DBLCLKS;
    if IsPopupControl then
      Style := Style and not WS_BORDER
    else
      if FBorderStyle = bsSingle then
        if NewStyleControls and Ctl3D then
        begin
          Style := Style and not WS_BORDER;
          ExStyle := ExStyle or WS_EX_CLIENTEDGE;
        end
        else
          Style := Style or WS_BORDER;
  end;
end;

procedure TcxCustomCalculator.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
var ButtonKind : TcxCalcButtonkind;
begin
  if not (csDesigning in ComponentState) and
      (CanFocus or (GetParentForm(Self) = nil)) and not IsPopupControl then
    SetFocus;

  ButtonKind := GetButtonKindAt(X, Y);
  if (Button = mbLeft) and (ButtonKind <> cbNone) and not FButtons[ButtonKind].Grayed then
  begin
    MouseCapture := True;
    FTracking := True;
    FDownButton := ButtonKind;
    TrackButton(X, Y);
  end;
  inherited MouseDown(Button, Shift, X, Y);
end;

procedure TcxCustomCalculator.MouseMove(Shift: TShiftState; X, Y: Integer);
var OldButton : TcxCalcButtonKind;
begin
  if FTracking then
    TrackButton(X, Y)
  else
    if GetPainter.IsButtonHotTrack and Enabled and not Dragging then
    begin
      OldButton := FActiveButton;
      FActiveButton := GetButtonKindAt(X, Y);
      if FActiveButton <> OldButton then
      begin
        if not FButtons[OldButton].Grayed then
          InvalidateButton(OldButton);
        if not FButtons[FActiveButton].Grayed then
          InvalidateButton(FActiveButton);
      end;
    end;
  inherited MouseMove(Shift, X, Y);
end;

procedure TcxCustomCalculator.MouseUp(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
var
  WasPressed: Boolean;
begin
  WasPressed := (FDownButton <> cbNone) and FButtons[FDownButton].Down;
  StopTracking;
  if (Button = mbLeft) and WasPressed then
    ButtonClick(FDownButton);
  FDownButton := cbNone;
  inherited MouseUp(Button, Shift, X, Y);
end;

procedure TcxCustomCalculator.KeyDown(var Key: Word; Shift: TShiftState);
var
  NewButton, OldButton : TcxCalcButtonKind;
begin
  inherited KeyDown(Key, Shift);
  OldButton := FPressedButton;
  NewButton := GetButtonKindKey(Key, Shift);
  if (NewButton <> cbNone) and (OldButton <> NewButton) then
  begin
    DoButtonUp(OldButton);
    FPressedButton := NewButton;
    DoButtonDown(FPressedButton);
  end;
end;

procedure TcxCustomCalculator.KeyPress(var Key: Char);
var
  NewButton, OldButton : TcxCalcButtonKind;
begin
  inherited KeyPress(Key);
  if (Key = ^V) then
    PasteFromClipboard
  else
    if (Key = ^C) then CopyToClipboard;

  OldButton := FPressedButton;
  NewButton := GetButtonKindChar(Key);
  if (NewButton <> cbNone) and (OldButton <> NewButton) then
  begin
    DoButtonUp(OldButton);
    FPressedButton := NewButton;
    DoButtonDown(FPressedButton);
  end;
  if FPressedButton in RepeatButtons {cbBack} then ButtonClick(FPressedButton);
end;

procedure TcxCustomCalculator.KeyUp(var Key: Word; Shift: TShiftState);
begin
  inherited KeyUp(Key, Shift);
  DoButtonUp(FPressedButton);
end;

procedure TcxCustomCalculator.Resize;
begin
  CalcSize(ClientWidth, ClientHeight);
  ClientWidth := FCalcWidth;
  ClientHeight := FCalcHeight;
  inherited;
end;

procedure TcxCustomCalculator.DoButtonDown(ButtonKind : TcxCalcButtonKind);
begin
  if ButtonKind <> cbNone then
  begin
    FButtons[ButtonKind].Down := True;
    InvalidateButton(ButtonKind);
    Update;
    if not (ButtonKind in RepeatButtons) {cbBack} then ButtonClick(ButtonKind);
  end;
end;

procedure TcxCustomCalculator.DoButtonUp(ButtonKind : TcxCalcButtonKind);
begin
  if ButtonKind <> cbNone then
  begin
    FButtons[ButtonKind].Down := False;
    InvalidateButton(ButtonKind);
    FPressedButton := cbNone;
    Update;
  end;
end;

function TcxCustomCalculator.GetEditorValue: String;
begin
  Result := '';
end;

procedure TcxCustomCalculator.SetEditorValue(const Value: String);
begin
end;

procedure TcxCustomCalculator.CreateLayout;
const
  BtnColors : array [cbBack..cbEqual] of TColor = (clMaroon, clMaroon, clMaroon,
    clRed, clRed, clRed, clRed,
    clBlue, clBlue, clBlue, clBlue, clBlue, clBlue, clBlue, clBlue, clBlue, clBlue,
    clBlue, clBlue,
    clRed, clRed, clRed, clRed,
    clNavy, clNavy, clNavy, clRed);
var i : TcxCalcButtonKind;
    X : Integer;
begin
  for i := cbBack to cbEqual do
  begin
    FButtons[i].Kind := i;
    FButtons[i].Text := BtnCaptions[i];
    if i = cbDecimal then FButtons[i].Text := SysUtils.DecimalSeparator
    else  FButtons[i].Text := BtnCaptions[i];
    FButtons[i].FontColor := BtnColors[i];
    FButtons[i].BtnRect := cxEmptyRect;
    FButtons[i].Down := False;
    FButtons[i].Grayed := False;
  end;
  {coord buttons}
  FButtons[cbMC].BtnRect := Rect(FCalcXOfs,
                                 (FCalcYOfs+FCalcBtnHeight)+FCalcYOfs,
                                 FCalcXOfs+FCalcBtnWidth,
                                 (FCalcYOfs+FCalcBtnHeight)*2);
  FButtons[cbMR].BtnRect := Rect(FCalcXOfs,
                                 (FCalcYOfs+FCalcBtnHeight)*2+FCalcYOfs,
                                 FCalcXOfs+FCalcBtnWidth,
                                 (FCalcYOfs+FCalcBtnHeight)*3);
  FButtons[cbMS].BtnRect := Rect(FCalcXOfs,
                                 (FCalcYOfs+FCalcBtnHeight)*3+FCalcYOfs,
                                 FCalcXOfs+FCalcBtnWidth,
                                 (FCalcYOfs+FCalcBtnHeight)*4);
  FButtons[cbMP].BtnRect := Rect(FCalcXOfs,
                                 (FCalcYOfs+FCalcBtnHeight)*4+FCalcYOfs,
                                 FCalcXOfs+FCalcBtnWidth,
                                 (FCalcYOfs+FCalcBtnHeight)*5);
  X := FCalcXOfs+FCalcBtnWidth + FCalcXOfs + 4;
  {7, 8, 9, /, sqrt}
  FButtons[cbNum7].BtnRect := Rect(X+FCalcXOfs,
                                   (FCalcYOfs+FCalcBtnHeight)+FCalcYOfs,
                                   X+FCalcXOfs+FCalcBtnWidth,
                                   (FCalcYOfs+FCalcBtnHeight)*2);
  FButtons[cbNum8].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth),
                                   (FCalcYOfs+FCalcBtnHeight)+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*2,
                                   (FCalcYOfs+FCalcBtnHeight)*2);
  FButtons[cbNum9].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*2,
                                   (FCalcYOfs+FCalcBtnHeight)+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*3,
                                   (FCalcYOfs+FCalcBtnHeight)*2);
  FButtons[cbDiv].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*3,
                                   (FCalcYOfs+FCalcBtnHeight)+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*4,
                                   (FCalcYOfs+FCalcBtnHeight)*2);
  FButtons[cbSqrt].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*4,
                                   (FCalcYOfs+FCalcBtnHeight)+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*5,
                                   (FCalcYOfs+FCalcBtnHeight)*2);

  {4, 5, 6, *, %}
  FButtons[cbNum4].BtnRect := Rect(X+FCalcXOfs,
                                  (FCalcYOfs+FCalcBtnHeight)*2+FCalcYOfs,
                                   X+FCalcXOfs+FCalcBtnWidth,
                                 (FCalcYOfs+FCalcBtnHeight)*3);
  FButtons[cbNum5].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth),
                                  (FCalcYOfs+FCalcBtnHeight)*2+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*2,
                                 (FCalcYOfs+FCalcBtnHeight)*3);
  FButtons[cbNum6].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*2,
                                  (FCalcYOfs+FCalcBtnHeight)*2+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*3,
                                 (FCalcYOfs+FCalcBtnHeight)*3);
  FButtons[cbMul].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*3,
                                  (FCalcYOfs+FCalcBtnHeight)*2+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*4,
                                 (FCalcYOfs+FCalcBtnHeight)*3);
  FButtons[cbPercent].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*4,
                                  (FCalcYOfs+FCalcBtnHeight)*2+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*5,
                                 (FCalcYOfs+FCalcBtnHeight)*3);

  {1, 2, 3, -, 1/x}
  FButtons[cbNum1].BtnRect := Rect(X+FCalcXOfs,
                                  (FCalcYOfs+FCalcBtnHeight)*3+FCalcYOfs,
                                   X+FCalcXOfs+FCalcBtnWidth,
                                 (FCalcYOfs+FCalcBtnHeight)*4);
  FButtons[cbNum2].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth),
                                  (FCalcYOfs+FCalcBtnHeight)*3+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*2,
                                 (FCalcYOfs+FCalcBtnHeight)*4);
  FButtons[cbNum3].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*2,
                                  (FCalcYOfs+FCalcBtnHeight)*3+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*3,
                                 (FCalcYOfs+FCalcBtnHeight)*4);
  FButtons[cbSub].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*3,
                                  (FCalcYOfs+FCalcBtnHeight)*3+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*4,
                                 (FCalcYOfs+FCalcBtnHeight)*4);
  FButtons[cbRev].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*4,
                                  (FCalcYOfs+FCalcBtnHeight)*3+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*5,
                                 (FCalcYOfs+FCalcBtnHeight)*4);

  {0, +/-, ., +, =}
  FButtons[cbNum0].BtnRect := Rect(X+FCalcXOfs,
                                  (FCalcYOfs+FCalcBtnHeight)*4+FCalcYOfs,
                                   X+FCalcXOfs+FCalcBtnWidth,
                                 (FCalcYOfs+FCalcBtnHeight)*5);
  FButtons[cbSign].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth),
                                  (FCalcYOfs+FCalcBtnHeight)*4+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*2,
                                 (FCalcYOfs+FCalcBtnHeight)*5);
  FButtons[cbDecimal].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*2,
                                  (FCalcYOfs+FCalcBtnHeight)*4+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*3,
                                 (FCalcYOfs+FCalcBtnHeight)*5);
  FButtons[cbAdd].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*3,
                                  (FCalcYOfs+FCalcBtnHeight)*4+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*4,
                                 (FCalcYOfs+FCalcBtnHeight)*5);
  FButtons[cbEqual].BtnRect := Rect(X+FCalcXOfs+(FCalcXOfs+FCalcBtnWidth)*4,
                                  (FCalcYOfs+FCalcBtnHeight)*4+FCalcYOfs,
                                   X+(FCalcXOfs+FCalcBtnWidth)*5,
                                 (FCalcYOfs+FCalcBtnHeight)*5);
  {C}
  FButtons[cbClear].BtnRect := FButtons[cbEqual].BtnRect;
  FButtons[cbClear].BtnRect.Left := FButtons[cbClear].BtnRect.Right - FCalcLargeBtnWidth;
  FButtons[cbClear].BtnRect.Top := FCalcYOfs;
  FButtons[cbClear].BtnRect.Bottom := FCalcYOfs + FCalcBtnHeight;
  {CE}
  FButtons[cbCancel].BtnRect := FButtons[cbClear].BtnRect;
  FButtons[cbCancel].BtnRect.Right := FButtons[cbClear].BtnRect.Left - FCalcYOfs;
  FButtons[cbCancel].BtnRect.Left := FButtons[cbCancel].BtnRect.Right - FCalcLargeBtnWidth;
  {Back}
  FButtons[cbBack].BtnRect := FButtons[cbCancel].BtnRect;
  FButtons[cbBack].BtnRect.Right := FButtons[cbBack].BtnRect.Left - FCalcYOfs;
  FButtons[cbBack].BtnRect.Left := FButtons[cbBack].BtnRect.Right - FCalcLargeBtnWidth;
  // ResetOperands;
  ResetOperands;
  // Update Memory display
  UpdateMemoryButtons;
end;

procedure TcxCustomCalculator.ResetOperands;
begin
  FOperator := cbEqual;
  FStatus := csFirst;
  FMemory := 0.0;
end;

procedure TcxCustomCalculator.SetBorderStyle(Value: TBorderStyle);
begin
  if FBorderStyle <> Value then
  begin
    FBorderStyle := Value;
    RecreateWnd;
  end;
end;

procedure TcxCustomCalculator.SetFocusRectVisible(Value : Boolean);
begin
  if FFocusRectVisible <> Value then
  begin
    FFocusRectVisible := Value;
    Invalidate;
  end;
end;

procedure TcxCustomCalculator.CalcSize(AWidth, AHeight : Integer);
var
  h, NearHeight, d, dMin : Integer;

  function CalcHeight(ABtnHeight:Integer):Integer;
  var FYOfs : Integer;
  begin
    FYOfs := MulDiv(ABtnHeight, cxMinCalcYOfs, cxMinCalcBtnHeight);
    Result := (FYOfs + ABtnHeight) * 5 + FYOfs;
  end;

begin
  if AutoFontSize then
  begin
    h := MulDiv(AWidth, cxMinCalcHeight, cxMinCalcWidth);
    if AHeight > h then AHeight := h;
    {Calculate nearest FCalcHeight }
    h := cxMinCalcBtnHeight;
    NearHeight := h;
    dMin := AHeight;
    while True do
    begin
      d := abs(CalcHeight(h) - AHeight);
      if d < dMin then
      begin
        dMin := d;
        NearHeight := h;
      end
      else
        Break;
      inc(h);
    end;
  end
  else
    NearHeight := Canvas.FontHeight(Font) * 2;
  FCalcBtnHeight     := NearHeight;
  FCalcBtnWidth      := MulDiv(FCalcBtnHeight, cxMinCalcBtnWidth, cxMinCalcBtnHeight);
  FCalcYOfs          := MulDiv(FCalcBtnHeight, cxMinCalcYOfs, cxMinCalcBtnHeight);
  FCalcXOfs          := FCalcYOfs;
  FCalcLargeBtnWidth := MulDiv(FCalcBtnWidth, 17, 10);
  FCalcFontSize      := MulDiv(FCalcBtnHeight, cxMinCalcFontSize, cxMinCalcBtnHeight);
  FCalcHeight        := (FCalcYOfs+FCalcBtnHeight)*5+FCalcYOfs;
  FCalcWidth         := (FCalcXOfs+FCalcBtnWidth)*6+FCalcXOfs*2+4;
  // reCalc rect buttons
  CreateLayout;
end;

procedure TcxCustomCalculator.FontChanged;
begin
  if not (csLoading in ComponentState) then ParentFont := False;
  inherited FontChanged;
end;

procedure TcxCustomCalculator.FocusChanged;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?