cxcalc.pas

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

PAS
1,899
字号

{********************************************************************}
{                                                                    }
{       Developer Express Visual Component Library                   }
{       ExpressEditors                                               }
{                                                                    }
{       Copyright (c) 1998-2008 Developer Express Inc.               }
{       ALL RIGHTS RESERVED                                          }
{                                                                    }
{   The entire contents of this file is protected by U.S. and        }
{   International Copyright Laws. Unauthorized reproduction,         }
{   reverse-engineering, and distribution of all or any portion of   }
{   the code contained in this file is strictly prohibited and may   }
{   result in severe civil and criminal penalties and will be        }
{   prosecuted to the maximum extent possible under the law.         }
{                                                                    }
{   RESTRICTIONS                                                     }
{                                                                    }
{   THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES            }
{   (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE     }
{   SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS    }
{   LICENSED TO DISTRIBUTE THE EXPRESSEDITORS AND ALL                }
{   ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
{                                                                    }
{   THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED       }
{   FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE         }
{   COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE        }
{   AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT   }
{   AND PERMISSION FROM DEVELOPER EXPRESS INC.                       }
{                                                                    }
{   CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON        }
{   ADDITIONAL RESTRICTIONS.                                         }
{                                                                    }
{********************************************************************}

unit cxCalc;

{$I cxVer.inc}

interface

uses
  Windows, Messages,
  SysUtils, Classes, Graphics, Controls, Forms, StdCtrls, Clipbrd,
  cxClasses, cxControls, cxContainer, cxGraphics, cxDataStorage, cxDataUtils,
  cxButtons, cxEdit, cxDropDownEdit, cxEditConsts, cxFormats, cxLookAndFeelPainters,
  cxTextEdit, cxFilterControlUtils;

const
  cxMaxCalcPrecision     = cxEditDefaultPrecision;
  cxDefCalcPrecision     = cxMaxCalcPrecision;
  // Size
  cxMinCalcFontSize      = 8;
  cxCalcMinBoldFontSize  = 10;
  cxMinCalcBtnWidth      = 28;
  cxMinCalcBtnHeight     = 22;
  cxMinCalcLargeBtnWidth = Integer(Trunc(1.7*cxMinCalcBtnWidth));
  cxMinCalcXOfs          = 3;
  cxMinCalcYOfs          = 3;
  cxMinCalcWidth         = (cxMinCalcXOfs+cxMinCalcBtnWidth)*6+cxMinCalcXOfs*3+3;
  cxMinCalcHeight        = (cxMinCalcYOfs+cxMinCalcBtnHeight)*5+cxMinCalcYOfs+3;

type
  TcxCalcState = (csFirst, csValid, csError);

  TcxCalcButtonKind =
   (cbBack, cbCancel, cbClear,
    cbMC, cbMR, cbMS, cbMP,
    cbNum0, cbNum1, cbNum2, cbNum3, cbNum4, cbNum5, cbNum6, cbNum7, cbNum8, cbNum9,
    cbSign, cbDecimal,
    cbDiv, cbMul, cbSub, cbAdd,
    cbSqrt, cbPercent, cbRev, cbEqual, cbNone);

const
  BtnCaptions : array [cbBack..cbEqual] of string[4] = ('Back', 'CE', 'C',
    'MC', 'MR', 'MS', 'M+',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    '+/-', ',', '/', '*', '-', '+', 'sqrt', '%', '1/x', '=');

type
  TcxButtonInfo = record
    Kind : TcxCalcButtonKind;
    Text : String[4];
    FontColor : TColor;
    BtnRect : TRect;
    Down : Boolean;
    Grayed : Boolean;
  end;

  TCalcButtons = array [TcxCalcButtonKind] of TcxButtonInfo;

  { TcxCustomCalculator }

  TcxCalcButtonClick = procedure(Sender: TObject; var ButtonKind : TcxCalcButtonKind) of object;
  TcxCalcGetEditValue = procedure(Sender: TObject; var Value : String) of object;
  TcxCalcSetEditValue = procedure(Sender: TObject; const Value : String) of object;

  TcxCustomCalculator = class(TcxControl)
  private
    {calc style}
    FAutoFontSize : Boolean;
    FBeepOnError: Boolean;
    FBorderStyle : TBorderStyle;
    FFocusRectVisible : Boolean;
    {calc size}
    FCalcFontSize      : Integer;
    FCalcBtnWidth      : Integer;
    FCalcBtnHeight     : Integer;
    FCalcLargeBtnWidth : Integer;
    FCalcXOfs          : Integer;
    FCalcYOfs          : Integer;
    FCalcWidth         : Integer;
    FCalcHeight        : Integer;
    {math}
    FMemory : Extended;
    FOperator: TcxCalcButtonKind;
    FOperand: Extended;
    FPrecision: Byte;
    FStatus: TcxCalcState;
    {control}
    FButtons : TCalcButtons;
    FActiveButton : TcxCalcButtonKind;
    FDownButton : TcxCalcButtonKind;
    FPressedButton : TcxCalcButtonKind;
    FTracking: Boolean;
    // events
    FOnDisplayChange: TNotifyEvent;
    FOnButtonClick: TcxCalcButtonClick;
    FOnResult: TNotifyEvent;
    FOnHidePopup: TcxEditClosePopupEvent;

    function GetDisplay: Extended;
    procedure SetDisplay(Value: Extended);
    function GetMemory: Extended;

    procedure SetAutoFontSize(Value : Boolean);
    procedure SetBorderStyle(Value: TBorderStyle);
    procedure SetFocusRectVisible(Value : Boolean);

    procedure StopTracking;
    procedure TrackButton(X,Y: Integer);
    procedure InvalidateButton(ButtonKind : TcxCalcButtonKind);
    procedure DoButtonDown(ButtonKind : TcxCalcButtonKind);
    procedure DoButtonUp(ButtonKind : TcxCalcButtonKind);
    procedure Error;
    procedure CheckFirst;
    procedure Clear;
    procedure CalcSize(AWidth, AHeight : Integer);
    procedure UpdateMemoryButtons;
    procedure InvalidateMemoryButtons;
    procedure ResetOperands;
  protected
    IsPopupControl : Boolean;
    function GetPainter: TcxCustomLookAndFeelPainterClass; virtual;
    procedure Paint; override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure FontChanged; override;
    procedure FocusChanged; override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseLeave(AControl: TControl); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
    procedure KeyUp(var Key: Word; Shift: TShiftState); override;
    procedure Resize; override;
    procedure SetEnabled( Value: Boolean); override;
    procedure CreateLayout;
    procedure ButtonClick(ButtonKind : TcxCalcButtonKind);
    // for link with EditControl
    function GetEditorValue: String; virtual;
    procedure SetEditorValue(const Value: String); virtual;
    procedure HidePopup(Sender: TcxControl; AReason: TcxEditCloseUpReason); virtual;

    property Color default clBtnFace;
    property ParentColor default False;
    property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle
      default bsNone;

    property AutoFontSize : Boolean read FAutoFontSize write SetAutoFontSize
      default True;
    property BeepOnError: Boolean read FBeepOnError write FBeepOnError
      default True;
    property ShowFocusRect : Boolean
      read FFocusRectVisible write SetFocusRectVisible default True;

    property Precision: Byte read FPrecision write FPrecision
      default cxDefCalcPrecision;
    property EditorValue : string read GetEditorValue write SetEditorValue;

    property OnHidePopup: TcxEditClosePopupEvent read FOnHidePopup write FOnHidePopup;
    property OnDisplayChange: TNotifyEvent
      read FOnDisplayChange write FOnDisplayChange;
    property OnButtonClick: TcxCalcButtonClick
      read FOnButtonClick write FOnButtonClick;
    property OnResult: TNotifyEvent read FOnResult write FOnResult;
  public
    constructor Create(AOwner: TComponent); override;
    function GetButtonKindAt(X, Y : Integer) : TcxCalcButtonKind;
    function GetButtonKindChar(Ch : Char) : TcxCalcbuttonKind;
    function GetButtonKindKey(Key: Word; Shift: TShiftState) : TcxCalcbuttonKind;
    procedure CopyToClipboard;
    procedure PasteFromClipboard;
    property Memory: Extended read GetMemory;
    property Value: Extended read GetDisplay write SetDisplay;
  published
    property TabStop default True;
  end;

  { TcxPopupCalculator }

  TcxCustomCalcEdit = class;

  TcxPopupCalculator = class(TcxCustomCalculator)
  private
    FEdit: TcxCustomCalcEdit;
  protected
    function GetEditorValue: string; override;
    function GetPainter: TcxCustomLookAndFeelPainterClass; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
    procedure SetEditorValue(const Value: string); override;
    property Edit: TcxCustomCalcEdit read FEdit write FEdit;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Init; virtual;
  end;

  { TcxCalcEditPropertiesValues }

  TcxCalcEditPropertiesValues = class(TcxTextEditPropertiesValues)
  private
    FPrecision: Boolean;
    procedure SetPrecision(Value: Boolean);
  public
    procedure Assign(Source: TPersistent); override;
    procedure RestoreDefaults; override;
  published
    property Precision: Boolean read FPrecision write SetPrecision stored False;
  end;

  { TcxCustomCalcEditProperties }

  TcxCustomCalcEditProperties = class(TcxCustomPopupEditProperties)
  private
    FBeepOnError: Boolean;
    FPrecision: Byte;
    FQuickClose: Boolean;              
    FScientificFormat: Boolean;
    FUseThousandSeparator: Boolean;
    function GetAssignedValues: TcxCalcEditPropertiesValues;
    function GetPrecision: Byte;
    function IsPrecisionStored: Boolean;
    procedure SetAssignedValues(Value: TcxCalcEditPropertiesValues);
    procedure SetBeepOnError(Value: Boolean);
    procedure SetPrecision(Value: Byte);
    procedure SetQuickClose(Value: Boolean);
    procedure SetScientificFormat(Value: Boolean);
    procedure SetUseThousandSeparator(Value: Boolean);
  protected
    function GetAlwaysPostEditValue: Boolean; override;
    class function GetAssignedValuesClass: TcxCustomEditPropertiesValuesClass; override;
    function HasDigitGrouping(AIsDisplayValueSynchronizing: Boolean): Boolean; override;
    function PopupWindowAcceptsAnySize: Boolean; override;
    function StrToFloatEx(S: string; var Value: Extended): Boolean;
    property AssignedValues: TcxCalcEditPropertiesValues read GetAssignedValues
      write SetAssignedValues;
  public
    constructor Create(AOwner: TPersistent); override;
    procedure Assign(Source: TPersistent); override;
    class function GetContainerClass: TcxContainerClass; override;
    function GetEditValueSource(AEditFocused: Boolean): TcxDataEditValueSource; override;
    function IsDisplayValueValid(var DisplayValue: TcxEditValue;
      AEditFocused: Boolean): Boolean; override;
    function IsEditValueValid(var EditValue: TcxEditValue;
      AEditFocused: Boolean): Boolean; override;
    procedure PrepareDisplayValue(const AEditValue: TcxEditValue;
      var DisplayValue: TcxEditValue; AEditFocused: Boolean); override;
    procedure ValidateDisplayValue(var ADisplayValue: TcxEditValue;
      var AErrorText: TCaption; var Error: Boolean; AEdit: TcxCustomEdit); override;
    // !!!
    property BeepOnError: Boolean read FBeepOnError write SetBeepOnError
      default True;
    property ImmediateDropDown default False;
    property Precision: Byte read GetPrecision write SetPrecision
      stored IsPrecisionStored;
    property QuickClose: Boolean read FQuickClose write SetQuickClose
      default False;
    property ScientificFormat: Boolean read FScientificFormat
      write SetScientificFormat default False;
    property UseThousandSeparator: Boolean read FUseThousandSeparator
      write SetUseThousandSeparator default False;
  end;

  { TcxCalcEditProperties }

  TcxCalcEditProperties = class(TcxCustomCalcEditProperties)
  published
    property Alignment;
    property AssignedValues;
    property AutoSelect;
    property BeepOnError;
    property ButtonGlyph;
    property ClearKey;
    property DisplayFormat;
    property ImeMode;
    property ImeName;
    property ImmediatePost;
    property Precision;
    property ReadOnly;
    property QuickClose;
    property ScientificFormat;
    property UseLeftAlignmentOnEditing;
    property UseThousandSeparator;
    property ValidateOnEnter;
    property OnChange;
    property OnCloseUp;
    property OnEditValueChanged;
    property OnInitPopup;
    property OnPopup;
    property OnValidate;
  end;

  { TcxCustomCalcEdit }

  TcxCustomCalcEdit = class(TcxCustomPopupEdit)
  private
    FCalculator: TcxPopupCalculator;
    function GetProperties: TcxCustomCalcEditProperties;
    function GetActiveProperties: TcxCustomCalcEditProperties;
    function GetValue: Extended;
    procedure SetProperties(Value: TcxCustomCalcEditProperties);
    procedure SetValue(const Value: Extended);
  protected
    // IcxFormatControllerListener
    procedure FormatChanged; override;

    function CanDropDown: Boolean; override;
    procedure CreatePopupWindow; override;
    procedure DoEnter; override;
    procedure DoExit; override;
    procedure DoInitPopup; override;
    procedure Initialize; override;
    procedure InitializePopupWindow; override;
    function InternalGetEditingValue: TcxEditValue; override;
    function IsValidChar(Key: Char): Boolean; override;
    procedure KeyPress(var Key: Char); override;
    procedure PopupWindowClosed(Sender: TObject); override;
    procedure PopupWindowShowed(Sender: TObject); override;
    procedure PropertiesChanged(Sender: TObject); override;
    function InternalPrepareEditValue(const ADisplayValue: string;
      out EditValue: TcxEditValue): Boolean;
    property Calculator: TcxPopupCalculator read FCalculator;
  public
    destructor Destroy; override;
    class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
    procedure PasteFromClipboard; override;
    procedure PrepareEditValue(const ADisplayValue: TcxEditValue;
      out EditValue: TcxEditValue; AEditFocused: Boolean); override;
    property ActiveProperties: TcxCustomCalcEditProperties
      read GetActiveProperties;
    property Properties: TcxCustomCalcEditProperties read GetProperties
      write SetProperties;
    property Value: Extended read GetValue write SetValue stored False;
  end;

  { TcxCalcEdit }

  TcxCalcEdit = class(TcxCustomCalcEdit)
  private
    function GetActiveProperties: TcxCalcEditProperties;
    function GetProperties: TcxCalcEditProperties;
    procedure SetProperties(Value: TcxCalcEditProperties);
  public
    class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
    property ActiveProperties: TcxCalcEditProperties read GetActiveProperties;
  published
    property Anchors;
    property AutoSize;
    property BeepOnEnter;
    property Constraints;
    property DragCursor;
    property DragKind;
    property DragMode;
    property EditValue;
    property Enabled;
    property ImeMode;
    property ImeName;
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property Properties: TcxCalcEditProperties read GetProperties
      write SetProperties;
    property ShowHint;
    property Style;
    property StyleDisabled;
    property StyleFocused;
    property StyleHot;
    property TabOrder;
    property TabStop default True;
    property Value;
    property Visible;
    property OnClick;
{$IFDEF DELPHI5}
    property OnContextPopup;
{$ENDIF}
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEditing;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDrag;
    property BiDiMode;
    property ParentBiDiMode;
    property OnEndDock;
    property OnStartDock;
  end;

  { TcxFilterCalcEditHelper }

  TcxFilterCalcEditHelper = class(TcxFilterDropDownEditHelper)
  public
    class function GetFilterEditClass: TcxCustomEditClass; override;
    class function GetSupportedFilterOperators(
      AProperties: TcxCustomEditProperties;
      AValueTypeClass: TcxValueTypeClass;
      AExtendedSet: Boolean = False): TcxFilterControlOperators; override;
    class procedure InitializeProperties(AProperties,
      AEditProperties: TcxCustomEditProperties; AHasButtons: Boolean); override;
  end;

implementation

uses
{$IFDEF DELPHI6}
  Variants,
{$ENDIF}
  Math, cxLookAndFeels, cxVariants, dxThemeManager, dxUxTheme;

const
  ResultButtons    = [cbEqual, cbPercent];
  RepeatButtons    = [cbBack];
  OperationButtons = [cbAdd, cbSub, cbMul, cbDiv];
  BorderWidth = 4;

{TcxCustomCalculator}

constructor TcxCustomCalculator.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  {init size variables}
  FCalcFontSize      := cxMinCalcFontSize;
  FCalcBtnWidth      := cxMinCalcBtnWidth;
  FCalcBtnHeight     := cxMinCalcBtnHeight;
  FCalcLargeBtnWidth := cxMinCalcLargeBtnWidth;
  FCalcXOfs          := cxMinCalcXOfs;
  FCalcYOfs          := cxMinCalcYOfs;
  FCalcWidth         := cxMinCalcWidth;
  FCalcHeight        := cxMinCalcHeight;
  {default size}
  Width := FCalcWidth;
  Height := FCalcHeight;
  {style}
  ControlStyle := [csCaptureMouse, csOpaque];

⌨️ 快捷键说明

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