home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 21 / CTROM21B.mdf / win95 / zakelijk / esbcalc / setup.exe / file0009.bin / captbtn.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-05-17  |  9.1 KB  |  319 lines

  1. {*************************************************************}
  2. {            TCaptionButton Components for Delphi 16/32       }
  3. { Version:   1.01                                             }
  4. { Author:    Aleksey Kuznetsov, Kiev, Ukraine                 }
  5. {            └δσΩ±σΘ ╩≤τφσ÷εΓ (Xacker), ╩ΦσΓ, ╙Ω≡αΦφα         }
  6. { E-Mail:    xacker@phreaker.net                              }
  7. { Homepage:  http://www.angen.net/~xacker/                    }
  8. { Created:   March, 3, 1999                                   }
  9. { Modified:  March, 12, 1999                                  }
  10. { Legal:     Copyright (c) 1999 by Aleksey Xacker             }
  11. {*************************************************************}
  12. {   TCaptionButton (English):                                 }
  13. { Additional button on form's title.                          }
  14. {*************************************************************}
  15. {   TCaptionButton (Russian):                                 }
  16. { ─ε∩εδφΦ≥σδⁿφα  Ωφε∩Ωα φα ταπεδεΓΩσ εΩφα.                    }
  17. {*************************************************************}
  18. { If at occurrence of any questions concerning these          }
  19. { components, mail me: xacker@phreaker.net.                   }
  20. { For updated versions visit my H-page: www.angen.net/~xacker }
  21. {*************************************************************}
  22. unit CaptBtn;
  23.  
  24. interface
  25.  
  26. uses
  27.   {$IfDef Win32} Windows, {$Else} WinTypes, WinProcs, {$EndIf}
  28.   Classes, Controls, Forms, Messages, Graphics;
  29.  
  30. type
  31.   TCaptionButton = class(TComponent)
  32.   private
  33.     Canvas: TCanvas;
  34.     ParentForm: TForm;
  35.     PrevParentWndProc: Pointer;
  36.     FRightMargin: Integer;
  37.     FGlyph: TBitmap;
  38.     FVisible: Boolean;
  39.     ButtonRect: TRect;
  40.     FOnClick: TNotifyEvent;
  41.     FDown, FButtonDown: Boolean;
  42.     SeekAndDestroy: Boolean;
  43.     CtrlMsg: Word;
  44.  
  45.     procedure NewParentWndProc(var Msg: TMessage);
  46.     procedure SetRightMargin(Value: Integer);
  47.     procedure SetGlyph(Value: TBitmap);
  48.     procedure SetVisible(Value: Boolean);
  49.     procedure PaintCaption(Down: Boolean);
  50.   protected
  51.   public
  52.     constructor Create(AOwner: TComponent); override;
  53.     destructor Destroy; override;
  54.   published
  55.     property Glyph: TBitmap read FGlyph write SetGlyph;
  56.     property RightMargin: Integer read FRightMargin write SetRightMargin;
  57.     property Visible: Boolean read FVisible write SetVisible;
  58.  
  59.     property OnClick: TNotifyEvent read FOnClick write FOnClick;
  60.   end;
  61.  
  62. procedure Register;
  63.  
  64. implementation
  65.  
  66. const
  67.   NotUsedCtrlMsg: Word = 666;
  68.  
  69. constructor TCaptionButton.Create(AOwner: TComponent);
  70. var
  71.   p: Pointer;
  72. begin
  73.   inherited Create(AOwner);
  74.   ParentForm := TForm(aOwner);
  75.   FGlyph := TBitmap.Create;
  76.   Canvas := TCanvas.Create;
  77.   FVisible := True;
  78.   CtrlMsg := NotUsedCtrlMsg;
  79.   inc(NotUsedCtrlMsg);
  80.  
  81.   { Setting hook on parent form }
  82.   PrevParentWndProc := Pointer(GetWindowLong(ParentForm.Handle, GWL_WNDPROC));
  83.   P := MakeObjectInstance(NewParentWndProc);
  84.   SetWindowLong(ParentForm.Handle, GWL_WNDPROC, LongInt(p));
  85. end;
  86.  
  87. destructor TCaptionButton.Destroy;
  88. begin
  89.   if not SeekAndDestroy {ParentForm.HandleAllocated} then
  90.    begin
  91.     Visible := False;
  92.     SetWindowLong(ParentForm.Handle, GWL_WNDPROC, LongInt(PrevParentWndProc));
  93.    end;
  94.   Canvas.Free;
  95.   FGlyph.Free;
  96.   inherited Destroy;
  97. end;
  98.  
  99. procedure TCaptionButton.NewParentWndProc(var Msg: TMessage);
  100. var
  101.   Pnt: TPoint;
  102. begin
  103.   with Msg do
  104.    begin
  105.     Result := CallWindowProc(PrevParentWndProc, ParentForm.Handle, Msg,
  106.                              WParam, LParam);
  107.     if FVisible then
  108.      if (Msg = wm_NCPaint) or
  109.         (Msg = wm_NCActivate) then PaintCaption(False)
  110.      else
  111.       if Msg = wm_NCHitTest then
  112.        if Result = htCaption then
  113.         begin
  114.          Pnt.x := LoWord(lParam);
  115.          ScreenToClient(ParentForm.Handle, Pnt);
  116.          if (Pnt.x > ButtonRect.Left) and (Pnt.x < ButtonRect.Right) then
  117.           begin
  118.            if not FDown and FButtonDown then PaintCaption(True);
  119.            Result := CtrlMsg
  120.           end
  121.          else
  122.           if FDown then PaintCaption(False);
  123.         end
  124.        else if FDown then PaintCaption(False) else
  125.       else
  126.        if (Msg = wm_NCLButtonDown) or (Msg = wm_NCLButtonDblClk) then
  127.         if wParam = CtrlMsg then
  128.          begin
  129.           if not FDown then PaintCaption(True);
  130.           if not FButtonDown then
  131.            begin
  132.             FButtonDown := True;
  133.             SetCapture(ParentForm.Handle);
  134.            end;
  135.          end
  136.         else
  137.          begin
  138.           if FDown then PaintCaption(False);
  139.           if FButtonDown then
  140.            begin       
  141.             FButtonDown := False;
  142.             ReleaseCapture;
  143.            end;
  144.          end
  145.        else
  146.         if (Msg = wm_NCLButtonUp) or (Msg = wm_LButtonUp) then
  147.          begin
  148.           if FButtonDown then
  149.            begin
  150.             FButtonDown := False;
  151.             ReleaseCapture;
  152.             if FDown and Assigned(FOnClick) then
  153.              FOnClick(Self);
  154.            end;
  155.           if FDown then PaintCaption(False);
  156.          end
  157.         else
  158.          if (Msg = wm_Close) or (Msg = wm_Destroy) then
  159.           SeekAndDestroy := True;
  160.    end;
  161. end;
  162.  
  163. procedure TCaptionButton.PaintCaption(Down: Boolean);
  164. var
  165.   DC: hDC;
  166.   R: TRect;
  167.   Image: TBitmap;
  168.   LeftX, x, y, FrameY: Integer;
  169.   Shift: Byte;
  170.  
  171.   procedure DrawUpFrame;
  172.   begin
  173.     with Canvas do
  174.      begin
  175.       Pen.Color := clWhite;
  176.       MoveTo(LeftX, FrameY + y + 1);
  177.       LineTo(LeftX, FrameY);
  178.       LineTo(LeftX + x + 3, FrameY);
  179.       Pen.Color := clBlack;
  180.       MoveTo(LeftX, FrameY + y + 2);
  181.       LineTo(LeftX + x + 2, FrameY + y + 2);
  182.       LineTo(LeftX + x + 2, FrameY - 1);
  183.       Pen.Color := clGray;
  184.       MoveTo(LeftX + x + 1, FrameY + 1);
  185.       LineTo(LeftX + x + 1, FrameY + y + 1);
  186.       LineTo(LeftX, FrameY + y + 1);
  187.       Shift := 1;
  188.      end;
  189.   end;
  190.  
  191.   procedure DrawDownFrame;
  192.   begin
  193.     with Canvas do
  194.      begin
  195.       Pen.Color := clBlack;
  196.       MoveTo(LeftX, FrameY + y + 1);
  197.       LineTo(LeftX, FrameY);
  198.       LineTo(LeftX + x + 3, FrameY);
  199.       Pen.Color := clWhite;
  200.       MoveTo(LeftX, FrameY + y + 2);
  201.       LineTo(LeftX + x + 2, FrameY + y + 2);
  202.       LineTo(LeftX + x + 2, FrameY - 1);
  203.       Pen.Color := clGray;
  204.       MoveTo(LeftX + x, FrameY + 1);
  205.       LineTo(LeftX + 1, FrameY + 1);
  206.       LineTo(LeftX + 1, FrameY + y + 1);
  207.       Pen.Color := clSilver;
  208.       MoveTo(LeftX + x + 1, FrameY + 1);
  209.       LineTo(LeftX + x + 1, FrameY + y + 1);
  210.       LineTo(LeftX, FrameY + y + 1);
  211.       Shift := 2;
  212.      end;
  213.   end;
  214.  
  215. begin
  216.   FDown := Down;
  217.   if FVisible then
  218.    try
  219.     DC := GetWindowDC(ParentForm.Handle);
  220.     Canvas.Handle := DC;
  221.     Image := TBitmap.Create;
  222.     GetWindowRect(ParentForm.Handle, R);
  223.     R.Right := R.Right - R.Left;
  224.  
  225.     if ParentForm.BorderStyle = bsSingle then
  226.      {$IFDEF WIN32}
  227.      FrameY := GetSystemMetrics(sm_cyFrame) + 1
  228.      {$ELSE}
  229.      FrameY := GetSystemMetrics(sm_cyBorder) + 2
  230.      {$ENDIF}
  231.     else
  232.      if ParentForm.BorderStyle = bsDialog then
  233.       FrameY := GetSystemMetrics(sm_cyBorder) + 4
  234.      else
  235.       {$IFDEF WIN32}
  236.       if ParentForm.BorderStyle = bsSizeToolWin then
  237.        FrameY := GetSystemMetrics(sm_cySizeFrame) + 2
  238.       else
  239.        if ParentForm.BorderStyle = bsToolWindow then
  240.         FrameY := GetSystemMetrics(sm_cyBorder) + 4
  241.        else
  242.        {$ENDIF}
  243.         FrameY := GetSystemMetrics(sm_cyFrame) + 2;
  244.  
  245.     LeftX := R.Right - RightMargin - FrameY;
  246.     {$IFDEF WIN32}
  247.     if (ParentForm.BorderStyle = bsSizeToolWin) or
  248.        (ParentForm.BorderStyle = bsToolWindow) then
  249.      begin
  250.       y := GetSystemMetrics(sm_cySMCaption) - 8;
  251.       x := GetSystemMetrics(sm_cxSMSize) - 5;
  252.      end
  253.     else
  254.      begin
  255.       y := GetSystemMetrics(sm_cyCaption) - 8;
  256.       x := GetSystemMetrics(sm_cxSize) - 5;
  257.      end;
  258.     {$ELSE}
  259.     y := GetSystemMetrics(sm_cyCaption) - 9;
  260.     x := GetSystemMetrics(sm_cxSize) - 5;
  261.     {$ENDIF}
  262.     with ButtonRect do
  263.      begin
  264.       Left := LeftX - FrameY;
  265.       Top := FrameY;
  266.       Right := Left + x + 3;
  267.       Bottom := y + 2;
  268.      end;
  269.  
  270.     if Down then DrawDownFrame
  271.     else DrawUpFrame;
  272.     
  273.     StretchBlt(DC, LeftX + Shift,
  274.                FrameY + Shift,
  275.                x, y,
  276.                FGlyph.Canvas.Handle, 0, 0,
  277.                FGlyph.Width, FGlyph.Height,
  278.                srcCopy);
  279.  
  280.     Image.Free;
  281.    finally
  282.     ReleaseDC(ParentForm.Handle, DC);
  283.    end;
  284. end;
  285.  
  286. procedure TCaptionButton.SetRightMargin(Value: Integer);
  287. begin
  288.   if FRightMargin <> Value then
  289.    begin
  290.     FRightMargin := Value;
  291.     SendMessage(ParentForm.Handle, wm_NCActivate, 0, 0);
  292.    end;
  293. end;
  294.  
  295. procedure TCaptionButton.SetGlyph(Value: TBitmap);
  296. begin
  297.   if FGlyph <> Value then
  298.    begin
  299.     FGlyph.Assign(Value);
  300.     SendMessage(ParentForm.Handle, wm_NCActivate, 0, 0);
  301.    end;
  302. end;
  303.  
  304. procedure TCaptionButton.SetVisible(Value: Boolean);
  305. begin
  306.   if FVisible <> Value then
  307.    begin
  308.     FVisible := Value;
  309.     SendMessage(ParentForm.Handle, wm_NCActivate, 0, 0);
  310.    end;
  311. end;
  312.  
  313. procedure Register;
  314. begin
  315.   RegisterComponents('Xacker', [TCaptionButton]);
  316. end;
  317.  
  318. end.
  319.