Rxcalc.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:30k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 1995, 1996 AO ROSNO             }
  6. {         Copyright (c) 1997, 1998 Master-Bank          }
  7. {                                                       }
  8. {*******************************************************}
  9. unit RxCalc;
  10. interface
  11. {$I RX.INC}
  12. uses Windows, SysUtils, Variants,
  13.   Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Menus,
  14.   ExtCtrls, Buttons, RxCtrls, Clipbrd;
  15. const
  16.   DefCalcPrecision = 15;
  17. type
  18.   TRxCalcState = (csFirst, csValid, csError);
  19.   TRxCalculatorForm = class;
  20. { TRxCalculator }
  21.   TRxCalculator = class(TComponent)
  22.   private
  23.     FValue: Double;
  24.     FMemory: Double;
  25.     FTitle: PString;
  26.     FCtl3D: Boolean;
  27.     FPrecision: Byte;
  28.     FBeepOnError: Boolean;
  29.     FHelpContext: THelpContext;
  30.     FCalc: TRxCalculatorForm;
  31.     FOnChange: TNotifyEvent;
  32.     FOnCalcKey: TKeyPressEvent;
  33.     FOnDisplayChange: TNotifyEvent;
  34.     function GetDisplay: Double;
  35.     function GetTitle: string;
  36.     procedure SetTitle(const Value: string);
  37.     function TitleStored: Boolean;
  38.   protected
  39.     procedure Change; dynamic;
  40.     procedure CalcKey(var Key: Char); dynamic;
  41.     procedure DisplayChange; dynamic;
  42.   public
  43.     constructor Create(AOwner: TComponent); override;
  44.     destructor Destroy; override;
  45.     function Execute: Boolean;
  46.     property CalcDisplay: Double read GetDisplay;
  47.     property Memory: Double read FMemory;
  48.   published
  49.     property BeepOnError: Boolean read FBeepOnError write FBeepOnError default True;
  50.     property Ctl3D: Boolean read FCtl3D write FCtl3D default True;
  51.     property HelpContext: THelpContext read FHelpContext write FHelpContext default 0;
  52.     property Precision: Byte read FPrecision write FPrecision default DefCalcPrecision;
  53.     property Title: string read GetTitle write SetTitle stored TitleStored;
  54.     property Value: Double read FValue write FValue;
  55.     property OnCalcKey: TKeyPressEvent read FOnCalcKey write FOnCalcKey;
  56.     property OnChange: TNotifyEvent read FOnChange write FOnChange;
  57.     property OnDisplayChange: TNotifyEvent read FOnDisplayChange write FOnDisplayChange;
  58.   end;
  59. { TRxCalculatorForm }
  60.   TRxCalculatorForm = class(TForm)
  61.   private
  62.     FMainPanel: TPanel;
  63.     FCalcPanel: TPanel;
  64.     FDisplayPanel: TPanel;
  65.     FDisplayLabel: TLabel;
  66.     FPasteItem: TMenuItem;
  67.     procedure FormKeyPress(Sender: TObject; var Key: Char);
  68.     procedure PopupMenuPopup(Sender: TObject);
  69.     procedure CopyItemClick(Sender: TObject);
  70.     procedure PasteItemClick(Sender: TObject);
  71.     procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
  72.   protected
  73.     procedure OkClick(Sender: TObject);
  74.     procedure CancelClick(Sender: TObject);
  75.     procedure CalcKey(Sender: TObject; var Key: Char);
  76.     procedure DisplayChange(Sender: TObject);
  77.   public
  78.     constructor Create(AOwner: TComponent); override;
  79.   end;
  80. function CreateCalculatorForm(AOwner: TComponent; AHelpContext: THelpContext): TRxCalculatorForm;
  81. function CreatePopupCalculator(AOwner: TComponent
  82.   {$IFDEF RX_D4}; ABiDiMode: TBiDiMode = bdLeftToRight {$ENDIF}): TWinControl;
  83. procedure SetupPopupCalculator(PopupCalc: TWinControl; APrecision: Byte;
  84.   ABeepOnError: Boolean);
  85. implementation
  86. uses {$IFNDEF WIN32} Str16, {$ENDIF} VclUtils, MaxMin, rxStrUtils, ToolEdit;
  87. {$IFDEF WIN32}
  88.  {$R *.R32}
  89. {$ELSE}
  90.  {$R *.R16}
  91. {$ENDIF}
  92. const
  93.   SCalculator = 'Calculator';
  94.   SError = 'Error';
  95. type
  96.   TCalcBtnKind =
  97.    (cbNone, cbNum0, cbNum1, cbNum2, cbNum3, cbNum4, cbNum5, cbNum6,
  98.     cbNum7, cbNum8, cbNum9, cbSgn, cbDcm, cbDiv, cbMul, cbSub,
  99.     cbAdd, cbSqr, cbPcnt, cbRev, cbEql, cbBck, cbClr, cbMP,
  100.     cbMS, cbMR, cbMC, cbOk, cbCancel);
  101.   TCalcPanelLayout = (clDialog, clPopup);
  102. procedure SetDefaultFont(AFont: TFont; Layout: TCalcPanelLayout);
  103. {$IFDEF WIN32}
  104. var
  105.   NonClientMetrics: TNonClientMetrics;
  106. {$ENDIF}
  107. begin
  108. {$IFDEF WIN32}
  109.   NonClientMetrics.cbSize := SizeOf(NonClientMetrics);
  110.   if SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NonClientMetrics, 0) then
  111.     AFont.Handle := CreateFontIndirect(NonClientMetrics.lfMessageFont)
  112.   else
  113. {$ENDIF}
  114.   with AFont do begin
  115.     Color := clWindowText;
  116.     Name := 'MS Sans Serif';
  117.     Size := 8;
  118.   end;
  119.   AFont.Style := [fsBold];
  120.   if Layout = clDialog then begin
  121.   end
  122.   else begin
  123.   end;
  124. end;
  125. function CreateCalculatorForm(AOwner: TComponent; AHelpContext: THelpContext): TRxCalculatorForm;
  126. begin
  127.   Result := TRxCalculatorForm.Create(AOwner);
  128.   with Result do
  129.   try
  130.     HelpContext := AHelpContext;
  131. {$IFDEF WIN32}
  132.     if HelpContext <> 0 then BorderIcons := BorderIcons + [biHelp];
  133. {$ENDIF}
  134.     if Screen.PixelsPerInch <> 96 then begin { scale to screen res }
  135.       ScaleBy(Screen.PixelsPerInch, 96);
  136.       SetDefaultFont(Font, clDialog);
  137.       Left := (Screen.Width div 2) - (Width div 2);
  138.       Top := (Screen.Height div 2) - (Height div 2);
  139.     end;
  140.   except
  141.     Free;
  142.     raise;
  143.   end;
  144. end;
  145. { TCalcButton }
  146. type
  147.   TCalcButton = class(TRxSpeedButton)
  148.   private
  149.     FKind: TCalcBtnKind;
  150.     FFontChanging: Boolean;
  151.   protected
  152.     procedure CMParentFontChanged(var Message: TMessage); message CM_PARENTFONTCHANGED;
  153.   public
  154.     constructor CreateKind(AOwner: TComponent; AKind: TCalcBtnKind);
  155.     property Kind: TCalcBtnKind read FKind;
  156.   end;
  157. constructor TCalcButton.CreateKind(AOwner: TComponent; AKind: TCalcBtnKind);
  158. begin
  159.   inherited Create(AOwner);
  160. {$IFDEF WIN32}
  161.   ControlStyle := ControlStyle + [csReplicatable];
  162. {$ENDIF}
  163.   FKind := AKind;
  164.   if FKind in [cbNum0..cbClr] then Tag := Ord(Kind) - 1
  165.   else Tag := -1;
  166. end;
  167. procedure TCalcButton.CMParentFontChanged(var Message: TMessage);
  168.   function BtnColor(Kind: TCalcBtnKind): TColor;
  169.   begin
  170.     if Kind in [cbSqr, cbPcnt, cbRev, cbMP..cbMC] then Result := clNavy
  171.     else if Kind in [cbDiv, cbMul, cbSub, cbAdd, cbEql] then Result := clPurple
  172.     else if Kind in [cbBck, cbClr] then Result := clMaroon
  173.     else Result := clBtnText;
  174.   end;
  175. begin
  176.   if not FFontChanging then inherited;
  177.   if ParentFont and not FFontChanging then begin
  178.     FFontChanging := True;
  179.     try
  180.       Font.Color := BtnColor(FKind);
  181.       ParentFont := True;
  182.     finally
  183.       FFontChanging := False;
  184.     end;
  185.   end;
  186. end;
  187. const
  188.   BtnPos: array[TCalcPanelLayout, TCalcBtnKind] of TPoint =
  189.   (((X: -1; Y: -1), (X: 47; Y: 104), (X: 47; Y: 80), (X: 85; Y: 80),
  190.     (X: 123; Y: 80), (X: 47; Y: 56), (X: 85; Y: 56), (X: 123; Y: 56),
  191.     (X: 47; Y: 32), (X: 85; Y: 32), (X: 123; Y: 32), (X: 85; Y: 104),
  192.     (X: 123; Y: 104), (X: 161; Y: 32), (X: 161; Y: 56), (X: 161; Y: 80),
  193.     (X: 161; Y: 104), (X: 199; Y: 32), (X: 199; Y: 56), (X: 199; Y: 80),
  194.     (X: 199; Y: 104), (X: 145; Y: 6), (X: 191; Y: 6), (X: 5; Y: 104),
  195.     (X: 5; Y: 80), (X: 5; Y: 56), (X: 5; Y: 32),
  196.     (X: 47; Y: 6), (X: 85; Y: 6)),
  197.    ((X: -1; Y: -1), (X: 6; Y: 75), (X: 6; Y: 52), (X: 29; Y: 52),
  198.     (X: 52; Y: 52), (X: 6; Y: 29), (X: 29; Y: 29), (X: 52; Y: 29),
  199.     (X: 6; Y: 6), (X: 29; Y: 6), (X: 52; Y: 6), (X: 52; Y: 75),
  200.     (X: 29; Y: 75), (X: 75; Y: 6), (X: 75; Y: 29), (X: 75; Y: 52),
  201.     (X: 75; Y: 75), (X: -1; Y: -1), (X: -1; Y: -1), (X: -1; Y: -1),
  202.     (X: 52; Y: 98), (X: 29; Y: 98), (X: 6; Y: 98), (X: -1; Y: -1),
  203.     (X: -1; Y: -1), (X: -1; Y: -1), (X: -1; Y: -1),
  204.     (X: -1; Y: -1), (X: -1; Y: -1)));
  205.   ResultKeys = [#13, '=', '%'];
  206. function CreateCalcBtn(AParent: TWinControl; AKind: TCalcBtnKind;
  207.   AOnClick: TNotifyEvent; ALayout: TCalcPanelLayout): TCalcButton;
  208. const
  209.   BtnCaptions: array[cbSgn..cbMC] of PChar =
  210.    ('