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

Delphi控件源码

开发平台:

Delphi

  1. {  This a editor prepared to edit numbers.
  2.    Inplace edit calculations are supported.
  3.    The following key operations are supported while editing.
  4.    Operation      Valid Keys
  5.    ---------      ----------
  6.      %              %
  7.      *              *
  8.      +              +
  9.      -              -
  10.      .              . or ,
  11.      /              /
  12.      0-9            0-9
  13.      1/x            r
  14.      =              Enter
  15.      Backspace      backspace
  16.      C              Esc
  17.      CE             Del
  18.      ln             n
  19.      log            l
  20.      n!             !
  21.      pi             p
  22.      x^2            @
  23.      x^3            #
  24.      x^y            y
  25.      MS             Ctrl+M
  26.      M+             Ctrl+P
  27.      MC             Ctrl+L
  28.      MR             Ctrl+R
  29.      inv            i
  30.      sqrt           @
  31.      +/-            F9
  32.      (              (
  33.      )              )
  34.      A-F (HEX)      A-F
  35.      And            &
  36.      Ave            Ctrl+A
  37.      bin            F8
  38.      Byte           F4
  39.      Cos            o or O
  40.      Dat            Ins
  41.      Dec            F6
  42.      Degrees        F2
  43.      dms            m
  44.      Dword          F2
  45.      Exp            x
  46.      F-E            v
  47.      Grads          F4
  48.      Hex            F5
  49.      Hyp            h
  50.      Int            ;
  51.      lsh            <
  52.      M+             Ctrl+P
  53.      MC             Ctrl+L
  54.      Mod            %
  55.      MR             Ctrl+R
  56.      MS             Ctrl+M
  57.      Not            ~
  58.      oct            f7
  59.      or             |
  60.      qword          f12
  61.      radians        f3
  62.      Sin            s
  63.      Sum            Ctrl+t
  64.      Tan            t
  65.      word           f3
  66.      xor            ^
  67.    Addition        +
  68.    Subtraction     -
  69.    Multiplication  *
  70.    Division        /
  71.    sqrt            s
  72.    invert          r
  73.    percentage      %
  74.    C (Clear)       BackSpace and Left
  75.    CE              Delete
  76.    log             l
  77.    ln              n
  78.    sin             s or S
  79.    cos             o
  80.    pi              p
  81.    tan             t
  82.    exp             x
  83.    x^Y             y
  84.    n! factorial    !
  85.    x^2  SQR        @
  86.    OR              ^ |
  87.    AND             &
  88.    Memory          Ctrl-M
  89.    Recall          Ctrl-R
  90.    Memory Clear    Ctrl-L
  91.    Memory Add      Ctrl-P
  92.    Result          =
  93.    Aso you can use the Backspace,
  94.    Del key means CE command ( using 'l' char ),
  95.    and the C command ( using 'c' char ).
  96. }
  97. unit wwCalcEdit;
  98. interface
  99. uses
  100.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Buttons, Forms, Dialogs,
  101.   StdCtrls, wwdbedit, wwdbcomb, math, extctrls,wwcommon,wwCalculator;
  102. type
  103.   TwwCustomCalcEdit = class;
  104.   TwwPopupCalcOptions = class(TPersistent)
  105.   private
  106.     FBackground:TPicture;
  107.     FBackGroundStyle: TwwCalcBitmapDrawStyle;
  108.     FMargin:integer;
  109.     FOptions: TwwCalcOptions;
  110.     FPanelColor:TColor;
  111.     procedure SetBackgroundStyle(Value: TwwCalcBitmapDrawStyle);
  112.     procedure SetOptions(Value: TwwCalcOptions);
  113.     procedure SetMargin(Value: Integer);
  114.     procedure SetPanelColor(Value: TColor);
  115.   public
  116.     constructor Create(AOwner: TComponent);
  117.     destructor Destroy; override;
  118.   protected
  119.     procedure SetBackgroundBitmap(Value: TPicture); virtual;
  120.   published
  121.     property Background:TPicture read FBackground write SetBackGroundBitmap;
  122.     property BackgroundStyle: TwwCalcBitmapDrawStyle read FBackgroundStyle write SetBackgroundStyle;
  123.     property ButtonMargin: integer read FMargin write SetMargin default 3;
  124.     property Options: TwwCalcOptions read FOptions write SetOptions default [];
  125.     property PanelColor: TColor read FPanelColor write SetPanelColor default clBtnFace;
  126.   end;
  127.   TwwCalcPanel = class(TwwCalculator)
  128.   private
  129.     FAssociatedEdit:TwwCustomCalcEdit;
  130.   protected
  131.     procedure CreateParams(var Params: TCreateParams); override;
  132.     procedure CreateWnd; override;
  133.     procedure Keypress(var Key: Char); override;
  134.     procedure Compute(Sender: TObject); override;
  135. //    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  136.   public
  137.     constructor Create(AOwner: TComponent); override;
  138.     property AssociatedEdit:TwwCustomCalcEdit read FAssociatedEdit write FAssociatedEdit;
  139.   end;
  140. (*  TCalculatorWindow = class( TCustomControl )
  141.   private
  142.     FEdit: TCalculatorCombo;
  143.     FButtonPressed,
  144.     FButtonDown: TBotonPresionado;
  145.     procedure DrawButton( aCanvas: TCanvas; B: TBotonPresionado;
  146.                           Text: string );
  147.     procedure ButtonRect( B: TBotonPresionado; var R: TRect );
  148.     function ButtonToChar( B: TBotonPresionado ): char;
  149.     function CharToButton( ch: char ): TBotonPresionado;
  150.     procedure ButtonPushed( B: TBotonPresionado );
  151.     procedure Draw( aCanvas: TCanvas );
  152.   protected
  153.     procedure Paint; override;
  154.     procedure CreateParams(var Params: TCreateParams); override;
  155.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  156.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  157.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer ); override;
  158.     function MouseToButton( X, Y: Integer ): TBotonPresionado;
  159.     procedure PushButton( B: TBotonPresionado );
  160.   public
  161. //    procedure Repintar;
  162.     property Edit: TCalculatorCombo read FEdit;
  163.   end;
  164.   *)
  165.   TwwCustomCalcEdit = class(TwwDBCustomComboBox)
  166.   private
  167.     FDropDownCalc:TwwCalcPanel;
  168. //    FCalculator: TCalculatorWindow;
  169.     fResult: Double;
  170.     FMemoryValue: Double;
  171.     FLastOperator: Char;
  172.     FSecondToLastOperator: Char;
  173.     FLastOperand: Double;
  174.     FClearOnNextKey: boolean;
  175.     FLastOperatorEquals: Boolean;
  176.     FDecimalEntered : Boolean;
  177.     FCalcOptions : TwwPopupCalcOptions;
  178. //    procedure ToggleSign;
  179.     function GetValue: Double;
  180. //    procedure SetCalcOptions(Value: TwwPopupCalcOptions);
  181.     procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
  182.     procedure CMCancelMode(var Message: TCMCancelMode); message CM_CANCELMODE;
  183.   protected
  184.     procedure ResetCalculator; virtual;
  185.     function IsValidOperator(Key: Char): boolean; virtual;
  186.     function IsUnaryOperator(Key:Char):boolean; virtual;
  187.     function IsBinaryOperator(Key:Char):boolean; virtual;
  188.     procedure CreateParams(var Params: TCreateParams); override;
  189.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  190.     procedure KeyPress(var Key: Char); override;
  191.     procedure Compute(OperatorKey:Char);
  192. //    function GetPanel: TwwCalcPanel;
  193.   public
  194.     property Panel:TwwCalcPanel read fDropDownCalc write fDropDownCalc;
  195.     constructor Create( AOwner: TComponent ); override;
  196.     destructor Destroy; override;
  197.     procedure CreateWnd; override;
  198.     //MAKE DoCloseUp and DoDropDown events.
  199.     procedure CloseUp(Accept: Boolean); override;
  200.     procedure DropDown; override;
  201.     function IsDroppedDown: Boolean; override;
  202.     property Value: Double read GetValue;// write fResult;
  203.   published
  204.     property CalcOptions: TwwPopupCalcOptions read FCalcOptions write FCalcOptions;
  205.     property AutoSelect;
  206.     property Color;
  207.     property Ctl3D;
  208.     property DragCursor;
  209.     property DragMode;
  210.     property Enabled;
  211.     property Font;
  212.     property ImeMode;
  213.     property ImeName;
  214.     property MaxLength;
  215.     property ParentColor;
  216.     property ParentCtl3D;
  217.     property ParentFont;
  218.     property ParentShowHint;
  219.     property PopupMenu;
  220.     property ShowHint;
  221.     property TabOrder;
  222.     property TabStop;
  223.     property Visible;
  224.     property OnChange;
  225.     property OnClick;
  226.     property OnDblClick;
  227.     property OnDragDrop;
  228.     property OnDragOver;
  229.     property OnDropDown;
  230.     property OnEndDrag;
  231.     property OnEnter;
  232.     property OnExit;
  233.     property OnKeyDown;
  234.     property OnKeyPress;
  235.     property OnKeyUp;
  236.     property OnMouseDown;
  237.     property OnMouseMove;
  238.     property OnMouseUp;
  239.     property OnStartDrag;
  240.   end;
  241. procedure Register;
  242. implementation
  243. var wwCalcHook: HHOOK;
  244. function wwCalcHookProc(nCode: Integer; wParam: Integer; lParam: Integer): LResult; stdcall;
  245. var r1, r2: TRect;
  246. begin
  247.   result := CallNextHookEx(wwCalcHook, nCode, wParam, lParam);
  248.   with PMouseHookStruct(lParam)^ do
  249.   begin
  250.     if (wParam = WM_LBUTTONDOWN) or (wParam = WM_NCLBUTTONDOWN) then
  251.     begin
  252.       if (Screen.ActiveControl <> nil) and (Screen.ActiveControl is TwwCustomCalcEdit) then
  253.         with (Screen.ActiveControl as TwwCustomCalcEdit) do
  254.       begin
  255.         { Auto-closeup if clicked outside of drop-down area }
  256.         if (fDropDownCalc <> nil) and fDropDownCalc.Visible then begin
  257.            GetWindowRect(fDropDownCalc.Handle, r1);
  258.            GetWindowRect(Handle, r2);
  259.            if (not PtInRect(r1, pt)) and (not PtInRect(r2, pt)) then
  260.               PostMessage(Handle, CM_CANCELMODE, 0, 0);
  261.         end
  262.       end;
  263.     end;
  264.   end;
  265. end;
  266. function fcThisThat(const Clause: Boolean; TrueVal, FalseVal: Integer): Integer;
  267. begin
  268.   if Clause then result := TrueVal else Result := FalseVal;
  269. end;
  270. procedure TwwCalcPanel.Compute(Sender: TObject);
  271. var
  272.  ch: char;
  273.  ButtonType: TwwCalcButtonType;
  274. begin
  275.   ButtonType := TwwCalcButtonType(TSpeedButton(Sender).Tag);
  276.   case ButtonType of
  277.     bt0..bt9:   ch := TSpeedButton(Sender).Caption[1];
  278.     btDecimal:  ch := '.';
  279.     btPlusMinus: ;
  280.     btClearAll: ch := char(vk_escape);
  281.     btClear:    ch := char(vk_back);
  282.     btAdd:      ch:='+';
  283.     btSubtract: ch:='-';
  284.     btDivide:   ch:='/';
  285.     btMultiply: ch:='*';
  286.     btBackSpace:ch:=char(vk_back);
  287.     btInverse:  ch:='r';
  288.     btPercent:  ch:='%';
  289.     btSqrt:     ch:='@';
  290.     btMStore:   ch:='m';
  291.     btMAdd:     ch:='p';
  292.     btMRecall:  ch:='r';
  293.     btMClear:   ch:='l';
  294.     btEquals:   ch:='=';
  295.     else
  296.       ch:=' ';
  297.     end;
  298.     SendMessage(FAssociatedEdit.Handle, WM_CHAR, word(ch), 0);
  299. end;
  300. procedure TwwCalcPanel.Keypress(var Key: Char);
  301. var
  302.   combo: TwwCustomCalcEdit;
  303. begin
  304.   Combo:= owner as TwwCustomCalcEdit;
  305.   inherited Keypress(Key);
  306. end;
  307.     constructor TwwPopupCalcOptions.Create(AOwner: TComponent);
  308.     begin
  309.       FBackground := TPicture.Create;
  310.       FMargin := 3;
  311.       FOptions := [];
  312.       FPanelColor := clBtnFace;
  313.     end;
  314.     destructor TwwPopupCalcOptions.Destroy;
  315.     begin
  316.       if FBackGround <> nil then begin
  317.          FBackground.Free;
  318.          FBackground := nil;
  319.       end;
  320.       inherited;
  321.     end;
  322.     procedure TwwPopupCalcOptions.SetBackgroundBitmap(Value: TPicture);
  323.     begin
  324.       FBackground.assign(Value);
  325.     end;
  326.     procedure TwwPopupCalcOptions.SetBackgroundStyle(Value: TwwCalcBitmapDrawStyle);
  327.     begin
  328.       if Value<>FBackgroundStyle then begin
  329.          FBackgroundStyle:= Value;
  330.       end;
  331.     end;
  332.     procedure TwwPopupCalcOptions.SetOptions(Value: TwwCalcOptions);
  333.     begin
  334.       if Value<>FOptions then begin
  335.          FOptions:= Value;
  336.       end;
  337.     end;
  338.     procedure TwwPopupCalcOptions.SetPanelColor(Value: TColor);
  339.     begin
  340.       if Value<>FPanelColor then begin
  341.          FPanelColor:= Value;
  342.       end;
  343.     end;
  344.     procedure TwwPopupCalcOptions.SetMargin(Value: Integer);
  345.     begin
  346.       if Value<>FMargin then begin
  347.          FMargin := Value;
  348.       end;
  349.     end;
  350. procedure TwwCalcPanel.CreateParams(var Params: TCreateParams);
  351. begin
  352.   inherited CreateParams(Params);
  353.   with Params do
  354.   begin
  355.     Style := Style or WS_CHILD or WS_CLIPSIBLINGS or WS_CLIPCHILDREN; // ak
  356.     Style := Style or WS_BORDER;
  357.     {$ifdef win32}
  358.     ExStyle := WS_EX_TOOLWINDOW;
  359.     ExStyle := ExStyle or WS_EX_CONTROLPARENT; //ak
  360.     {$endif}
  361.     WindowClass.Style := CS_SAVEBITS;
  362.   end;
  363. end;
  364. constructor TwwCalcPanel.Create(AOwner: TComponent);
  365. begin
  366.    inherited Create(AOwner);
  367.    FAssociatedEdit := TwwCustomCalcEdit(AOwner);
  368.    ControlStyle := ControlStyle + [csReplicatable];
  369.    ControlStyle := ControlStyle + [csNoDesignVisible];
  370.    ControlStyle := ControlStyle + [csReflector];
  371.    Color := clBtnFace;
  372. //   Height := 175;
  373. //   Width := 250;
  374. end;
  375. procedure TwwCalcPanel.CreateWnd;
  376. begin
  377.   inherited CreateWnd;
  378.   Windows.SetParent(Handle, 0);
  379. end;
  380. (*procedure TwwCalcPanel.Draw( aCanvas: TCanvas );
  381. var
  382.   OldBrushColor: TColor;
  383.   OldPenColor: TColor;
  384. begin
  385.   inherited;
  386.   exit;
  387.   OldBrushColor := aCanvas.Brush.Color;
  388.   OldPenColor := aCanvas.Pen.Color;
  389.   try
  390.     aCanvas.Brush.Color := clRed;//FEdit.CalculatorBackColor;
  391.     aCanvas.FillRect( ClientRect );
  392.     aCanvas.Rectangle( ClientRect.left, ClientRect.top,
  393.                       ClientRect.right, ClientRect.bottom );
  394.     acanvas.TextOut(10,10,'Sum');
  395.     // Pintar botones BACK, CE y C
  396. //    aCanvas.Brush.Color := FEdit.CalculatorButtonsColor;
  397. //    aCanvas.Font := Font;//FEdit.BackFont;
  398.   //  DrawButton( aCanvas, bpBack, STR_BACK );
  399.   finally
  400.     aCanvas.Brush.Color := OldBrushColor;
  401.     aCanvas.Pen.Color := OldPenColor;
  402.   end;
  403. end;
  404. procedure TwwCalcPanel.Paint;
  405. var
  406.   bmp: TBitmap;
  407. begin
  408.   inherited;
  409.   exit;
  410.   bmp := TBitmap.Create;
  411.   try
  412.     bmp.Width := Width;
  413.     bmp.Height := Height;
  414.     Draw( bmp.Canvas );
  415.     Canvas.CopyRect( ClientRect, bmp.Canvas, ClientRect );
  416.   finally
  417.     bmp.free;
  418.   end;
  419. end;
  420.   *)
  421. { TwwCustomCalcEdit }
  422. constructor TwwCustomCalcEdit.Create( aOwner: TComponent );
  423. begin
  424.   inherited Create( aOwner );
  425.   fResult := 0;
  426.   MaxLength := 20;
  427.   WantReturns := True;
  428.   FCalcOptions := TwwPopupCalcOptions.Create(Self);
  429. end;
  430. procedure TwwCustomCalcEdit.CreateWnd;
  431. begin
  432.   inherited;
  433. end;
  434. destructor TwwCustomCalcEdit.Destroy;
  435. begin
  436.   FCalcOptions.Free;
  437.   if wwCalcHook<>0 then begin
  438.      UnhookWindowsHookEx(wwCalcHook);
  439.      wwCalcHook:= 0;
  440.   end;
  441.   inherited Destroy;
  442. end;
  443. function TwwCustomCalcEdit.IsBinaryOperator(Key:Char): boolean;
  444. begin
  445.   Result := Key in ['+','-','*','/','%','^','='];
  446. end;
  447. function TwwCustomCalcEdit.IsUnaryOperator(Key:Char): boolean;
  448. begin
  449.   Result := Key in ['@','#','r','n','l',';','!'];
  450. end;
  451. function TwwCustomCalcEdit.IsValidOperator(Key:Char): boolean;
  452. begin
  453.   Result := IsBinaryOperator(Key) or IsUnaryOperator(Key) or
  454.             (Key in ['p']);
  455. end;
  456. procedure TwwCustomCalcEdit.ResetCalculator;
  457. begin
  458.   fResult := 0.0;
  459.   Text:='';
  460.   FLastOperator := char(#0);
  461.   FLastOperand := 0;
  462.   FLastOperatorEquals:= False;
  463.   FClearOnNextKey := False;
  464.   FDecimalEntered := False;
  465. end;
  466. procedure TwwCustomCalcEdit.KeyDown(var Key: Word; Shift: TShiftState);
  467. var curvalue:Double;
  468. begin
  469.   inherited KeyDown(Key, Shift);
  470.   if (key=vk_Delete) or (key=vk_escape) then begin
  471.        //Clear the displayed number.
  472.       Text := '0';
  473.       //Treat vk_Escape as C key like the windows calculator.
  474.       //The C key clears the current calculation.
  475.       if (FLastOperator = char(#0)) or (key=vk_Escape) then begin
  476.          ResetCalculator;
  477.       end;
  478.       SelectAll;
  479.       Key := 0;
  480.    end;
  481.    //Handle Memory Keys....
  482.    if not (ssCtrl in Shift) or (Text = '') then exit;
  483.    try
  484.      curValue := StrToFloat(Text);
  485.    except
  486.      curValue := 0;
  487.    end;
  488.    if (ssCtrl in Shift) and ((key = ord('M')) or (key=ord('m'))) then
  489.       FMemoryValue := curValue;
  490.    if (ssCtrl in Shift) and ((key = ord('L')) or (key=ord('l'))) then
  491.      FMemoryValue := 0.0;
  492.    if (ssCtrl in Shift) and ((key = ord('P')) or (key=ord('p'))) then
  493.      FMemoryValue := FMemoryValue + CurValue;
  494.    if (ssCtrl in Shift) and ((key = ord('R')) or (key=ord('r'))) then
  495.    begin
  496.      Text := FloatToStr(FMemoryValue);
  497.    end;
  498. end;
  499. procedure TwwCustomCalcEdit.KeyPress(var Key: Char);
  500.   function IsValidDigit(Key:Char): boolean;
  501.   begin
  502.       Result := (key in ['0'..'9',',','.'])
  503.                 or ((ord(key) >= VK_NUMPAD0) and (ord(key) <= VK_NUMPAD9));
  504.   end;
  505.   function IsValidCalcChar(Key:Char): boolean;
  506.   begin
  507.      result:= isValidDigit(Key) or (key=#13) or
  508.               (key = #8) or (key=#46) or (Key=#27) or
  509.               isValidOperator(Key)
  510.   end;
  511. begin
  512.   inherited KeyPress(Key);
  513.   case Key of
  514.     '.',',':
  515.         if (Key='.') or (Key=',') then begin
  516.            if FClearOnNextKey then ResetCalculator;
  517.            if not FDecimalEntered then begin
  518.               if Text = '' then begin
  519.                  Text := '0'+decimalseparator;
  520.                  SelStart := Length(Text);
  521.                  Key := #0;
  522.               end
  523.               else Key := DecimalSeparator;
  524.               FDecimalEntered := True;
  525.            end
  526.            else begin
  527.               Key := #0;
  528.               Beep;
  529.            end;
  530.         end;
  531.     '0'..'9',#96..#105:
  532.         begin
  533.           if FClearOnNextKey then begin
  534.              if FLastOperatorEquals then ResetCalculator
  535.              else Text := '';
  536.           end;
  537.           FClearOnNextKey := false;
  538.         end;
  539. {    #27,#47:
  540.         begin
  541.            //If a vk_Escape (C) or a vk_delete (CE) was pressed the text needs to be reset to zero.
  542.            //Clear the displayed number.
  543.            Text := '0';
  544.            //Treat vk_Escape as C key like the windows calculator.
  545.            //The C key clears the current calculation.
  546.            if ord(key)=vk_Escape then ResetCalculator;
  547.            SelectAll;
  548.            Key := #0;
  549.         end}
  550.       else
  551.       begin
  552.          if Key=#13 then Key := '=';
  553.          if IsValidOperator(Key) then begin
  554.             if not isDroppedDown then DropDOwn;
  555.             Compute(Key);
  556.             if Key='=' then SelectAll;//SelStart := Length(Text);
  557.             Key := #0;
  558.          end
  559.          else Key := #0;
  560.       end;
  561.    end;
  562. end;
  563. procedure TwwCustomCalcEdit.Compute(OperatorKey:Char);
  564. var
  565.   Value : Double;
  566.   flag: boolean;
  567.   i:integer;
  568. begin
  569.   if Text = '' then
  570.   begin
  571.      Value := 0;
  572.      exit;
  573.   end;
  574.   try
  575.      Value := StrToFloat( Text );
  576.   except
  577.      Value := 0.0;
  578.   end;
  579.   if isBinaryOperator(OperatorKey) then
  580.   begin
  581.     if FClearOnNextKey and ((OperatorKey<>'=') and (ord(OperatorKey)<>vk_return))then
  582.     begin
  583.       FLastOperator := OperatorKey;
  584.       FLastOperatorEquals:= False;
  585.     end
  586.     else //Equals pressed.
  587.     begin
  588.       if not fLastOperatorEquals then flastoperand := Value;
  589.       flag := true;
  590.       try
  591.         if OperatorKey='%' then fResult := (fResult * flastoperand)/100.0
  592.         else begin
  593.           case FLastOperator of
  594.             '*': fResult := fResult * flastoperand;
  595.             '/': begin
  596.                    if flastoperand <> 0 then
  597.                       fResult := fResult / flastoperand
  598.                    else begin Text := 'Error';
  599.                       flag := False;
  600.                    end;
  601.                  end;
  602.             '+': fResult := fResult + flastoperand;
  603.             '-': fResult := fResult - flastoperand;
  604.             '^': fResult := Power(fResult,flastoperand);
  605.           else
  606.             flag := false;
  607.             FLastOperator := '=';
  608.           end;
  609.         end;
  610.       except
  611.          ResetCalculator;
  612.          Text := 'Error';
  613.          exit;
  614.       end;
  615.       FClearOnNextKey := true;
  616.       if flag then
  617.          Text := FloatToStr(fResult)
  618.       else fResult := Value;
  619.       if ((OperatorKey<>'=') and (ord(OperatorKey)<>vk_return)) then FLastOperator := OperatorKey
  620.       else FLastOperatorEquals:= True;
  621.     end;
  622.   end
  623.   else begin
  624.     case OperatorKey of
  625.       ^M : FMemoryValue := Value;
  626.       '@' : fResult := Sqr(Value);
  627.       'r' : fResult := 1 / Value;
  628.       '#' : fResult := Power(Value,3);
  629.       'n' : fResult := ln(Value);
  630.       'l' : fResult := log10(Value);
  631.       '!' : begin
  632.               fResult := 1;
  633.               for i:= 1 to trunc(Value) do
  634.                  fResult := fResult*i;
  635.             end;
  636.       ';' : fResult := Trunc(Value);
  637.     end;
  638.     Text := FloatToStr(fResult);
  639.    end;
  640. end;
  641. function TwwCustomCalcEdit.GetValue: Double;
  642. begin
  643.   Result := StrToFloat( Text );
  644. end;
  645. {procedure TwwCustomCalcEdit.ToggleSign;
  646. begin
  647.   if Text[ 1 ] = CH_MINUS then Text := Copy( Text, 2, Length( Text ))
  648.   else Text := CH_MINUS + Text;
  649. end;
  650.  }
  651. procedure TwwCustomCalcEdit.CreateParams(var Params: TCreateParams);
  652. begin
  653.   inherited CreateParams(Params);
  654.   Params.Style :=(Params.Style and not (ES_AUTOVSCROLL or ES_WANTRETURN) or
  655.                    WS_CLIPCHILDREN);
  656.   if UseRightToLeftAlignment or LimitEditRect then
  657.     Params.Style:= Params.Style or ES_MULTILINE;
  658. end;
  659. function TwwCustomCalcEdit.IsDroppedDown: Boolean;
  660. begin
  661.   result := (fDropDownCalc<>nil) and fDropDownCalc.Visible;
  662. end;
  663. procedure TwwCustomCalcEdit.CMCancelMode(var Message: TCMCancelMode);
  664. var
  665.   F: THandle;
  666.   sb:TSpeedButton;
  667. begin
  668.   if (Message.Sender <> Self) and (Message.Sender <> fDropDownCalc) and
  669.      (Message.Sender <> Button) and (Message.Sender.Parent <> fDropDownCalc) then
  670.     CloseUp(True);
  671. end;
  672. procedure TwwCustomCalcEdit.WMKillFocus(var Message: TWMKillFocus);
  673. {begin
  674.   inherited;
  675.   if fDropDownCalc.HandleAllocated and
  676.      (Message.FocusedWnd <> fDropDownCalc.Handle) then
  677.     CloseUp(True);
  678.  }
  679. var
  680.   F: THandle;
  681.   sb:TSpeedButton;
  682. begin
  683.   inherited;
  684.   CloseUp(True);
  685.   exit;
  686.   F := GetFocus;
  687.   sb:= TwwCustomCalcEdit(self).Button;
  688.   if ((fDropDownCalc <> nil) and ( F <> fDropDownCalc.Handle ))
  689.       and ( F <> Handle )and
  690.      ( F <> sb.parent.Handle ) then
  691.     CloseUp(True);
  692. end;
  693. //end;
  694. procedure TwwCustomCalcedit.DropDown;
  695. var
  696.   P: TPoint;
  697.   X, Y: Integer;
  698.   WinAttribute: HWnd;
  699.   ListBoxWidth, ListBoxHeight: integer;
  700.   function GetDeskTopHeight:Integer;
  701.      var Rect1:TRect;
  702.   begin
  703.       if SystemParametersInfo(SPI_GETWORKAREA,0,@Rect1,0) Then
  704.          GetDeskTopHeight:=Rect1.Bottom-Rect1.Top
  705.       else
  706.          GetDeskTopHeight:=Screen.Height;
  707.   end;
  708. begin
  709.   if (fDropDownCalc <> nil) then exit;
  710.   if wwCalcHook=0 then
  711.       wwCalcHook := SetWindowsHookEx(WH_MOUSE, @wwCalcHookProc, HINSTANCE, GetCurrentThreadID);
  712.   fDropDownCalc := TwwCalcPanel.Create(self);
  713.   fDropDownCalc.Visible := False;
  714.   fDropDownCalc.Height := 175;
  715.   fDropDownCalc.Width := 250;
  716.   fDropDownCalc.Parent := Self;
  717.   if CalcOptions.background <> nil then begin
  718.      fDropDownCalc.BackgroundBitmapDrawStyle := CalcOptions.BackgroundStyle;
  719.      fDropDownCalc.BackgroundBitmap.Assign(CalcOptions.Background);
  720.   end;
  721.   fDropDownCalc.PanelColor := CalcOptions.PanelColor;
  722.   fDropDownCalc.Options := CalcOptions.Options;
  723.   fDropDownCalc.ButtonMargin := CalcOptions.ButtonMargin;
  724.   P := Parent.ClientToScreen(Point(Left, Top));
  725.   Y := P.Y + Height - 1;
  726.   if BorderStyle = bsNone then y:= y + 1;
  727.   { 11/28/2000 - PYW - Check based on actual work area. }
  728.    if Y + fDropDownCalc.Height > GetDeskTopHeight then Y := P.Y - fDropDownCalc.Height;
  729.    { 4/1/97 - Expand list to left since it goes past edge of screen }
  730.    X := P.X ;
  731.    if P.X + fDropDownCalc.Width >= Screen.Width then X := P.X + Width - 1 - fDropDownCalc.Width;
  732.    try
  733. //      DoDropDown;
  734.    except
  735.       exit;
  736.    end;
  737.    { 3/13/97 - Always Top so that drop-down is not hidden under taskbar}
  738.    WinAttribute:= HWND_TOPMOST;
  739.    SetWindowPos(fDropDownCalc.Handle, WinAttribute, X, Y, 0, 0,
  740.      SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
  741.    fDropDownCalc.visible:= true;
  742.    Windows.SetFocus(Handle);
  743. {   if not inAutoDropDown then DoSelectAll;
  744.    if Editable then ShowCaret(Handle);
  745.    LastShowHint:= ShowHint;
  746.    ShowHint:= False;
  747.    Invalidate;      }
  748. end;
  749. {procedure TwwCustomCalcEdit.SetCalcOptions(Value: TwwPopupCalcOptions);
  750. begin
  751.   if FCalcOptions <> Value then
  752.     FCalcOptions := Value;
  753. end;}
  754. procedure TwwCustomCalcEdit.CloseUp(Accept: Boolean);
  755. begin
  756.   try
  757.     if fDropDownCalc = nil then exit
  758.     else begin
  759.       fDropDownCalc.Visible := False;
  760.  SetWindowPos(fDropDownCalc.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
  761.       SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
  762.       fDropDownCalc.Free;
  763.       fDropDownCalc := nil;
  764.       SetFocus;
  765.      if wwCalcHook<>0 then
  766.      begin
  767.        UnhookWindowsHookEx(wwCalcHook);
  768.        wwCalcHook:= 0;
  769.      end;
  770.     end;
  771.     SelectAll;
  772.     if IsDroppedDown then
  773.     begin
  774. //      SetWindowPos(fDropDownCalc.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
  775.   //      SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
  776.     //  Invalidate;
  777.       if fDropDownCalc.Focused or fDropDownCalc.ResultEdit.Focused then SetFocus;
  778.       fDropDownCalc.Visible := False;
  779.       fDropDownCalc.Free;
  780. //      if Assigned(FOnCloseUp) then FOnCloseUp(self, Accept);
  781.     end;
  782.   finally
  783.      if wwCalcHook<>0 then
  784.      begin
  785.        UnhookWindowsHookEx(wwCalcHook);
  786.        wwCalcHook:= 0;
  787.      end;
  788.   end;
  789. end;
  790. procedure Register;
  791. begin
  792.   RegisterComponents('Samples', [TwwCustomCalcEdit]);
  793. end;
  794. end.