home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kolekce / d56 / RMCTL.ZIP / rmPanel.pas < prev    next >
Pascal/Delphi Source File  |  2001-06-22  |  32KB  |  1,229 lines

  1. {================================================================================
  2. Copyright (C) 1997-2001 Mills Enterprise
  3.  
  4. Unit     : rmPanel
  5. Purpose  : This is a regular panel that has a splitter bar on the oppositly
  6.            aligned side
  7. Date     : 07-10-1999
  8. Author   : Ryan J. Mills
  9. Version  : 1.80
  10. ================================================================================}
  11.  
  12. unit rmPanel;
  13.  
  14. interface
  15.  
  16. uses windows, messages, graphics, classes, forms, controls, sysutils, extctrls;
  17.  
  18. {$I CompilerDefines.INC}
  19.  
  20. type
  21.   TrmCaptionPosition = (cpStandard, cpTopEdge);
  22.  
  23.   TrmPanel = class(TCustomPanel)
  24.   private
  25.     { Private }
  26.     FActiveControl: TWinControl;
  27.     fCapPos : TrmCaptionPosition;
  28.     FBrush: TBrush;
  29.     FDeltaPos: integer;
  30.     FDownPos: TPoint;
  31.     FLineDC: HDC;
  32.     FLineVisible, fPanelSizing: Boolean;
  33.     FMinSize: NaturalNumber;
  34.     FMaxSize: Integer;
  35.     FNewSize: Integer;
  36.     FOldKeyDown: TKeyEvent;
  37.     FOldSize: Integer;
  38.     FPrevBrush: HBrush;
  39.     FResizeStyle: TResizeStyle;
  40.     FSplit: Integer;
  41.     FOnCanResize: TCanResizeEvent;
  42.     FOnMoved: TNotifyEvent;
  43.     fonVisibleChanged: TNotifyEvent;
  44.     fResizeBtn: boolean;
  45.     fLastOpenSize: integer;
  46.     fMouseOverBtn: boolean;
  47.     fBtnDown: boolean;
  48.     fDotCount: integer;
  49.     fResizing: boolean;
  50.     fSplitterPanel: boolean;
  51.     fIBWidth: integer;
  52.     procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  53.     function CanResize(var NewSize: Integer): Boolean; {$IFDEF D4_OR_HIGHER} reintroduce; {$ENDIF} virtual;
  54.     procedure CMVisibleChanged(var Message: TMessage); message CM_VISIBLECHANGED;
  55.     procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
  56.     procedure CMParentFontChanged(var Message: TMessage); message CM_PARENTFONTCHANGED;
  57.     procedure SetResizeBtn(const Value: boolean);
  58.     procedure SetDotCount(const Value: integer);
  59.     procedure SetSplitterPanel(const Value: boolean);
  60.     procedure SetCapPos(const Value: TrmCaptionPosition);
  61.     procedure SetIBWidth(const Value: integer);
  62.     procedure UpdateSize(X, Y: Integer);
  63.     procedure CalcSplitSize(X, Y: Integer; var NewSize, Split: Integer);
  64.     procedure AllocateLineDC;
  65.     procedure DrawLine;
  66.     procedure ReleaseLineDC;
  67.     procedure FocusKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  68.     procedure StopSizing;
  69.     function DoCanResize(var NewSize: Integer): Boolean;
  70.     procedure UpdateControlSize;
  71.     function Convert(wRect:TRect):TRect;
  72.  
  73.     procedure WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo); message WM_GETMINMAXINFO;
  74.     procedure WMNCCalcSize(var Message: TWMNCCalcSize) ; message WM_NCCALCSIZE;
  75.     procedure WMNCPaint(var Message: TMessage) ; message WM_NCPAINT;
  76.     procedure WMNCHitTest(var Message: TWMNCHitTest) ; message WM_NCHITTEST;
  77.     procedure WMNCLButtonDown(var Message: TWMNCLButtonDown) ; message WM_NCLBUTTONDOWN;
  78.     procedure WMNCMouseMove(var Message: TWMNCMouseMove) ; message WM_NCMOUSEMOVE;
  79.     procedure WMLButtonUp(var Message: TWMLButtonUp) ; message WM_LBUTTONUP;
  80.   protected
  81.     { Protected }
  82.     function GripSize: integer;
  83.     function GripRect: TRect;
  84.     function BtnRect: TRect;
  85.     procedure PaintGrip;
  86.     procedure Paint; override;
  87.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  88.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  89.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  90.   public
  91.     { Public }
  92.     constructor create(AOwner: TComponent); override;
  93.     function GetClientRect: TRect; override;
  94.     procedure AdjustClientRect(var Rect: TRect); override;
  95.     property DockManager;
  96.   published
  97.     { Published }
  98.     property Align;
  99.     property Alignment;
  100.     property Anchors;
  101.     property AutoSize;
  102.     property BevelInner;
  103.     property BevelOuter default bvNone;
  104.     property BevelWidth;
  105.     property BiDiMode;
  106.     property BorderWidth;
  107.     property InternalBorderWidth : integer read fIBWidth write SetIBWidth default 0;
  108.     property Caption;
  109.     property CaptionPosition : TrmCaptionPosition read fCapPos write SetCapPos default cpStandard;
  110.     property Color;
  111.     property Constraints;
  112.     property Ctl3D;
  113.     property SplitterPanel: boolean read fSplitterPanel write SetSplitterPanel default false;
  114.     property UseDockManager default True;
  115.     property DotCount: integer read fDotCount write SetDotCount default 10;
  116.     property DockSite;
  117.     property DragCursor;
  118.     property DragKind;
  119.     property DragMode;
  120.     property Enabled;
  121.     property FullRepaint;
  122.     property Font;
  123.     property Locked;
  124.     property MinSize: NaturalNumber read FMinSize write FMinSize default 30;
  125.     property ParentBiDiMode;
  126.     property ParentColor;
  127.     property ParentCtl3D;
  128.     property ParentFont;
  129.     property ParentShowHint;
  130.     property PopupMenu;
  131.     property ResizeStyle: TResizeStyle read FResizeStyle write FResizeStyle default rsPattern;
  132.     property ResizeBtn: boolean read fResizeBtn write SetResizeBtn default false;
  133.     property ShowHint;
  134.     property TabOrder;
  135.     property TabStop;
  136.     property Visible;
  137.     property OnCanResize;
  138.     property OnClick;
  139.     property OnConstrainedResize;
  140.     property OnDockDrop;
  141.     property OnDockOver;
  142.     property OnDblClick;
  143.     property OnDragDrop;
  144.     property OnDragOver;
  145.     property OnEndDock;
  146.     property OnEndDrag;
  147.     property OnEnter;
  148.     property OnExit;
  149.     property OnGetSiteInfo;
  150.     property OnMouseDown;
  151.     property OnMouseMove;
  152.     property OnMouseUp;
  153.     property OnResize;
  154.     property OnStartDock;
  155.     property OnStartDrag;
  156.     property OnUnDock;
  157.     property OnVisibleChanged: TNotifyEvent read fOnVisibleChanged write fOnVisibleChanged;
  158.   end;
  159.  
  160. implementation
  161.  
  162. {$R *.RES}
  163.  
  164. uses rmLibrary;
  165.  
  166. { TrmPanel }
  167.  
  168. const
  169.   DotSize = 4;
  170.  
  171. type
  172.   TWinControlAccess = class(TWinControl);
  173.  
  174. procedure TrmPanel.CMMouseLeave(var Message: TMessage);
  175. begin
  176.   inherited;
  177.   Cursor := crDefault;
  178.   fMouseOverBtn := false;
  179.   PaintGrip;
  180. end;
  181.  
  182. constructor TrmPanel.create(AOwner: TComponent);
  183. begin
  184.   inherited create(AOwner);
  185.   Caption := '';
  186.   fCapPos := cpStandard;
  187.   fIBWidth := 0;
  188.   BevelOuter := bvNone;
  189.   BevelInner := bvNone;
  190.   FMinSize := 30;
  191.   FResizeStyle := rsPattern;
  192.   FOldSize := -1;
  193.   fPanelSizing := false;
  194.   FDeltaPos := 0;
  195.   fResizeBtn := false;
  196.   fLastOpenSize := 0;
  197.   fMouseOverBtn := false;
  198.   fBtnDown := false;
  199.   fDotCount := 10;
  200.   fResizing := false;
  201.   fSplitterPanel := false;
  202. end;
  203.  
  204. function TrmPanel.GetClientRect: TRect;
  205. var
  206.   wRect: TRect;
  207. begin
  208.   wRect := inherited GetClientRect;
  209.   if CaptionPosition = cpTopEdge then
  210.   begin
  211.      Canvas.Font := Self.Font;
  212.      wRect.Top := wRect.Top + Canvas.textHeight('W');
  213.   end;
  214.   result := wRect;
  215. end;
  216.  
  217. function TrmPanel.GripRect: TRect;
  218. var
  219.   wRect: TRect;
  220. begin
  221.   case align of
  222.     alTop: wRect := Rect(0, height - gripsize, width, height);
  223.     alBottom: wRect := Rect(0, -GripSize, width, 0);
  224.     alLeft: wRect := Rect(width - gripsize, 0, width, height);
  225.     alRight: wRect := Rect(-GripSize, 0, 0, height);
  226.   else
  227.     wRect := Rect(-1, -1, -1, -1);
  228.   end;
  229.   result := wRect;
  230. end;
  231.  
  232.  
  233. procedure TrmPanel.UpdateControlSize;
  234. begin
  235.   if FNewSize <> FOldSize then
  236.   begin
  237.     case Align of
  238.       alLeft: Width := FNewSize;
  239.       alTop: Height := FNewSize;
  240.       alRight:
  241.         begin
  242.           Parent.DisableAlign;
  243.           try
  244.             Width := FNewSize;
  245.           finally
  246.             Parent.EnableAlign;
  247.           end;
  248.  
  249.           parent.realign;
  250.         end;
  251.       alBottom:
  252.         begin
  253.           Parent.DisableAlign;
  254.           try
  255.             Height := FNewSize;
  256.           finally
  257.             Parent.EnableAlign;
  258.           end;
  259.         end;
  260.     end;
  261.     Update;
  262.     if Assigned(FOnMoved) then FOnMoved(Self);
  263.     FOldSize := FNewSize;
  264.   end;
  265. end;
  266.  
  267. procedure TrmPanel.Paint;
  268. const
  269.   Alignments: array[TAlignment] of Longint = (DT_LEFT, DT_RIGHT, DT_CENTER);
  270. var
  271.   wRect: TRect;
  272.   TopColor, BottomColor: TColor;
  273.   FontHeight: Integer;
  274.   Flags: Longint;
  275.  
  276.   procedure AdjustColors(Bevel: TPanelBevel);
  277.   begin
  278.     TopColor := clBtnHighlight;
  279.     if Bevel = bvLowered then TopColor := clBtnShadow;
  280.     BottomColor := clBtnShadow;
  281.     if Bevel = bvLowered then BottomColor := clBtnHighlight;
  282.   end;
  283.  
  284. begin
  285.   if CaptionPosition = cpStandard then
  286.   begin
  287.      inherited;
  288.   end
  289.   else
  290.   begin
  291.      with Canvas do
  292.      begin
  293.        Font := Self.Font;
  294.        FontHeight := TextHeight('W');
  295.        Brush.Color := Color;
  296.        FillRect(Rect(0,0,width,height));
  297.      end;
  298.  
  299.      wRect := ClientRect;
  300.      wRect.Top := wRect.Top - (FontHeight div 2);
  301.  
  302.      if BevelOuter <> bvNone then
  303.      begin
  304.        AdjustColors(BevelOuter);
  305.        Frame3D(Canvas, wRect, TopColor, BottomColor, BevelWidth);
  306.      end;
  307.      Frame3D(Canvas, wRect, Color, Color, BorderWidth);
  308.      if BevelInner <> bvNone then
  309.      begin
  310.        AdjustColors(BevelInner);
  311.        Frame3D(Canvas, wRect, TopColor, BottomColor, BevelWidth);
  312.      end;
  313.  
  314.      with Canvas do
  315.      begin
  316.        wRect := GetClientRect;
  317.  
  318.        wRect.Top := wRect.Top - FontHeight;
  319.        wRect.Bottom := Top + FontHeight;
  320.  
  321.        Case Alignment of
  322.           taLeftJustify:
  323.              begin
  324.                  wRect.Left := 8;
  325.                  wRect.Right := wRect.Left + TextWidth(Caption);
  326.              end;
  327.           taRightJustify:
  328.              begin
  329.                  wRect.Right := wRect.Right - 8;
  330.                  wRect.Left := wRect.Right - TextWidth(Caption);
  331.              end;
  332.           taCenter:
  333.              begin
  334.                 Try
  335.                    wRect.Left := (width - TextWidth(Caption)) div 2;
  336.                 except
  337.                    wRect.Left := 0; 
  338.                 end;
  339.                 wRect.right := wRect.Left+TextWidth(caption)+1;  
  340.              end;
  341.        end;
  342.  
  343.        OffsetRect(wRect, Borderwidth, BorderWidth);
  344.  
  345.        Flags := DT_EXPANDTABS or DT_VCENTER or DT_CENTER;
  346.        Flags := DrawTextBiDiModeFlags(Flags);
  347.        DrawText(Handle, PChar(Caption), -1, wRect, Flags);
  348.      end;
  349.   end;
  350.   PaintGrip;
  351. end;
  352.  
  353. procedure TrmPanel.CMVisibleChanged(var Message: TMessage);
  354. begin
  355.   inherited;
  356.   if assigned(fonVisibleChanged) then
  357.     fOnVisibleChanged(self);
  358. end;
  359.  
  360. procedure TrmPanel.SetResizeBtn(const Value: boolean);
  361. begin
  362.   if fResizeBtn <> Value then
  363.   begin
  364.     fResizeBtn := Value;
  365.     Realign;
  366.     Invalidate;
  367.   end;
  368. end;
  369.  
  370. function TrmPanel.GripSize: integer;
  371. begin
  372.   if fResizeBtn then
  373.     result := 6
  374.   else
  375.     result := 3;
  376. end;
  377.  
  378. function TrmPanel.BtnRect: TRect;
  379. var
  380.   wRect: TRect;
  381.   wGripH, wGripW: integer;
  382. begin
  383.   wrect := GripRect;
  384.   wGripH := wRect.Bottom - wrect.Top;
  385.   wGripW := wRect.Right - wrect.Left;
  386.   case Align of
  387.     alTop, alBottom:
  388.       begin
  389.         result.Left := ((wGripW div 2) - ((DotCount * DotSize) div 2));
  390.         result.right := result.left + (DotCount * DotSize);
  391.         if align = altop then
  392.         begin
  393.           result.top := Height - wGripH;
  394.           result.Bottom := height;
  395.         end
  396.         else
  397.         begin
  398.           result.top := -wGripH;
  399.           result.Bottom := 0;
  400.         end;
  401.         InflateRect(result, 12, 0);
  402.       end;
  403.     alLeft, alRight:
  404.       begin
  405.         result.Top := ((wGripH div 2) - ((DotCount * DotSize) div 2));
  406.         result.Bottom := result.Top + (DotCount * DotSize);
  407.         if align = alLeft then
  408.         begin
  409.           result.Left := Width - wGripW;
  410.           result.Right := Width;
  411.         end
  412.         else
  413.         begin
  414.           result.Left := -wGripW;
  415.           result.Right := 0;
  416.         end;
  417.         InflateRect(result, 0, 12);
  418.       end;
  419.   else
  420.     result := Rect(0, 0, 0, 0);
  421.   end;
  422. end;
  423.  
  424. procedure TrmPanel.SetDotCount(const Value: integer);
  425. begin
  426.   if (value >= 5) and (value <= 20) then
  427.   begin
  428.     fDotCount := value;
  429.     PaintGrip;
  430.   end
  431.   else
  432.     raise ERangeError.Create('Value must be between 5 and 20');
  433. end;
  434.  
  435. procedure TrmPanel.PaintGrip;
  436. var
  437.   DC : HDC;
  438.   loop: integer;
  439.   wrect: TRect;
  440.   adjust: integer;
  441.   wBmp: TBitmap;
  442.   wArrow: TBitmap;
  443.   wxpos, wypos : integer;
  444. begin
  445.   if not (SplitterPanel or ResizeBtn) then
  446.      exit;
  447.  
  448.   wBmp := TBitMap.create;
  449.   try
  450.     wRect := GripRect;
  451.     wBmp.Height := wRect.Bottom - wRect.Top;
  452.     wBmp.Width := wRect.Right - wRect.Left;
  453.  
  454.     wBmp.canvas.brush.color := Color;
  455.     wBmp.canvas.FillRect(Rect(0, 0, wbmp.width, wbmp.height));
  456.  
  457.     if fResizeBtn then
  458.     begin
  459.       wrect := BtnRect;
  460.  
  461.       if (align in [albottom, alTop]) then
  462.       begin
  463.         OffsetRect(wRect, 0, -wRect.Top);
  464.         for loop := 0 to DotCount - 1 do
  465.         begin
  466.           adjust := (loop * DotSize) + 12;
  467.           wBmp.canvas.pixels[wRect.Left + 1 + adjust, wRect.Top + 1] := clbtnhighlight;
  468.           wBmp.canvas.pixels[wRect.Left + 2 + adjust, wRect.Top + 1] := clHighlight;
  469.           wBmp.canvas.pixels[wRect.Left + 1 + adjust, wRect.Top + 2] := clHighlight;
  470.           wBmp.canvas.pixels[wRect.Left + 2 + adjust, wRect.Top + 2] := clHighlight;
  471.  
  472.           if loop < DotCount then
  473.           begin
  474.             wBmp.canvas.pixels[wRect.Left + 3 + adjust, wRect.Top + 3] := clbtnhighlight;
  475.             wBmp.canvas.pixels[wRect.Left + 4 + adjust, wRect.Top + 3] := clHighlight;
  476.             wBmp.canvas.pixels[wRect.Left + 3 + adjust, wRect.Top + 4] := clHighlight;
  477.             wBmp.canvas.pixels[wRect.Left + 4 + adjust, wRect.Top + 4] := clHighlight;
  478.           end;
  479.         end;
  480.  
  481.         wArrow := TBitmap.create;
  482.         try
  483.           if fLastOpenSize = 0 then
  484.           begin
  485.             if align = altop then
  486.               wArrow.LoadFromResourceName(Hinstance, 'RMPUPARROW')
  487.             else
  488.               wArrow.LoadFromResourceName(Hinstance, 'RMPDNARROW');
  489.           end
  490.           else
  491.           begin
  492.             if align = alBottom then
  493.               wArrow.LoadFromResourceName(Hinstance, 'RMPUPARROW')
  494.             else
  495.               wArrow.LoadFromResourceName(Hinstance, 'RMPDNARROW');
  496.           end;
  497.  
  498.           ReplaceColors(wArrow, Color, clHighLight);
  499.  
  500.           wBmp.Canvas.Draw(wRect.Left + 1, wRect.Top + 2, wArrow);
  501.           wBmp.Canvas.Draw((wRect.Right - 1) - wArrow.width, wRect.Top + 2, wArrow);
  502.  
  503.         finally
  504.           wArrow.free;
  505.         end;
  506.  
  507.       end
  508.       else if (align in [alLeft, alRight]) then
  509.       begin
  510.         OffsetRect(wRect, -wRect.Left, 0);
  511.         for loop := 0 to DotCount - 1 do
  512.         begin
  513.           adjust := (loop * DotSize) + 12;
  514.           wBmp.canvas.pixels[wRect.Left + 1, wRect.Top + 1 + adjust] := clbtnhighlight;
  515.           wBmp.canvas.pixels[wRect.Left + 1, wRect.Top + 2 + adjust] := clHighlight;
  516.           wBmp.canvas.pixels[wRect.Left + 2, wRect.Top + 1 + adjust] := clHighlight;
  517.           wBmp.canvas.pixels[wRect.Left + 2, wRect.Top + 2 + adjust] := clHighlight;
  518.  
  519.           if loop < DotCount then
  520.           begin
  521.             wBmp.canvas.pixels[wRect.Left + 3, wRect.Top + 2 + adjust] := clbtnhighlight;
  522.             wBmp.canvas.pixels[wRect.Left + 3, wRect.Top + 4 + adjust] := clHighlight;
  523.             wBmp.canvas.pixels[wRect.Left + 4, wRect.Top + 3 + adjust] := clHighlight;
  524.             wBmp.canvas.pixels[wRect.Left + 4, wRect.Top + 4 + adjust] := clHighlight;
  525.           end;
  526.         end;
  527.  
  528.         wArrow := TBitmap.create;
  529.         try
  530.           if fLastOpenSize = 0 then
  531.           begin
  532.             if align = alLeft then
  533.               wArrow.LoadFromResourceName(Hinstance, 'RMPLTARROW')
  534.             else
  535.               wArrow.LoadFromResourceName(Hinstance, 'RMPRTARROW');
  536.           end
  537.           else
  538.           begin
  539.             if align = alRight then
  540.               wArrow.LoadFromResourceName(Hinstance, 'RMPLTARROW')
  541.             else
  542.               wArrow.LoadFromResourceName(Hinstance, 'RMPRTARROW');
  543.           end;
  544.           ReplaceColors(wArrow, Color, clHighLight);
  545.  
  546.           wBmp.Canvas.Draw(wRect.Left + 2, wRect.Top + 1, wArrow);
  547.           wBmp.Canvas.Draw(wRect.Left + 2, (wRect.Bottom - 1) - wArrow.Height, wArrow);
  548.         finally
  549.           wArrow.free;
  550.         end;
  551.  
  552.       end;
  553.  
  554.       if fMouseOverBtn then
  555.       begin
  556.         if fBtnDown then
  557.           Frame3D(wBmp.Canvas, wRect, clbtnshadow, clbtnhighlight, 1)
  558.         else
  559.           Frame3D(wBmp.Canvas, wRect, clbtnhighlight, clbtnshadow, 1);
  560.       end;
  561.     end;
  562.     wRect := GripRect;
  563.  
  564.     wxpos := 0;
  565.     wypos := 0;
  566.     case align of
  567.       albottom, alright:
  568.          begin
  569.            wxpos := 0;
  570.            wypos := 0;
  571.          end;
  572.       alleft :
  573.          begin
  574.             wxpos := width-wbmp.width;
  575.             wypos := 0;
  576.          end;
  577.       altop :
  578.          begin
  579.             wxpos := 0;
  580.             wypos := height-wbmp.height;
  581.          end;
  582.     end;
  583.  
  584.     DC := GetWindowDC(Handle) ;
  585.     try
  586.        BitBlt(DC, wxpos, wypos, wBMP.width, wBMP.height, wBMP.Canvas.Handle, 0, 0, SRCCOPY) ;
  587.     finally
  588.        ReleaseDC(Handle, DC) ;
  589.     end;
  590.  
  591.  
  592. //    Canvas.Draw(wRect.Left, wRect.Top, wBmp);
  593.   finally
  594.     wBmp.free;
  595.   end;
  596. end;
  597.  
  598. procedure TrmPanel.SetSplitterPanel(const Value: boolean);
  599. begin
  600.   if fSplitterPanel <> Value then
  601.   begin
  602.     fSplitterPanel := Value;
  603.     Realign;
  604.     Invalidate;
  605.   end;
  606. end;
  607.  
  608. procedure TrmPanel.SetCapPos(const Value: TrmCaptionPosition);
  609. begin
  610.   if fCapPos <> Value then
  611.   begin
  612.      fCapPos := Value;
  613.      Realign;
  614.      Invalidate;
  615.   end;
  616. end;
  617.  
  618. procedure TrmPanel.SetIBWidth(const Value: integer);
  619. begin
  620.   if fIBWidth <> Value then
  621.   begin
  622.      fIBWidth := Value;
  623.      Realign;
  624.      invalidate;
  625.   end;
  626. end;
  627.  
  628. procedure TrmPanel.AdjustClientRect(var Rect: TRect);
  629. begin
  630.   inherited AdjustClientRect(Rect);
  631.   InflateRect(Rect, -fIBWidth, -fIBWidth);
  632. end;
  633.  
  634. procedure TrmPanel.CMFontChanged(var Message: TMessage);
  635. begin
  636.    Inherited;
  637.    Realign;
  638.    Invalidate;
  639. end;
  640.  
  641. procedure TrmPanel.CMParentFontChanged(var Message: TMessage);
  642. begin
  643.    Inherited;
  644.    Realign;
  645.    Invalidate;
  646. end;
  647.  
  648. procedure TrmPanel.WMNCCalcSize(var Message: TWMNCCalcSize);
  649. begin
  650.    inherited;
  651.  
  652.    if SplitterPanel or ResizeBtn then
  653.    begin
  654.       with Message.CalcSize_Params^ do
  655.       begin
  656.         case align of
  657.           alTop: rgrc[0].Bottom := rgrc[0].Bottom - GripSize;
  658.           alBottom: rgrc[0].Top := rgrc[0].Top + GripSize;
  659.           alLeft: rgrc[0].Right := rgrc[0].Right - GripSize;
  660.           alRight: rgrc[0].Left := rgrc[0].Left + GripSize;
  661.         end;
  662.       end;
  663.    end;
  664. end;
  665.  
  666. procedure TrmPanel.WMNCPaint(var Message: TMessage);
  667. begin
  668.    if SplitterPanel or ResizeBtn then
  669.    begin
  670.       PaintGrip;
  671.       Message.result := 0;
  672.    end
  673.    else
  674.    inherited;
  675. end;
  676.  
  677. procedure TrmPanel.WMNCHitTest(var Message: TWMNCHitTest);
  678. var
  679.    wpt: TPoint;
  680. begin
  681.    if csDesigning in ComponentState then
  682.    begin
  683.       inherited;
  684.       exit;
  685.    end;
  686.  
  687.    if SplitterPanel or ResizeBtn then
  688.    begin
  689.       wpt := Point(Message.XPos, Message.YPos) ;
  690.  
  691.       if resizebtn and ptinrect(Convert(btnrect),wpt) then
  692.       begin
  693.          fMouseOverBtn := true;
  694.          message.result := htCaption;
  695.       end
  696.       else
  697.       begin
  698.           fMouseOverBtn := false;
  699.  
  700.           if splitterpanel and ptinrect(convert(GripRect),wpt) then
  701.           begin
  702.             if (fLastOpenSize = 0) then
  703.                message.result := htClient
  704.             else
  705.                Message.Result := htnowhere;
  706.           end
  707.           else
  708.             message.result := htClient
  709.       end;
  710.    end
  711.    else
  712.    begin
  713.       fMouseOverBtn := false;
  714.       inherited;
  715.    end;
  716. end;
  717.  
  718. function TrmPanel.Convert(wRect: TRect): TRect;
  719. begin
  720.    result.topleft := clienttoscreen(wrect.topleft);
  721.    result.bottomright := clienttoscreen(wrect.bottomright);
  722. end;
  723.  
  724. procedure TrmPanel.UpdateSize(X, Y: Integer);
  725. begin
  726.   CalcSplitSize(X, Y, FNewSize, FSplit);
  727. end;
  728.  
  729. procedure TrmPanel.CalcSplitSize(X, Y: Integer; var NewSize, Split: Integer);
  730. var
  731.   S: Integer;
  732. begin
  733.   if Align in [alLeft, alRight] then
  734.     Split := X - FDownPos.X
  735.   else
  736.     Split := Y - FDownPos.Y;
  737.   S := 0;
  738.   case Align of
  739.     alLeft: S := Width + Split;
  740.     alRight: S := Width - Split;
  741.     alTop: S := Height + Split;
  742.     alBottom: S := Height - Split;
  743.   end;
  744.   NewSize := S;
  745.   if S < FMinSize then
  746.     NewSize := FMinSize
  747.   else if S > FMaxSize then
  748.     NewSize := FMaxSize;
  749.   if S <> NewSize then
  750.   begin
  751.     if Align in [alRight, alBottom] then
  752.       S := S - NewSize else
  753.       S := NewSize - S;
  754.     Inc(Split, S);
  755.   end;
  756. end;
  757.  
  758. procedure TrmPanel.AllocateLineDC;
  759. begin
  760.   FLineDC := GetDCEx(Parent.Handle, 0, DCX_CACHE or DCX_CLIPSIBLINGS
  761.     or DCX_LOCKWINDOWUPDATE);
  762.   if ResizeStyle = rsPattern then
  763.   begin
  764.     if FBrush = nil then
  765.     begin
  766.       FBrush := TBrush.Create;
  767.       FBrush.Bitmap := AllocPatternBitmap(clBlack, clWhite);
  768.     end;
  769.     FPrevBrush := SelectObject(FLineDC, FBrush.Handle);
  770.   end;
  771. end;
  772.  
  773. procedure TrmPanel.DrawLine;
  774. var
  775.   P: TPoint;
  776.   h, w: integer;
  777.   wRect: TRect;
  778. begin
  779.   wRect := GripRect;
  780.   wRect.TopLeft := Parent.ScreenToClient(Self.ClientToScreen(wRect.TopLeft));
  781.   wRect.BottomRight := Parent.ScreenToClient(Self.ClientToScreen(wRect.BottomRight));
  782.  
  783.   FLineVisible := not FLineVisible;
  784.   case Align of
  785.     alLeft:
  786.       begin
  787.         P.X := wRect.left + FDeltaPos;
  788.         P.Y := Top;
  789.         h := height;
  790.         w := GripSize;
  791.       end;
  792.     alRight:
  793.       begin
  794.         P.X := left + FDeltaPos;
  795.         P.Y := Top;
  796.         h := height;
  797.         w := GripSize;
  798.       end;
  799.     alBottom:
  800.       begin
  801.         P.X := 0;
  802.         P.Y := top + FDeltaPos;
  803.         h := GripSize;
  804.         w := width;
  805.       end;
  806.     alTop:
  807.       begin
  808.         P.X := 0;
  809.         P.Y := wRect.top + FDeltaPos;
  810.         h := GripSize;
  811.         w := width;
  812.       end;
  813.   else
  814.     exit;
  815.   end;
  816.   with P do PatBlt(FLineDC, X, Y, W, H, PATINVERT);
  817. end;
  818.  
  819. procedure TrmPanel.ReleaseLineDC;
  820. begin
  821.   if FPrevBrush <> 0 then
  822.     SelectObject(FLineDC, FPrevBrush);
  823.   ReleaseDC(Parent.Handle, FLineDC);
  824.   if FBrush <> nil then
  825.   begin
  826.     FBrush.Free;
  827.     FBrush := nil;
  828.   end;
  829. end;
  830.  
  831. procedure TrmPanel.FocusKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  832. begin
  833.   if Key = VK_ESCAPE then
  834.     StopSizing
  835.   else if Assigned(FOldKeyDown) then
  836.     FOldKeyDown(Sender, Key, Shift);
  837. end;
  838.  
  839. procedure TrmPanel.StopSizing;
  840. begin
  841.   if FLineVisible then DrawLine;
  842.   ReleaseLineDC;
  843.   if Assigned(FActiveControl) then
  844.   begin
  845.     TWinControlAccess(FActiveControl).OnKeyDown := FOldKeyDown;
  846.     FActiveControl := nil;
  847.   end;
  848.   if Assigned(FOnMoved) then
  849.     FOnMoved(Self);
  850. end;
  851.  
  852. function TrmPanel.CanResize(var NewSize: Integer): Boolean;
  853. begin
  854.   Result := True;
  855.   if Assigned(FOnCanResize) then FOnCanResize(Self, NewSize, Result);
  856. end;
  857.  
  858. function TrmPanel.DoCanResize(var NewSize: Integer): Boolean;
  859. begin
  860.   Result := CanResize(NewSize);
  861.   if Result then
  862.   begin
  863.      NewSize := SetInRange(NewSize, fMinsize, fMaxSize);
  864.   end;
  865. end;
  866.  
  867. procedure TrmPanel.WMNCLButtonDown(var Message: TWMNCLButtonDown);
  868. var
  869.   wPt: TPoint;
  870.   wCloseBtn: boolean;
  871. begin
  872.    if csDesigning in ComponentState then
  873.    begin
  874.       inherited;
  875.       exit;
  876.    end;
  877.  
  878.   if ResizeBtn then
  879.   begin
  880.      wPt := Point(message.XCursor, message.YCursor);
  881.      wCloseBtn := (ResizeBtn and PtInRect(convert(BtnRect), wPt));
  882.  
  883.      if wCloseBtn then
  884.      begin
  885.         SendCancelMode(Self) ;
  886.         MouseCapture := true;
  887.      end;
  888.  
  889.      if wCloseBtn then
  890.      begin
  891.        fBtnDown := true;
  892.        PaintGrip;
  893.      end
  894.      else
  895.      begin
  896.        fBtnDown := false;
  897.      end;
  898.  
  899.      Message.result := 0;
  900.   end
  901.   else
  902.   inherited;
  903. end;
  904.  
  905. procedure TrmPanel.WMLButtonUp(var Message: TWMLButtonUp);
  906. var
  907.    wbtndown : boolean;
  908.    wpt : tpoint;
  909. begin
  910.    if csDesigning in ComponentState then
  911.    begin
  912.       inherited;
  913.       exit;
  914.    end;
  915.  
  916.    wBtnDown := fBtnDown;
  917.    fBtnDown := false;
  918.    MouseCapture := false;
  919.    PaintGrip;
  920.    wpt := point(message.XPos, Message.YPos);
  921.    if wBtnDown and ptInRect(btnrect, wpt) then
  922.    begin
  923.       if (fLastOpenSize <> 0) then
  924.       begin
  925.         case align of
  926.           alTop, alBottom: clientheight := fLastOpenSize;
  927.           alLeft, alRight: clientWidth := fLastOpenSize;
  928.         end;
  929.         fLastOpenSize := 0;
  930.       end
  931.       else
  932.       begin
  933.         case align of
  934.           alTop:
  935.             begin
  936.               fLastOpenSize := clientheight;
  937.               clientheight := 0;
  938.             end;
  939.           alBottom:
  940.             begin
  941.               Parent.DisableAlign;
  942.               try
  943.                 fLastOpenSize := clientheight;
  944.                 clientheight := 0;
  945.               finally
  946.                 Parent.EnableAlign;
  947.               end;
  948.             end;
  949.           alLeft:
  950.             begin
  951.               fLastOpenSize := clientWidth;
  952.               clientWidth := 0;
  953.             end;
  954.           alRight:
  955.             begin
  956.               Parent.DisableAlign;
  957.               try
  958.                 fLastOpenSize := clientWidth;
  959.                 clientWidth := 0;
  960.               finally
  961.                 Parent.EnableAlign;
  962.               end;
  963.             end;
  964.         end;
  965.         realign;
  966.       end;
  967.       Message.Result := 0;
  968.    end
  969.    else
  970.       inherited;
  971. end;
  972.  
  973. procedure TrmPanel.WMNCMouseMove(var Message: TWMNCMouseMove);
  974. var
  975.    wpt : Tpoint;
  976. begin
  977.    if csDesigning in ComponentState then
  978.    begin
  979.       inherited;
  980.       exit;
  981.    end;
  982.  
  983.    inherited;
  984.  
  985.    wPt := Point(message.XCursor, message.YCursor);
  986.  
  987.    fMouseOverBtn := (ResizeBtn and PtInRect(Convert(BtnRect), wPt));
  988.  
  989.    if SplitterPanel and PtInRect(convert(GripRect), wPt) and not (fMouseOverBtn) and (fLastOpenSize = 0) then
  990.    begin
  991.      case align of
  992.        alTop, alBottom: Cursor := crVSplit;
  993.        alRight, alLeft: Cursor := crHSplit;
  994.      else
  995.        Cursor := crDefault;
  996.      end;
  997.    end
  998.    else
  999.      Cursor := crDefault;
  1000.  
  1001.    PaintGrip;
  1002. end;
  1003.  
  1004. procedure TrmPanel.WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo);
  1005. begin
  1006.   inherited;
  1007.   if not (csReading in ComponentState) and Fresizing then
  1008.     with Message.MinMaxInfo^.ptMinTrackSize do
  1009.     begin
  1010.       case align of
  1011.          alright, alLeft:
  1012.             begin
  1013.                if x < fMinsize then
  1014.                   x := fMinsize;
  1015.  
  1016.                if x < GripSize then
  1017.                   x := gripsize;
  1018.             end;
  1019.          alTop, alBottom:
  1020.             begin
  1021.                if y < fMinsize then
  1022.                   y := fMinsize;
  1023.  
  1024.                if y < GripSize then
  1025.                   y := gripsize;
  1026.             end;
  1027.       end;
  1028.     end;
  1029. end;
  1030.  
  1031. procedure TrmPanel.MouseDown(Button: TMouseButton;
  1032.   Shift: TShiftState; X, Y: Integer);
  1033. var
  1034.   I: Integer;
  1035.   wPt: TPoint;
  1036.   wCloseBtn: boolean;
  1037. begin
  1038.   inherited MouseDown(Button, Shift, X, Y);
  1039.   wPt := Point(x, y);
  1040.   wCloseBtn := (fResizeBtn and PtInRect(BtnRect, wPt));
  1041.   if SplitterPanel and PtInRect(GripRect, wPt) and not wCloseBtn and (fLastOpenSize = 0) then
  1042.   begin
  1043.     fBtnDown := false;
  1044.     if Button = mbLeft then
  1045.     begin
  1046.       FPanelSizing := true;
  1047.       FDownPos := Point(X, Y);
  1048.       fDeltaPos := 0;
  1049.       if Align in [alLeft, alRight] then
  1050.       begin
  1051.         FMaxSize := Parent.ClientWidth;
  1052.         for I := 0 to Parent.ControlCount - 1 do
  1053.           with Parent.Controls[I] do
  1054.             if Align in [alLeft, alRight] then Dec(FMaxSize, Width);
  1055.         Inc(FMaxSize, Width);
  1056.       end
  1057.       else
  1058.       begin
  1059.         FMaxSize := Parent.ClientHeight;
  1060.         for I := 0 to Parent.ControlCount - 1 do
  1061.           with Parent.Controls[I] do
  1062.             if Align in [alTop, alBottom] then Dec(FMaxSize, Height);
  1063.         Inc(FMaxSize, Height);
  1064.       end;
  1065.       UpdateSize(X, Y);
  1066.       AllocateLineDC;
  1067.       with ValidParentForm(Self) do
  1068.         if ActiveControl <> nil then
  1069.         begin
  1070.           FActiveControl := ActiveControl;
  1071.           FOldKeyDown := TWinControlAccess(FActiveControl).OnKeyDown;
  1072.           TWinControlAccess(FActiveControl).OnKeyDown := FocusKeyDown;
  1073.         end;
  1074.       if ResizeStyle in [rsLine, rsPattern] then DrawLine;
  1075.     end;
  1076.   end
  1077.   else if (fResizeBtn and PtInRect(BtnRect, wPt) and (Button = mbLeft)) then
  1078.   begin
  1079.     fBtnDown := true;
  1080.     PaintGrip;
  1081.   end
  1082.   else
  1083.   begin
  1084.     fBtnDown := false;
  1085.   end;
  1086. end;
  1087.  
  1088. procedure TrmPanel.MouseMove(Shift: TShiftState; X, Y: Integer);
  1089. var
  1090.   wPt: TPoint;
  1091.   NewSize, Split: Integer;
  1092. begin
  1093.   inherited;
  1094.   if (ssLeft in Shift) and FPanelSizing then
  1095.   begin
  1096.     if ResizeStyle = rsUpdate then
  1097.     begin
  1098.         case align of
  1099.           alLeft: NewSize := x;
  1100.           alRight: NewSize := width - x;
  1101.           alTop: NewSize := y;
  1102.           alBottom: NewSize := height - y;
  1103.         else
  1104.           exit;
  1105.         end;
  1106.         if DoCanResize(NewSize) then
  1107.         begin
  1108.            fNewSize := newsize;
  1109.            UpdateControlSize;
  1110.         end;
  1111.     end
  1112.     else
  1113.     begin
  1114.       CalcSplitSize(X, Y, NewSize, Split);
  1115.       if DoCanResize(NewSize) then
  1116.       begin
  1117.         if ResizeStyle in [rsLine, rsPattern] then DrawLine;
  1118.         FNewSize := NewSize;
  1119.         FSplit := Split;
  1120.  
  1121.         case align of
  1122.           alLeft: fDeltaPos := x - fDownPos.x;
  1123.           alRight: fDeltaPos := x;
  1124.           alTop: fDeltaPos := y - fDownPos.y;
  1125.           alBottom: fDeltaPos := y;
  1126.         else
  1127.           fDeltaPos := 0;
  1128.         end;
  1129.  
  1130.         if ResizeStyle in [rsLine, rsPattern] then DrawLine;
  1131.       end;
  1132.     end;
  1133.   end
  1134.   else
  1135.   begin
  1136.     wPt := Point(x, y);
  1137.  
  1138.     fMouseOverBtn := (fResizeBtn and PtInRect(BtnRect, wPt));
  1139.  
  1140.     if SplitterPanel and PtInRect(GripRect, wPt) and not (fMouseOverBtn) and (fLastOpenSize = 0) then
  1141.     begin
  1142.       case align of
  1143.         alTop, alBottom: Cursor := crVSplit;
  1144.         alRight, alLeft: Cursor := crHSplit;
  1145.       else
  1146.         Cursor := crDefault;
  1147.       end;
  1148.     end
  1149.     else
  1150.       Cursor := crDefault;
  1151.  
  1152.     PaintGrip
  1153.   end;
  1154. end;
  1155.  
  1156. procedure TrmPanel.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
  1157.   Y: Integer);
  1158. var
  1159.   wPt: TPoint;
  1160. begin
  1161.   inherited;
  1162.   if FPanelSizing then
  1163.   begin
  1164.     fPanelSizing := false;
  1165.     if ResizeStyle in [rsLine, rsPattern] then DrawLine;
  1166.     UpdateControlSize;
  1167.     StopSizing;
  1168.   end
  1169.   else
  1170.   begin
  1171.     wPt := Point(x, y);
  1172.  
  1173.     if fResizeBtn and PtInRect(convert(BtnRect), wPt) and fBtnDown then
  1174.     begin
  1175.       if (fLastOpenSize <> 0) then
  1176.       begin
  1177.         case align of
  1178.           alTop, alBottom: clientheight := fLastOpenSize;
  1179.           alLeft, alRight: clientWidth := fLastOpenSize;
  1180.         end;
  1181.         fLastOpenSize := 0;
  1182.       end
  1183.       else
  1184.       begin
  1185.         case align of
  1186.           alTop:
  1187.             begin
  1188.               fLastOpenSize := clientheight;
  1189.               clientheight := 0;
  1190.             end;
  1191.           alBottom:
  1192.             begin
  1193.               Parent.DisableAlign;
  1194.               try
  1195.                 fLastOpenSize := clientheight;
  1196.                 clientheight := 0;
  1197.                 height := GripSize;
  1198.               finally
  1199.                 Parent.EnableAlign;
  1200.               end;
  1201.             end;
  1202.           alLeft:
  1203.             begin
  1204.               fLastOpenSize := clientWidth;
  1205.               clientWidth := 0;
  1206.             end;
  1207.           alRight:
  1208.             begin
  1209.               Parent.DisableAlign;
  1210.               try
  1211.                 fLastOpenSize := clientWidth;
  1212.                 clientWidth := 0;
  1213.                 width := GripSize;
  1214.               finally
  1215.                 Parent.EnableAlign;
  1216.               end;
  1217.             end;
  1218.         end;
  1219.         Update;
  1220.  
  1221.       end;
  1222.     end;
  1223.     fBtnDown := false;
  1224.   end;
  1225. end;
  1226.  
  1227. end.
  1228.  
  1229.