home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sibdemo3.zip / SOURCE.DAT / SOURCE / SPCC / DOCKTOOL.PAS < prev    next >
Pascal/Delphi Source File  |  1998-05-19  |  52KB  |  1,777 lines

  1.  
  2. {╔══════════════════════════════════════════════════════════════════════════╗
  3.  ║                                                                          ║
  4.  ║     Sibyl Portable Component Classes                                     ║
  5.  ║                                                                          ║
  6.  ║     Copyright (C) 1995,97 SpeedSoft Germany,   All rights reserved.      ║
  7.  ║                                                                          ║
  8.  ╚══════════════════════════════════════════════════════════════════════════╝}
  9.  
  10. Unit DockTool;
  11.  
  12. Interface
  13.  
  14. Uses Messages,SysUtils,Classes,Forms,StdCtrls,ExtCtrls;
  15.  
  16.  
  17. Type
  18.     {$M+}
  19.     TDockingEvent=Procedure(Sender:TObject;Var TargetForm:TForm;
  20.          Var NewAlign:TToolbarAlign) Of Object;
  21.  
  22.     TDockingState=(dsHide,dsDock,dsFloat);
  23.     {$M-}
  24.  
  25. Type
  26.     TDockingToolbar=Class(TPanel)
  27.       Private
  28.          FAutoAlign:Boolean;
  29.          FAutoWrap:Boolean;
  30.          FMargin:LongInt;
  31.          FState:TDockingState;
  32.          FResizing:Boolean;
  33.          FDragging:Boolean;
  34.          FPanelForm:TForm;
  35.          FDockingForm:TForm;
  36.          FToolAlign:TToolbarAlign;
  37.          FEnableDocking:TToolbarAlignments;
  38.          PanelBorderSizeX:LongInt;
  39.          PanelBorderSizeY:LongInt;
  40.          PanelTitleHeight:LongInt;
  41.          OldFgMode:TPenMode;
  42.          OldLineWidth:LongInt;
  43.          OldLineType:TPenStyle;
  44.          InitDrag:TPoint;
  45.          CurDrag:TPoint;
  46.          TryDocking:Boolean;
  47.          DraggingAborted:Boolean;
  48.          LastActiveControl:TControl;
  49.          LastDockToolbar:TToolbar;
  50.          LastDockLeft:LongInt;
  51.          LastDockBottom:LongInt;
  52.          LastDockWidth:LongInt;
  53.          LastDockHeight:LongInt;
  54.          UsePanelFormSize:Boolean;
  55.          FOnChange:TNotifyEvent;
  56.          FOnDocking:TDockingEvent;
  57.          Procedure UpdateTrackSize;
  58.          Procedure SetAutoWrap(Value:Boolean);
  59.          Procedure SetMargin(Value:LongInt);
  60.          Function IsDocked:Boolean;
  61.          Function GetState:TDockingState;
  62.          Procedure SetState(Value:TDockingState);
  63.          Function GetDockingForm:TForm;
  64.          Procedure UndockPanel;
  65.          Procedure DockPanel(ParentToolbar:TToolbar);
  66.          Procedure DockLastPanel;
  67.          Procedure HidePanel;
  68.          Procedure FloatPanel;
  69.          Procedure SetToolAlign(Value:TToolbarAlign);
  70.          Procedure SetDockingForm(AForm:TForm);
  71.          Function GetWrappedSize(Docked:Boolean;HorizToolbar:Boolean;
  72.                                  Var WrapWidth,WrapHeight:LongInt):Boolean;
  73.          Function GetToolbarMaxSize(ParentToolbar:TToolbar;NewSize:LongInt):LongInt;
  74.          Procedure DrawDragFrame;
  75.          Function GetDragTarget(ptScreen:TPoint;Var target:TRect):TControl;
  76.          Function GetTargetToolbarAlign(TargetForm:TForm; ptScreen:TPoint):TToolbarAlign;
  77.          Procedure FormOnClose(Sender:TObject;Var Action:TCloseAction);
  78.          Procedure FormOnSetupShow(Sender:TObject);
  79.       Protected
  80.          Procedure SetupComponent;Override;
  81.          Procedure RealignControls;Override;
  82.          Procedure MouseDown(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);Override;
  83.          Procedure MouseUp(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);Override;
  84.          Procedure MouseMove(ShiftState:TShiftState;X,Y:LongInt);Override;
  85.          Procedure MouseDblClick(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);Override;
  86.          Procedure ScanEvent(Var KeyCode:TKeyCode;RepeatCount:Byte);Override;
  87.          Procedure Change;Virtual;
  88.          Procedure LoadedFromSCU(SCUParent:TComponent);Override;
  89.          Procedure QueryDockingForm(Var TargetForm:TForm;Var NewAlign:TToolbarAlign);Virtual;
  90.          Property Align;
  91.          Property Alignment;
  92.          Property BevelInner;
  93.          Property BevelOuter;
  94.          Property BevelWidth;
  95.          Property BorderStyle;
  96.          Property BorderWidth;
  97.          Property Bottom;
  98.          Property Caption;
  99.          Property DragCursor;
  100.          Property DragMode;
  101.          Property Font;
  102.          Property Height;
  103.          Property Left;
  104.          Property ParentFont;
  105.          Property ParentPenColor;
  106.          Property PenColor;
  107.          Property Right;
  108.          Property TabOrder;
  109.          Property TabStop;
  110.          Property Top;
  111.          Property Visible;
  112.          Property Width;
  113.          Property ZOrder;
  114.          Property OnFontChange;
  115.       Public
  116.          Destructor Destroy;Override;
  117.          Procedure InsertControl(AChild:TControl);Override;
  118.          Procedure RemoveControl(AChild:TControl);Override;
  119.          Procedure Show;Override;
  120.          Procedure SetWindowPos(NewLeft,NewBottom,NewWidth,NewHeight:LongInt);Override;
  121.          Property DockingForm:TForm Read GetDockingForm Write SetDockingForm;
  122.       Published
  123.          Property AutoWrap:Boolean Read FAutoWrap Write SetAutoWrap;
  124.          Property DockingState:TDockingState Read GetState Write SetState;
  125.          Property EnableDocking:TToolbarAlignments Read FEnableDocking Write FEnableDocking;
  126.          Property Margin:LongInt Read FMargin Write SetMargin;
  127.          Property ToolbarAlign:TToolbarAlign Read FToolAlign Write SetToolAlign;
  128.          Property OnChange:TNotifyEvent Read FOnChange Write FOnChange;
  129.          Property OnDocking:TDockingEvent Read FOnDocking Write FOnDocking;
  130.     End;
  131.  
  132.  
  133. Procedure WriteDockingToolbars;
  134. Procedure ReadDockingToolbars;
  135.  
  136. Const
  137.     UseSCUDockingInformation:Boolean=True;
  138.  
  139.  
  140. Implementation
  141.  
  142. {$IFDEF OS2}
  143. Uses Os2Def,PmWin;
  144. {$ENDIF}
  145.  
  146. {$IFDEF WIN32}
  147. Uses WinDef,WinNT,WinUser;
  148. {$ENDIF}
  149.  
  150. Var
  151.     DockingList:TList;
  152.     OldTitleBarProc:Pointer;
  153.  
  154. {subclassed Window Procedure For Titlebar Of the PanelForms}
  155. {$IFDEF OS2}
  156. Function NewTitleBarProc(Win:HWND;Msg:ULONG;mp1,mp2:MPARAM):mresult;CDECL;
  157. Var  OldProc:Function(Win:HWND;Msg:ULONG;mp1,mp2:MPARAM):mresult;CDECL;
  158.      WinH:HWindow;
  159.      AForm:TForm;
  160.      AToolbar:TDockingToolbar;
  161.      pt:TPoint;
  162. Begin
  163.      Case Msg Of
  164.        WM_BUTTON1DOWN,WM_BUTTON2DOWN,
  165.        WM_BUTTON1DBLCLK,WM_BUTTON2DBLCLK:
  166.        Begin
  167.          WinH := WinQueryWindow(Win,QW_PARENT); {HWindowFrame bestimmen}
  168.          WinH := WinWindowFromID(WinH,FID_CLIENT); {HWindow bestimmen}
  169.          AForm := TForm(HandleToControl(WinH));
  170.          If AForm <> Nil Then
  171.            If AForm.ControlCount = 1 Then
  172.          Begin
  173.            AToolbar := TDockingToolbar(AForm.Controls[0]);
  174.            If AToolbar Is TDockingToolbar Then
  175.              If Not IsControlLocked(AToolbar) Then
  176.              Begin
  177.                pt := Screen.MousePos;
  178.                pt := AToolbar.ScreenToClient(pt);
  179.  
  180.                Case Msg Of
  181.                  WM_BUTTON1DOWN:
  182.                    AToolbar.MouseDown(mbLeft,[],pt.X,pt.Y);
  183.                  WM_BUTTON2DOWN:
  184.                    AToolbar.MouseDown(mbRight,[],pt.X,pt.Y);
  185.                  WM_BUTTON1DBLCLK:
  186.                    AToolbar.MouseDblClick(mbLeft,[],pt.X,pt.Y);
  187.                  WM_BUTTON2DBLCLK:
  188.                    AToolbar.MouseDblClick(mbRight,[],pt.X,pt.Y);
  189.                End;
  190.              End;
  191.          End;
  192.          Result := 0;
  193.        End
  194.        Else
  195.        Begin
  196.          OldProc := OldTitleBarProc;
  197.          Result := OldProc(Win,Msg,mp1,mp2);
  198.        End;
  199.      End;
  200. End;
  201. {$ENDIF}
  202.  
  203. {
  204. ╔═══════════════════════════════════════════════════════════════════════════╗
  205. ║                                                                           ║
  206. ║ Speed-Pascal/2 Version 2.0                                                ║
  207. ║                                                                           ║
  208. ║ Speed-Pascal Component Classes (SPCC)                                     ║
  209. ║                                                                           ║
  210. ║ This section: TDockingFrame Class Implementation                          ║
  211. ║                                                                           ║
  212. ║ (C) 1997 SpeedSoft. All rights reserved. Disclosure probibited !          ║
  213. ║                                                                           ║
  214. ╚═══════════════════════════════════════════════════════════════════════════╝
  215. }
  216.  
  217. Type
  218.     TDockingFrame=Class(TToolbar)
  219.       Private
  220.          FAutoWrap:Boolean;
  221.          FDockOrder:LongInt;
  222.          Procedure SetAutoWrap(Value:Boolean);
  223.       Protected
  224.          Procedure SetupComponent;Override;
  225.       Public
  226.          Property AutoWrap:Boolean Read FAutoWrap Write SetAutoWrap;
  227.          Property DockOrder:LongInt Read FDockOrder Write FDockOrder;
  228.     End;
  229.  
  230.  
  231. Procedure TDockingFrame.SetupComponent;
  232. Begin
  233.      Inherited SetupComponent;
  234.  
  235.      Name := 'DockingFrame';
  236. End;
  237.  
  238.  
  239. Procedure TDockingFrame.SetAutoWrap(Value:Boolean);
  240. Begin
  241.      If Value <> FAutoWrap Then
  242.      Begin
  243.           FAutoWrap := Value;
  244.           Sizeable := Not FAutoWrap;
  245.      End;
  246. End;
  247.  
  248. {
  249. ╔═══════════════════════════════════════════════════════════════════════════╗
  250. ║                                                                           ║
  251. ║ Speed-Pascal/2 Version 2.0                                                ║
  252. ║                                                                           ║
  253. ║ Speed-Pascal Component Classes (SPCC)                                     ║
  254. ║                                                                           ║
  255. ║ This section: TDockingToolbar Class Implementation                        ║
  256. ║                                                                           ║
  257. ║ (C) 1997 SpeedSoft. All rights reserved. Disclosure probibited !          ║
  258. ║                                                                           ║
  259. ╚═══════════════════════════════════════════════════════════════════════════╝
  260. }
  261.  
  262. Const
  263.     TDockingFrameRegistered:Boolean=False;
  264.  
  265.  
  266. Procedure TDockingToolbar.SetupComponent;
  267. Var  sm:TSystemMetrics;
  268. Begin
  269.      Inherited SetupComponent;
  270.  
  271.      Name := 'DockingToolbar';
  272.      Caption := '';
  273.      Align := alClient;
  274.      FAutoAlign := True;
  275.      FAutoWrap := True;
  276.      FToolAlign := tbTop;
  277.      FState := dsHide;
  278.      FEnableDocking := [tbTop,tbBottom,tbLeft,tbRight];
  279.      FMargin := 6;
  280.      FResizing := False;
  281.      FDragging := False;
  282.      UsePanelFormSize := False;
  283.  
  284.      If Owner Is TForm Then
  285.      Begin
  286.           FPanelForm := TForm(Owner);
  287.           FPanelForm.BorderIcons := FPanelForm.BorderIcons -
  288.                                         [biMinimize,biMaximize];
  289.           FPanelForm.Visible := FALSE;
  290.  
  291.           If Not Designed Then
  292.             If Not (csWriting In ComponentState)
  293.             Then FPanelForm.OnClose := FormOnClose;
  294.  
  295.           FPanelForm.OnSetupShow := FormOnSetupShow;
  296.  
  297.           {Size Of the framecontrol Items}
  298.           Case FPanelForm.BorderStyle Of
  299.             bsSingle:   sm := smCxBorder;
  300.             bsSizeable: sm := smCxSizeBorder;
  301.             bsDialog:   sm := smCxDlgBorder;
  302.           End;
  303.           PanelBorderSizeX := Screen.SystemMetrics(sm);
  304.           Case FPanelForm.BorderStyle Of
  305.             bsSingle:   sm := smCyBorder;
  306.             bsSizeable: sm := smCySizeBorder;
  307.             bsDialog:   sm := smCyDlgBorder;
  308.           End;
  309.           PanelBorderSizeY := Screen.SystemMetrics(sm);
  310.           PanelTitleHeight := Screen.SystemMetrics(smCyTitlebar);
  311.      End;
  312.      Include(ComponentState, csAcceptsControls);
  313.  
  314.      If Not (csWriting In ComponentState) Then
  315.        If Not Designed Then DockingList.Add(Self);
  316.  
  317.  
  318.      If Not TDockingFrameRegistered Then
  319.      Begin
  320.           RegisterClasses([TDockingFrame]); {RuntimeSCU}
  321.           TDockingFrameRegistered := True;
  322.      End;
  323. End;
  324.  
  325.  
  326. Procedure TDockingToolbar.LoadedFromSCU(SCUParent:TComponent);
  327. Begin
  328.      Inherited LoadedFromSCU(SCUParent);
  329.  
  330.      SetState(FState);
  331. End;
  332.  
  333.  
  334. Procedure TDockingToolbar.Show;
  335. Begin
  336.      Inherited Show;
  337.  
  338.      RealignControls;
  339. End;
  340.  
  341.  
  342. Destructor TDockingToolbar.Destroy;
  343. Begin
  344.      If Not (csWriting In ComponentState) Then DockingList.Remove(Self);
  345.  
  346.      FAutoAlign := False;   {avoid RealignControls}
  347.  
  348.      Inherited Destroy;
  349. End;
  350.  
  351.  
  352. Procedure TDockingToolbar.InsertControl(AChild:TControl);
  353. Begin
  354.      Inherited InsertControl(AChild);
  355.  
  356.      RealignControls;
  357. End;
  358.  
  359.  
  360. Procedure TDockingToolbar.RemoveControl(AChild:TControl);
  361. Begin
  362.      Inherited RemoveControl(AChild);
  363.  
  364.      RealignControls;
  365. End;
  366.  
  367.  
  368. Function TDockingToolbar.GetWrappedSize(Docked:Boolean;HorizToolbar:Boolean;
  369.                                    Var WrapWidth,WrapHeight:LongInt):Boolean;
  370. Var  I,X,Y:LongInt;
  371.      Control:TControl;
  372.      ASize:LongInt;
  373.      MaxHeight:LongInt;
  374.      MaxWrapWidth:LongInt;
  375. Begin
  376.      Result := False;
  377.      If ControlCount = 0 Then Exit;
  378.  
  379.      If Not FAutoWrap Then
  380.      Begin
  381.           Result := True;
  382.           Exit;
  383.      End;
  384.  
  385.      If Docked Then
  386.      Begin
  387.           WrapWidth := 0;
  388.           WrapHeight := 0;
  389.  
  390.           {Search largest Control To determine wrapping Size}
  391.           For I := 0 To ControlCount-1 Do
  392.           Begin
  393.                Control := Controls[I];
  394.                If HorizToolbar Then
  395.                Begin
  396.                     ASize := Control.Height;
  397.                     If ASize > WrapHeight Then WrapHeight := ASize;
  398.                     Inc(WrapWidth, Control.Width);
  399.                End
  400.                Else
  401.                Begin
  402.                     ASize := Control.Width;
  403.                     If ASize > WrapWidth Then WrapWidth := ASize;
  404.                     Inc(WrapHeight, Control.Height);
  405.                End;
  406.           End;
  407.      End;
  408.  
  409.  
  410.      {determine the highest Control}
  411.      MaxHeight := 0;
  412.      For I := 0 To ControlCount-1 Do
  413.      Begin
  414.           Control := Controls[I];
  415.           ASize := Control.Height;
  416.           If ASize > MaxHeight Then MaxHeight := ASize;
  417.      End;
  418.  
  419.  
  420.      {determine final Size}
  421.      MaxWrapWidth := 0;
  422.      WrapHeight := 0;
  423.      X := 0;
  424.      Y := 0;
  425.      For I := 0 To ControlCount-1 Do
  426.      Begin
  427.           Control := Controls[I];
  428.  
  429.           If X + Control.Width > WrapWidth Then
  430.           Begin
  431.                X := 0;
  432.                Y := Y + MaxHeight;
  433.           End;
  434.  
  435.           If X + Control.Width > MaxWrapWidth Then
  436.           Begin
  437.                MaxWrapWidth := X + Control.Width;
  438.           End;
  439.  
  440.           If Y + Control.Height > WrapHeight Then
  441.           Begin
  442.                WrapHeight := Y + Control.Height;
  443.           End;
  444.           Inc(X,Control.Width);
  445.      End;
  446.  
  447.      WrapWidth := MaxWrapWidth;
  448.  
  449.      Inc(WrapWidth, 2*FMargin);
  450.      Inc(WrapHeight, 2*FMargin);
  451.  
  452.      Result := True;
  453. End;
  454.  
  455.  
  456. Procedure TDockingToolbar.RealignControls;
  457. Var  I,X,Y:LongInt;
  458.      xadd,yadd:LongInt;
  459.      xmax,ymax:LongInt;
  460.      Control:TControl;
  461. Begin
  462.      If Not FAutoAlign Then Exit;
  463.  
  464.      If FResizing Then Exit;
  465.      If Handle = 0 Then Exit;
  466.  
  467.      If DockingState = dsFloat Then
  468.        If Form.WindowState = wsMinimized Then Exit;
  469.  
  470.  
  471.      If Not FAutoWrap Then // centre the Control
  472.      Begin
  473.           For I := 0 To ControlCount-1 Do
  474.           Begin
  475.                Control := Controls[I];
  476.                Control.SetWindowPos(FMargin, FMargin,
  477.                                     Width-2*FMargin, Height-2*FMargin);
  478.           End;
  479.           Exit;
  480.      End;
  481.  
  482.      X := FMargin; {from Left}
  483.      Y := FMargin; {from Top}
  484.      xmax := 0;
  485.      ymax := 0;
  486.      For I := 0 To ControlCount-1 Do
  487.      Begin
  488.           Control := Controls[I];
  489.           If Control.Handle <> 0 Then Control.Hide;
  490.  
  491.           If X + Control.Width > Width - FMargin Then
  492.           Begin
  493.                X := FMargin;
  494.                Y := Y + ymax;
  495.                ymax := 0;
  496.           End;
  497.           {Control.SetBounds(X,Y,Control.Width,Control.Height);}
  498.           Inc(X,Control.Width);
  499.           If xmax < X Then xmax := X;
  500.           If ymax < Control.Height Then ymax := Control.Height;
  501.      End;
  502.  
  503.      FResizing := True;
  504.      If parent Is TForm Then
  505.        If parent.ControlCount = 1 Then
  506.          If Form <> Nil Then
  507.            If Align = alClient Then
  508.              If ControlCount > 0 Then
  509.      Begin
  510.           xadd := Form.Width - Form.ClientWidth;
  511.           yadd := Form.Height - Form.ClientHeight;
  512.  
  513.           Form.SetBounds(Form.Left,Form.Top,
  514.                          xmax + FMargin + xadd,
  515.                          Y + ymax + FMargin + yadd);
  516.      End;
  517.      FResizing := False;
  518.  
  519.      X := FMargin; {from Left}
  520.      Y := FMargin; {from Top}
  521.      xmax := 0;
  522.      ymax := 0;
  523.      For I := 0 To ControlCount-1 Do
  524.      Begin
  525.           Control := Controls[I];
  526.           {If Control.Handle <> 0 Then Control.Hide;}
  527.  
  528.           If X + Control.Width > Width - FMargin Then
  529.           Begin
  530.                X := FMargin;
  531.                Y := Y + ymax;
  532.                ymax := 0;
  533.           End;
  534.           Control.SetBounds(X,Y,Control.Width,Control.Height);
  535.           Inc(X,Control.Width);
  536.           If xmax < X Then xmax := X;
  537.           If ymax < Control.Height Then ymax := Control.Height;
  538.      End;
  539.  
  540.      If Handle <> 0 Then
  541.        For I := 0 To ControlCount-1 Do
  542.        Begin
  543.             Control := Controls[I];
  544.             If Control.Handle <> 0 Then Control.Show;
  545.        End;
  546.  
  547.      UpdateTrackSize;
  548. End;
  549.  
  550.  
  551. Procedure TDockingToolbar.UpdateTrackSize;
  552. Var  I,xadd,yadd:LongInt;
  553.      wmin,wmax,hmin,hmax:LongInt;
  554.      Control:TControl;
  555. Begin
  556.      If Designed Then Exit;
  557.      If IsDocked Then Exit; {nicht im Docked Modus}
  558.      If Form = Nil Then Exit; {noch nicht eingefügt}
  559.      If FPanelForm = Nil Then Exit; {PanelForm zerstört}
  560.  
  561.      {Panel Modus}
  562.      If FPanelForm.ControlCount = 1 Then
  563.        If ControlCount > 0 Then
  564.      Begin
  565.           xadd := Form.Width - FPanelForm.ClientWidth + 2*FMargin;
  566.           yadd := Form.Height - FPanelForm.ClientHeight + 2*FMargin;
  567.           wmin := 0;
  568.           wmax := 0;
  569.           hmin := 0;
  570.           hmax := 0;
  571.           For I := 0 To ControlCount-1 Do
  572.           Begin
  573.                Control := Controls[I];
  574.                If Control.Width > wmin Then wmin := Control.Width;
  575.                Inc(wmax,Control.Width);
  576.                If Control.Height > hmin Then hmin := Control.Height;
  577.                Inc(hmax,Control.Height);  {?}
  578.           End;
  579.           FPanelForm.MinTrackWidth := wmin + xadd;
  580.           FPanelForm.MaxTrackWidth := wmax + xadd;
  581.           FPanelForm.MinTrackHeight := hmin + yadd;
  582.           FPanelForm.MaxTrackHeight := hmax + yadd;
  583.      End;
  584. End;
  585.  
  586.  
  587. Procedure TDockingToolbar.SetAutoWrap(Value:Boolean);
  588. Begin
  589.      If Value <> FAutoWrap Then
  590.      Begin
  591.           FAutoWrap := Value;
  592.           RealignControls;
  593.  
  594.           If parent Is TDockingFrame
  595.           Then TDockingFrame(parent).AutoWrap := FAutoWrap;
  596.      End;
  597. End;
  598.  
  599.  
  600. Procedure TDockingToolbar.SetMargin(Value:LongInt);
  601. Begin
  602.      If Value <> FMargin Then
  603.        If Value >= 0 Then
  604.      Begin
  605.           FMargin := Value;
  606.           RealignControls;
  607.      End;
  608. End;
  609.  
  610.  
  611. Procedure TDockingToolbar.SetToolAlign(Value:TToolbarAlign);
  612. Begin
  613.      If Value <> FToolAlign Then
  614.      Begin
  615.           FToolAlign := Value;
  616.           LastDockLeft := 0;
  617.           LastDockBottom := 0;
  618.  
  619.           If IsDocked Then
  620.           Begin
  621.                UndockPanel;
  622.                DockPanel(Nil);
  623.           End;
  624.      End;
  625. End;
  626.  
  627.  
  628. Procedure TDockingToolbar.SetDockingForm(AForm:TForm);
  629. Begin
  630.      If AForm <> FDockingForm Then
  631.      Begin
  632.           If AForm = Nil Then Exit;
  633.  
  634.           If IsDocked Then
  635.           Begin
  636.                LastDockLeft := 0;
  637.                LastDockBottom := 0;
  638.  
  639.                UndockPanel;
  640.                FDockingForm := AForm;
  641.                DockPanel(Nil);
  642.           End
  643.           Else FDockingForm := AForm;
  644.      End;
  645. End;
  646.  
  647.  
  648. Function TDockingToolbar.IsDocked:Boolean;
  649. Begin
  650.      Result := parent Is TDockingFrame;
  651. End;
  652.  
  653.  
  654.  
  655. Function TDockingToolbar.GetState:TDockingState;
  656. Begin
  657.      If Designed Then
  658.      Begin
  659.           Result := FState;
  660.           Exit;
  661.      End;
  662.  
  663.      If IsDocked Then Result := dsDock
  664.      Else If Showing Then Result := dsFloat
  665.           Else Result := dsHide;
  666. End;
  667.  
  668.  
  669. Procedure TDockingToolbar.SetState(Value:TDockingState);
  670. Begin
  671.      If (Designed) Or (csReading In ComponentState) Then
  672.      Begin
  673.           If Designed Or UseSCUDockingInformation Then FState := Value;
  674.           Exit;
  675.      End;
  676.  
  677.      If Value = GetState Then Exit;
  678.  
  679.      FState := Value;
  680.  
  681.      Case FState Of
  682.        dsDock:  DockLastPanel;
  683.        dsFloat: FloatPanel;
  684.        dsHide:  HidePanel;
  685.      End;
  686. End;
  687.  
  688.  
  689. Function TDockingToolbar.GetDockingForm:TForm;
  690. Begin
  691.      If FDockingForm = Nil Then FDockingForm := Application.MainForm;
  692.      Result := FDockingForm;
  693. End;
  694.  
  695.  
  696. Procedure TDockingToolbar.UndockPanel;
  697. Var  ParentToolbar:TDockingFrame;
  698.      NewSize:LongInt;
  699. Begin
  700.      Align := alNone;
  701.  
  702.      ParentToolbar := TDockingFrame(parent);
  703.  
  704.      If Owner <> Nil Then Owner.RemoveComponent(Self);
  705.      parent := Nil;
  706.  
  707.      If ParentToolbar Is TDockingFrame Then
  708.      Begin
  709.           LastDockToolbar := Nil;
  710.  
  711.           If ParentToolbar.ControlCount > 0 Then
  712.           Begin
  713.                If (ParentToolbar.ControlCount = 1) And
  714.                   (ParentToolbar.Sizeable) Then ParentToolbar.Destroy
  715.                Else
  716.                Begin {Wrap it}
  717.                     NewSize := GetToolbarMaxSize(ParentToolbar,0);
  718.                     ParentToolbar.Size := NewSize;
  719.                     LastDockToolbar := ParentToolbar;
  720.                End;
  721.           End
  722.           Else ParentToolbar.Destroy;
  723.      End;
  724.  
  725.  
  726.      If FPanelForm <> Nil Then
  727.      Begin
  728.           FPanelForm.Close; {no Destroy}
  729.           FPanelForm.Visible := FALSE;
  730.      End;
  731. End;
  732.  
  733.  
  734. Procedure TDockingToolbar.HidePanel;
  735. Begin
  736.      If FPanelForm <> Nil Then
  737.      Begin
  738.           UndockPanel;
  739.  
  740.           Align := alClient;
  741.  
  742.           FPanelForm.Hide;
  743.           FPanelForm.InsertComponent(Self);
  744.           parent := FPanelForm;
  745.      End;
  746. End;
  747.  
  748.  
  749. Procedure TDockingToolbar.FloatPanel;
  750. Begin
  751.      If GetState = dsFloat Then Exit;
  752.  
  753.      If FPanelForm <> Nil Then
  754.      Begin
  755.           UndockPanel;
  756.  
  757.           Align := alClient;
  758.  
  759.           FPanelForm.InsertComponent(Self);
  760.           parent := FPanelForm;
  761.           FPanelForm.Show;
  762.      End;
  763. End;
  764.  
  765.  
  766. Procedure TDockingToolbar.DockPanel(ParentToolbar:TToolbar);
  767. Var  HorizToolbar:Boolean;
  768.      ToolWidth,ToolHeight:LongInt;
  769.      NewSize:LongInt;
  770. Begin
  771.      FDockingForm := GetDockingForm;
  772.  
  773.      UndockPanel;
  774.  
  775.      If ParentToolbar <> Nil Then
  776.        If Not (ParentToolbar Is TDockingFrame) Then ParentToolbar := Nil;
  777.  
  778.      If ParentToolbar = Nil Then
  779.      Begin
  780.           ParentToolbar := TDockingFrame.Create(FDockingForm);
  781.           ParentToolbar.Alignment := FToolAlign;
  782.           ParentToolbar.BevelStyle := tbNone;
  783.           TDockingFrame(ParentToolbar).AutoWrap := FAutoWrap;
  784.      End;
  785.  
  786.      HorizToolbar := ParentToolbar.Alignment In [tbTop,tbBottom];
  787.      If FAutoWrap Then
  788.      Begin
  789.           ToolWidth := ParentToolbar.Width;
  790.           ToolHeight := ParentToolbar.Height;
  791.      End
  792.      Else
  793.      Begin
  794.           If (FPanelForm <> Nil) And UsePanelFormSize Then
  795.           Begin // take the Size Of the Panel Form
  796.                ToolWidth := FPanelForm.ClientWidth;
  797.                ToolHeight := FPanelForm.ClientHeight;
  798.           End
  799.           Else
  800.           Begin
  801.                ToolWidth := Width;
  802.                ToolHeight := Height;
  803.           End;
  804.           Align := alClient;
  805.      End;
  806.      ParentToolbar.Sizeable := Not FAutoWrap;
  807.  
  808.      If GetWrappedSize(True,HorizToolbar,ToolWidth,ToolHeight) Then
  809.      Begin
  810.           If HorizToolbar Then NewSize := ToolHeight
  811.           Else NewSize := ToolWidth;
  812.  
  813.           {Test ob Toolbar, größer sein muß als NewSize}
  814.           NewSize := GetToolbarMaxSize(ParentToolbar,NewSize);
  815.  
  816.           ParentToolbar.Size := NewSize;
  817.      End;
  818.  
  819.      SetWindowPos(LastDockLeft,LastDockBottom,ToolWidth,ToolHeight);
  820.  
  821.      parent := ParentToolbar;
  822.      LastDockToolbar := ParentToolbar;
  823.  
  824.      ParentToolbar.parent := FDockingForm;
  825.  
  826.      FDockingForm.InsertComponent(Self);
  827.  
  828.      Change;
  829. End;
  830.  
  831.  
  832. Procedure TDockingToolbar.DockLastPanel;
  833. Var  AToolbar:TDockingFrame;
  834.      I:LongInt;
  835. Begin
  836.      AToolbar := Nil;
  837.      {Search the Last Toolbar}
  838.      If FAutoWrap Then
  839.        If FDockingForm <> Nil Then
  840.        Begin
  841.             For I := 0 To FDockingForm.ControlCount-1 Do
  842.             Begin
  843.                  If FDockingForm.Controls[I] = LastDockToolbar Then
  844.                    If LastDockToolbar Is TDockingFrame Then
  845.                      If LastDockToolbar.Alignment = FToolAlign Then
  846.                      Begin
  847.                           AToolbar := TDockingFrame(LastDockToolbar);
  848.                           break;
  849.                      End;
  850.             End;
  851.        End;
  852.  
  853.      DockPanel(AToolbar);
  854. End;
  855.  
  856.  
  857. Function TDockingToolbar.GetToolbarMaxSize(ParentToolbar:TToolbar;NewSize:LongInt):LongInt;
  858. Var  I:LongInt;
  859.      AControl:TControl;
  860.      horz:Boolean;
  861. Begin
  862.      If ParentToolbar <> Nil Then
  863.      Begin
  864.           horz := ParentToolbar.Alignment In [tbTop,tbBottom];
  865.           For I := 0 To ParentToolbar.ControlCount-1 Do
  866.           Begin
  867.                AControl := ParentToolbar.Controls[I];
  868.                If csDetail In AControl.ComponentState Then continue;
  869.  
  870.                If horz Then
  871.                Begin
  872.                     If AControl.Height > NewSize
  873.                     Then NewSize := AControl.Height;
  874.                End
  875.                Else
  876.                Begin
  877.                     If AControl.Width > NewSize
  878.                     Then NewSize := AControl.Width;
  879.                End;
  880.           End;
  881.      End;
  882.      Result := NewSize;
  883. End;
  884.  
  885.  
  886. Procedure TDockingToolbar.Change;
  887. Begin
  888.      If FOnChange <> Nil Then FOnChange(Self);
  889. End;
  890.  
  891.  
  892. {$HINTS OFF}
  893. Procedure TDockingToolbar.FormOnClose(Sender:TObject;Var Action:TCloseAction);
  894. Begin
  895.      Action := caFreeHandle;
  896. End;
  897.  
  898.  
  899. Procedure TDockingToolbar.FormOnSetupShow(Sender:TObject);
  900. Var  TitlebarWin:HWindow;
  901.      ret:Pointer;
  902. Begin
  903.      If Designed Then Exit;
  904.  
  905.      {$IFDEF OS2}
  906.      TitlebarWin := WinWindowFromID(FPanelForm.Frame.Handle,FID_TITLEBAR);
  907.      ret := WinSubClassWindow(TitlebarWin, @NewTitleBarProc);
  908.      If ret <> Nil Then OldTitleBarProc := ret;
  909.      {$ENDIF}
  910. End;
  911. {$HINTS ON}
  912.  
  913.  
  914. Procedure TDockingToolbar.MouseDown(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);
  915. Begin
  916.      Inherited MouseDown(Button,ShiftState,X,Y);
  917.  
  918.      If FEnableDocking = [] Then Exit;
  919.  
  920.      FDragging := True;
  921.      MouseCapture := True;
  922.      DraggingAborted := False;
  923.      LastActiveControl := Screen.ActiveControl;
  924.      Focus;
  925.  
  926.      OldFgMode := Screen.Canvas.Pen.Mode;
  927.      OldLineWidth := Screen.Canvas.Pen.Width;
  928.      OldLineType := Screen.Canvas.Pen.Style;
  929.  
  930.      Screen.Canvas.Pen.Mode := pmNot;
  931.      Screen.Canvas.Pen.Width := 1;
  932.      Screen.Canvas.Pen.Style := psSolid;
  933.  
  934.      InitDrag := Forms.Point(X,Y);
  935.      CurDrag := InitDrag;
  936.  
  937.      DrawDragFrame;
  938. End;
  939.  
  940.  
  941. Procedure TDockingToolbar.MouseUp(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);
  942. Var  pt:TPoint;
  943.      AControl:TControl;
  944.      TargetForm:TForm;
  945.      NewLeft:LongInt;
  946.      NewBottom:LongInt;
  947.      NewToolAlign:TToolbarAlign;
  948.      rec:TRect;
  949.      TargetToolbar:TToolbar;
  950.  
  951.   Procedure MovePanelForm(rec:TRect);
  952.   Begin
  953.        If FPanelForm = Nil Then Exit;
  954.  
  955.        FPanelForm.SetWindowPos(rec.Left, rec.Bottom,
  956.                                FPanelForm.Width, FPanelForm.Height);
  957.   End;
  958.  
  959. Begin
  960.      Inherited MouseUp(Button,ShiftState,X,Y);
  961.  
  962.      If FDragging Then
  963.      Begin
  964.           DrawDragFrame;
  965.  
  966.           FDragging := False;
  967.           MouseCapture := False;
  968.  
  969.           Screen.Canvas.Pen.Mode := OldFgMode;
  970.           Screen.Canvas.Pen.Width := OldLineWidth;
  971.           Screen.Canvas.Pen.Style := OldLineType;
  972.  
  973.           Try
  974.              If LastActiveControl <> Nil Then LastActiveControl.Focus;
  975.           Except
  976.           End;
  977.  
  978.           {ignore For DblClick}
  979.           If (Abs(InitDrag.X - CurDrag.X) < 5) And
  980.              (Abs(InitDrag.Y - CurDrag.Y) < 5) Then Exit;
  981.  
  982.           If DraggingAborted Then Exit;
  983.  
  984.           {Change Docking State}
  985.           pt := Forms.Point(X,Y);
  986.           pt := ClientToScreen(pt);
  987.  
  988.           AControl := GetDragTarget(pt,rec);
  989.  
  990.           If AControl = Nil Then
  991.           Begin // target Is the DeskTop
  992.                MovePanelForm(rec);
  993.                FloatPanel;     {undock -> Align -> DeskTop}
  994.  
  995.                Change;
  996.                Exit;
  997.           End;
  998.  
  999.           {A drag target Is specified}
  1000.           TargetForm := AControl.Form;
  1001.           If TargetForm = Nil Then Exit; {?}
  1002.  
  1003.           If TargetForm = FPanelForm Then
  1004.           Begin // only the DeskTop Panel was moved
  1005.                MovePanelForm(rec);
  1006.  
  1007.                Change;
  1008.                Exit;
  1009.           End;
  1010.  
  1011.           {Set New Docking State Or Position}
  1012.           NewToolAlign := GetTargetToolbarAlign(TargetForm,pt);
  1013.  
  1014.           {check If we can dock At This Alignment}
  1015.           QueryDockingForm(TargetForm, NewToolAlign);
  1016.  
  1017.           If TargetForm = Nil Then
  1018.           Begin // target Is the DeskTop
  1019.                MovePanelForm(rec);
  1020.                FloatPanel;     {undock -> Align -> DeskTop}
  1021.  
  1022.                Change;
  1023.                Exit;
  1024.           End;
  1025.  
  1026.  
  1027.           {target redirected -> ignore Control To Insert}
  1028.           If AControl <> Nil Then
  1029.             If AControl.Form <> TargetForm Then AControl := Nil;
  1030.  
  1031.  
  1032.           If IsDocked Then                    {Docked}
  1033.             If TargetForm = Form Then         {In the same Form}
  1034.               If AControl = parent Then       {In the same Toolbar}
  1035.           Begin // only Position changes
  1036.                {determine the New Offset within the Toolbar}
  1037.                If FToolAlign In [tbTop,tbBottom] Then
  1038.                Begin
  1039.                     NewLeft := Left + X - InitDrag.X;
  1040.                     {clip Right}
  1041.                     If NewLeft + Width > parent.Width
  1042.                     Then NewLeft := parent.Width - Width;
  1043.                     {clip Left}
  1044.                     If NewLeft < 0 Then NewLeft := 0;
  1045.                     LastDockLeft := NewLeft;
  1046.                     LastDockBottom := 0;
  1047.                End
  1048.                Else
  1049.                Begin
  1050.                     NewBottom := Bottom + Y - InitDrag.Y;
  1051.                     {clip Top}
  1052.                     If NewBottom + Height > parent.Height
  1053.                     Then NewBottom := parent.Height - Height;
  1054.                     {clip Left}
  1055.                     If NewBottom < 0 Then NewBottom := 0;
  1056.                     LastDockLeft := 0;
  1057.                     LastDockBottom := NewBottom;
  1058.                End;
  1059.  
  1060.                SetWindowPos(LastDockLeft,LastDockBottom,Width,Height);
  1061.  
  1062.                Change;
  1063.                Exit;
  1064.           End;
  1065.  
  1066.           {Change the Docking Form, Toolbar And dock}
  1067.           While AControl <> Nil Do
  1068.           Begin
  1069.                If AControl Is TDockingFrame Then break
  1070.                Else AControl := AControl.parent;
  1071.           End;
  1072.  
  1073.           {für neworder merken}
  1074.           TargetToolbar := TToolbar(AControl);
  1075.  
  1076.           {prevent Docking A non-wrapped In another Panel}
  1077.           If Not FAutoWrap Then AControl := Nil;
  1078.  
  1079.           {prevent Docking A wrapped In A non-wrapped Panel}
  1080.           If FAutoWrap Then
  1081.             If AControl Is TDockingFrame Then // check the Toolbar
  1082.               If Not TDockingFrame(AControl).AutoWrap Then AControl := Nil;
  1083.  
  1084.  
  1085.           UsePanelFormSize := True; {For Docking non-wrapped Panels}
  1086.  
  1087.           UndockPanel;
  1088.  
  1089.           LastDockLeft := 0;
  1090.           LastDockBottom := 0;
  1091.           FToolAlign := NewToolAlign;
  1092.           FDockingForm := TargetForm;
  1093.           FToolAlign := NewToolAlign;
  1094.  
  1095.           DockPanel(TDockingFrame(AControl));
  1096.  
  1097.           {neue order}
  1098.           If TargetToolbar <> Nil Then
  1099.             If TargetToolbar <> parent
  1100.             Then TDockingFrame(parent).order := TargetToolbar.order;
  1101.  
  1102.           UsePanelFormSize := False; {For Docking non-wrapped Panels}
  1103.      End;
  1104. End;
  1105.  
  1106.  
  1107. Procedure TDockingToolbar.MouseMove(ShiftState:TShiftState;X,Y:LongInt);
  1108. Begin
  1109.      Inherited MouseMove(ShiftState,X,Y);
  1110.  
  1111.      If FDragging Then
  1112.      Begin
  1113.           DrawDragFrame;
  1114.           CurDrag := Forms.Point(X,Y);
  1115.           TryDocking := Not (ssCtrl In ShiftState);
  1116.           DrawDragFrame;
  1117.      End;
  1118. End;
  1119.  
  1120.  
  1121. Procedure TDockingToolbar.MouseDblClick(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);
  1122. Begin
  1123.      Inherited MouseDblClick(Button,ShiftState,X,Y);
  1124.  
  1125.      If FEnableDocking = [] Then Exit;
  1126.  
  1127.      If Button = mbLeft Then
  1128.      Begin
  1129.           If Not IsDocked Then
  1130.           Begin
  1131.                {check If FDockingForm In able To dock}
  1132.                If FDockingForm <> Nil Then
  1133.                  If FDockingForm.EnableDocking * [FToolAlign] <> []
  1134.                  Then DockLastPanel;
  1135.           End
  1136.           Else FloatPanel;
  1137.      End;
  1138. End;
  1139.  
  1140.  
  1141. Procedure TDockingToolbar.ScanEvent(Var KeyCode:TKeyCode;RepeatCount:Byte);
  1142. Begin
  1143.      Inherited ScanEvent(KeyCode,RepeatCount);
  1144.  
  1145.      If FDragging Then
  1146.      Begin
  1147.        Case KeyCode Of
  1148.          kbEsc:
  1149.          Begin
  1150.               DraggingAborted := True;
  1151.               MouseUp(mbLeft,[],CurDrag.X,CurDrag.Y);
  1152.          End;
  1153.          kbCtrl:
  1154.          Begin
  1155.               MouseMove([ssCtrl],CurDrag.X,CurDrag.Y);
  1156.          End;
  1157.        End;
  1158.      End;
  1159. End;
  1160.  
  1161.  
  1162. Procedure TDockingToolbar.DrawDragFrame;
  1163. Var  rec:TRect;
  1164.      pt:TPoint;
  1165.      target:TControl;
  1166. {$IFDEF WIN32}
  1167. Procedure ScreenRect(Const rc:TRect);
  1168. Begin
  1169.      Screen.Canvas.Line(rc.Left,rc.Bottom,rc.Right,rc.Bottom);
  1170.      Screen.Canvas.Line(rc.Right,rc.Bottom,rc.Right,rc.Top);
  1171.      Screen.Canvas.Line(rc.Right,rc.Top,rc.Left,rc.Top);
  1172.      Screen.Canvas.Line(rc.Left,rc.Top,rc.Left,rc.Bottom);
  1173. End;
  1174. {$ENDIF}
  1175. Begin
  1176.      pt := CurDrag;
  1177.      pt := ClientToScreen(pt);
  1178.  
  1179.      target := GetDragTarget(pt, rec);
  1180.  
  1181.      {$IFDEF OS2}
  1182.      Screen.Canvas.Rectangle(rec);
  1183.      If target = Nil Then
  1184.      Begin
  1185.           Forms.InflateRect(rec,-1,-1);
  1186.           Screen.Canvas.Rectangle(rec);
  1187.           Forms.InflateRect(rec,-1,-1);
  1188.           Screen.Canvas.Rectangle(rec);
  1189.      End;
  1190.      {$ENDIF}
  1191.      {$IFDEF WIN32}
  1192.      ScreenRect(rec);
  1193.      If target = Nil Then
  1194.      Begin
  1195.           Forms.InflateRect(rec,-1,-1);
  1196.           ScreenRect(rec);
  1197.           Forms.InflateRect(rec,-1,-1);
  1198.           ScreenRect(rec);
  1199.      End;
  1200.      {$ENDIF}
  1201. End;
  1202.  
  1203.  
  1204. Procedure TDockingToolbar.QueryDockingForm(Var TargetForm:TForm;Var NewAlign:TToolbarAlign);
  1205. Begin
  1206.      If TargetForm = Nil Then Exit;
  1207.  
  1208.      {dont drop In another Palette}
  1209.      If TargetForm.ControlCount = 1 Then
  1210.        If TargetForm.Controls[0] Is TDockingToolbar Then
  1211.        Begin
  1212.             TargetForm := Nil;
  1213.             Exit;
  1214.        End;
  1215.  
  1216.      If TargetForm.Designed Then
  1217.      Begin
  1218.           TargetForm := Nil;
  1219.           Exit;
  1220.      End;
  1221.  
  1222.      If Not (NewAlign In EnableDocking) Then
  1223.      Begin
  1224.           TargetForm := Nil;
  1225.           Exit;
  1226.      End;
  1227.  
  1228.      If Not (NewAlign In TargetForm.EnableDocking) Then
  1229.      Begin
  1230.           TargetForm := Nil;
  1231.           Exit;
  1232.      End;
  1233.  
  1234.      If FOnDocking <> Nil Then FOnDocking(Self,TargetForm,NewAlign);
  1235. End;
  1236.  
  1237.  
  1238. Function TDockingToolbar.GetDragTarget(ptScreen:TPoint;Var target:TRect):TControl;
  1239. Var  AControl:TControl;
  1240.      TargetForm:TForm;
  1241.      TargetToolbar:TDockingFrame;
  1242.      WrapWidth,WrapHeight:LongInt;
  1243.      FinalWrapHeight:LongInt;
  1244.      NewToolAlign:TToolbarAlign;
  1245.      dock:Boolean;
  1246.      horz:Boolean;
  1247. Begin
  1248.      Result := Nil;
  1249.      TargetForm := Nil;
  1250.      TargetToolbar := Nil;
  1251.      AControl := Screen.GetControlFromPoint(ptScreen);
  1252.      If AControl <> Nil Then TargetForm := AControl.Form;
  1253.  
  1254.      If Not TryDocking Then
  1255.      Begin
  1256.           TargetForm := Nil;
  1257.           AControl := Nil;
  1258.      End;
  1259.  
  1260.      If TargetForm <> Nil Then
  1261.      Begin // ignore framecontrol
  1262.           If TargetForm.Frame = AControl Then TargetForm := Nil;
  1263.  
  1264.           While AControl <> Nil Do
  1265.           Begin
  1266.                If AControl Is TDockingFrame Then
  1267.                Begin
  1268.                     TargetToolbar := TDockingFrame(AControl);
  1269.                     If TargetToolbar Is TDockingFrame
  1270.                     Then Result := AControl;
  1271.                     break;
  1272.                End
  1273.                Else AControl := AControl.parent;
  1274.           End;
  1275.  
  1276.           If AControl = Nil Then Result := TargetForm;
  1277.      End;
  1278.  
  1279.      If FPanelForm <> Nil Then
  1280.      Begin
  1281.           WrapWidth := FPanelForm.ClientWidth;
  1282.           WrapHeight := FPanelForm.ClientHeight;
  1283.      End;
  1284.  
  1285.      dock := (TargetForm <> FPanelForm) And (TargetForm <> Nil);
  1286.  
  1287.      NewToolAlign := FToolAlign;
  1288.  
  1289.      If dock Then // determine where To dock
  1290.      Begin
  1291.           If TargetToolbar <> Nil Then NewToolAlign := TargetToolbar.Alignment
  1292.           Else NewToolAlign := GetTargetToolbarAlign(TargetForm,ptScreen);
  1293.      End;
  1294.  
  1295.      {check If we can dock At This Alignment}
  1296.      QueryDockingForm(TargetForm, NewToolAlign);
  1297.  
  1298.  
  1299.      {target redirected -> ignore Control To Insert}
  1300.      If AControl <> Nil Then
  1301.        If AControl.Form <> TargetForm Then AControl := Nil;
  1302.  
  1303.      {no final target}
  1304.      If TargetForm = Nil Then Result := Nil;
  1305.  
  1306.      {Test again}
  1307.      dock := (TargetForm <> FPanelForm) And (TargetForm <> Nil);
  1308.  
  1309.      horz := NewToolAlign In [tbTop,tbBottom];
  1310.  
  1311.      // determine the New Size Of the Panel
  1312.      GetWrappedSize(dock, horz, WrapWidth, WrapHeight);
  1313.  
  1314.      // Add Titlebar Size
  1315.      FinalWrapHeight := WrapHeight;
  1316.      If Not dock Then Inc(FinalWrapHeight, PanelTitleHeight);
  1317.  
  1318.      If (IsDocked And (NewToolAlign <> FToolAlign)) Or
  1319.         (IsDocked <> dock) Or
  1320.         (InitDrag.X > WrapWidth) Or
  1321.         (InitDrag.Y > FinalWrapHeight) Then
  1322.      Begin {re-centre the dragframe}
  1323.           ptScreen.X := ptScreen.X - (WrapWidth Div 2) + InitDrag.X;
  1324.           ptScreen.Y := ptScreen.Y - (WrapHeight Div 2) + InitDrag.Y;
  1325.      End;
  1326.  
  1327.      {dragframe}
  1328.      target := Forms.Rect(ptScreen.X, ptScreen.Y,
  1329.                           ptScreen.X + WrapWidth, ptScreen.Y + WrapHeight);
  1330.  
  1331.      Forms.OffsetRect(target, -InitDrag.X, -InitDrag.Y);
  1332.  
  1333.      If Not dock Then // Add Form Frame sizes
  1334.      Begin
  1335.           Dec(target.Left, PanelBorderSizeX);
  1336.           Inc(target.Right, PanelBorderSizeX);
  1337.           Dec(target.Bottom, PanelBorderSizeY);
  1338.           Inc(target.Top, PanelBorderSizeY);
  1339.           Inc(target.Top, PanelTitleHeight);
  1340.      End;
  1341. End;
  1342.  
  1343.  
  1344. Function TDockingToolbar.GetTargetToolbarAlign(TargetForm:TForm; ptScreen:TPoint):TToolbarAlign;
  1345. Var  crect:TRect;
  1346.      Min:LongInt;
  1347.      ptForm:TPoint;
  1348. Begin
  1349.      Result := FToolAlign;
  1350.  
  1351.      If TargetForm <> Nil Then
  1352.      Begin // Get possible Toolbar Alignment
  1353.           ptForm := TargetForm.ScreenToClient(ptScreen);
  1354.           crect := TargetForm.ClientRect;
  1355.  
  1356.           Min := ptForm.X;
  1357.           Result := tbLeft;
  1358.           If crect.Right - ptForm.X < Min Then
  1359.           Begin
  1360.                Min := crect.Right - ptForm.X;
  1361.                Result := tbRight;
  1362.           End;
  1363.           If ptForm.Y < Min Then
  1364.           Begin
  1365.                Min := ptForm.Y;
  1366.                Result := tbBottom;
  1367.           End;
  1368.           If crect.Top - ptForm.Y < Min Then
  1369.           Begin
  1370.                Min := crect.Top - ptForm.Y;
  1371.                Result := tbTop;
  1372.           End;
  1373.      End;
  1374. End;
  1375.  
  1376.  
  1377. Const
  1378.      AligningPanels:Boolean=False;
  1379.  
  1380.  
  1381. Procedure TDockingToolbar.SetWindowPos(NewLeft,NewBottom,NewWidth,NewHeight:LongInt);
  1382. Var  ParentToolbar:TDockingFrame;
  1383.      AControl:TControl;
  1384.      horz:Boolean;
  1385.      I,S:LongInt;
  1386.      APos,ASize:LongInt;
  1387.      MaxPos:LongInt;
  1388.      ASort:TControl;
  1389.      ASortPos:LongInt;
  1390.      SortList:TList;
  1391.      inserted:Boolean;
  1392.      moved:Boolean;
  1393. Begin
  1394.      If IsDocked And (Not AligningPanels) Then // prevent overlapping
  1395.      Begin
  1396.           AligningPanels := True;
  1397.  
  1398.           ParentToolbar := TDockingFrame(parent);
  1399.           horz := ParentToolbar.Alignment In [tbTop,tbBottom];
  1400.           SortList.Create;
  1401.  
  1402.           {Sort the Panels}
  1403.           For I := 0 To ParentToolbar.ControlCount-1 Do
  1404.           Begin
  1405.                AControl := ParentToolbar.Controls[I];
  1406.                If csDetail In AControl.ComponentState Then continue;
  1407.  
  1408.                If AControl = Self Then // Use the New Parameter
  1409.                Begin
  1410.                     If horz Then APos := NewLeft
  1411.                     Else APos := NewBottom;
  1412.                End
  1413.                Else
  1414.                Begin
  1415.                     If horz Then APos := AControl.Left
  1416.                     Else APos := AControl.Bottom;
  1417.                End;
  1418.  
  1419.                {Insert In the sorted List}
  1420.                inserted := False;
  1421.                For S := 0 To SortList.Count-1 Do
  1422.                Begin
  1423.                     ASort := TControl(SortList[S]);
  1424.                     If ASort = Self Then // Use the New Parameter
  1425.                     Begin
  1426.                          If horz Then ASortPos := NewLeft
  1427.                          Else ASortPos := NewBottom;
  1428.                     End
  1429.                     Else
  1430.                     Begin
  1431.                          If horz Then ASortPos := ASort.Left
  1432.                          Else ASortPos := ASort.Bottom;
  1433.                     End;
  1434.  
  1435.                     If APos < ASortPos Then
  1436.                     Begin
  1437.                          SortList.Insert(S, AControl);
  1438.                          inserted := True;
  1439.                          break;
  1440.                     End;
  1441.                End;
  1442.                If Not inserted Then SortList.Add(AControl);
  1443.           End;
  1444.  
  1445.  
  1446.           {Arrange the Panels}
  1447.           MaxPos := 0;
  1448.           For I := 0 To SortList.Count-1 Do
  1449.           Begin
  1450.                AControl := TControl(SortList[I]);
  1451.                If AControl = Self Then // Use the New Parameter
  1452.                Begin
  1453.                     If horz Then
  1454.                     Begin
  1455.                          APos := NewLeft;
  1456.                          ASize := NewWidth;
  1457.                     End
  1458.                     Else
  1459.                     Begin
  1460.                          APos := NewBottom;
  1461.                          ASize := NewHeight;
  1462.                     End;
  1463.                End
  1464.                Else
  1465.                Begin
  1466.                     If horz Then
  1467.                     Begin
  1468.                          APos := AControl.Left;
  1469.                          ASize := AControl.Width;
  1470.                     End
  1471.                     Else
  1472.                     Begin
  1473.                          APos := AControl.Bottom;
  1474.                          ASize := AControl.Height;
  1475.                     End;
  1476.                End;
  1477.  
  1478.                If APos < MaxPos Then APos := MaxPos;
  1479.  
  1480.                If AControl = Self Then
  1481.                Begin {Arrange Self With Inherited}
  1482.                     If horz Then NewLeft := APos
  1483.                     Else NewBottom := APos;
  1484.                End
  1485.                Else
  1486.                Begin
  1487.                     If horz Then
  1488.                     Begin
  1489.                          moved := AControl.Left <> APos;
  1490.                          AControl.Left := APos;
  1491.                     End
  1492.                     Else
  1493.                     Begin
  1494.                          moved := AControl.Bottom <> APos;
  1495.                          AControl.Bottom := APos;
  1496.                     End;
  1497.  
  1498.                     If moved Then
  1499.                       If AControl Is TDockingToolbar
  1500.                       Then TDockingToolbar(AControl).Change;
  1501.                End;
  1502.  
  1503.                MaxPos := APos + ASize;
  1504.           End;
  1505.  
  1506.  
  1507.           SortList.Destroy;
  1508.           AligningPanels := False;
  1509.      End;
  1510.  
  1511.      Inherited SetWindowPos(NewLeft,NewBottom,NewWidth,NewHeight);
  1512.  
  1513.      If IsDocked Then
  1514.      Begin
  1515.           LastDockLeft := Left;
  1516.           LastDockBottom := Bottom;
  1517.           LastDockWidth := Width;
  1518.           LastDockHeight := Height;
  1519.      End;
  1520. End;
  1521.  
  1522.  
  1523. /////////////////////////////////////////////////////////////
  1524.  
  1525. Type
  1526.     TPosition=Record
  1527.          Left,Bottom,Width,Height:LongInt;
  1528.     End;
  1529.  
  1530.     TDockingData=Record
  1531.          DataSize:LongInt;
  1532.          PanelName:String[64];
  1533.          PanelPosition:TPosition;
  1534.          PanelAlign:TToolbarAlign;
  1535.          DockName:String[64];
  1536.          DockOrder:LongInt;
  1537.          DockingState:TDockingState;
  1538.          FormName:String[64];
  1539.          FormPosition:TPosition;
  1540.     End;
  1541.  
  1542.  
  1543. Procedure WriteDockingToolbars;
  1544. Var  I:LongInt;
  1545.      ADockTool:TDockingToolbar;
  1546.      AToolbar:TDockingFrame;
  1547.      Data:TDockingData;
  1548.      PanelForm:TForm;
  1549.      iniName,ext:String;
  1550.      F:File Of TDockingData;
  1551. Begin
  1552.      iniName := ParamStr(0);
  1553.      ext := ExtractFileExt(iniName);
  1554.      SetLength(iniName, Length(iniName) - Length(ext));
  1555.      iniName := iniName + '.dtb';
  1556.  
  1557.      {$I-}
  1558.      Assign(F, iniName);
  1559.      Rewrite(F);
  1560.  
  1561.      Data.DataSize := SizeOf(TDockingData);
  1562.  
  1563.      Try
  1564.         For I := 0 To DockingList.Count-1 Do
  1565.         Begin
  1566.              ADockTool := TDockingToolbar(DockingList[I]);
  1567.  
  1568.              PanelForm := ADockTool.FPanelForm;
  1569.              Data.FormName := PanelForm.Name;
  1570.  
  1571.              Data.FormPosition.Left := PanelForm.Left;
  1572.              Data.FormPosition.Bottom := PanelForm.Bottom;
  1573.              Data.FormPosition.Width := PanelForm.Width;
  1574.              Data.FormPosition.Height := PanelForm.Height;
  1575.  
  1576.              Data.PanelName := ADockTool.Name;
  1577.              Data.PanelPosition.Left := ADockTool.LastDockLeft;
  1578.              Data.PanelPosition.Bottom := ADockTool.LastDockBottom;
  1579.              Data.PanelPosition.Width := ADockTool.LastDockWidth;
  1580.              Data.PanelPosition.Height := ADockTool.LastDockHeight;
  1581.              Data.PanelAlign := ADockTool.ToolbarAlign;
  1582.  
  1583.              Data.DockingState := ADockTool.DockingState;
  1584.  
  1585.              Data.DockName := ADockTool.DockingForm.Name;
  1586.              If Data.DockingState = dsDock Then
  1587.              Begin
  1588.                   AToolbar := TDockingFrame(ADockTool.parent);
  1589.                   Data.DockOrder := AToolbar.order;
  1590.              End
  1591.              Else Data.DockOrder := -1;
  1592.  
  1593.              Write(F, Data);
  1594.         End;
  1595.         Close(F);
  1596.      Except
  1597.         Close(F);
  1598.         ErrorBox2('DTB Write Error');
  1599.      End;
  1600.      {$I+}
  1601. End;
  1602.  
  1603.  
  1604. Procedure ReadDockingToolbars;
  1605. Var  I,J:LongInt;
  1606.      ADockTool:TDockingToolbar;
  1607.      ATempDock:TDockingToolbar;
  1608.      AToolbar:TDockingFrame;
  1609.      AControl:TControl;
  1610.      AForm:TForm;
  1611.      Data:TDockingData;
  1612.      PanelForm:TForm;
  1613.      DockForm:TForm;
  1614.      iniName,ext:String;
  1615.      F:File Of TDockingData;
  1616.      AFormName:String;
  1617.      OwnerName:String;
  1618. Begin
  1619.      iniName := ParamStr(0);
  1620.      ext := ExtractFileExt(iniName);
  1621.      SetLength(iniName, Length(iniName) - Length(ext));
  1622.      iniName := iniName + '.dtb';
  1623.  
  1624.      {$I-}
  1625.      Assign(F, iniName);
  1626.      Reset(F,1);
  1627.  
  1628.      AligningPanels := True;
  1629.  
  1630.      If IOResult = 0 Then
  1631.      While Not Eof(F) Do
  1632.      Begin
  1633.         {Read A Data Set And Find the corresponding Panel In the List}
  1634.         Read(F, Data);
  1635.         If IOResult <> 0 Then break;
  1636.  
  1637.         If Data.DataSize <> SizeOf(TDockingData) Then break;
  1638.  
  1639.         {Search Panel}
  1640.         ADockTool := Nil;
  1641.  
  1642.         UpcaseStr(Data.FormName);
  1643.         UpcaseStr(Data.DockName);
  1644.  
  1645.         For I := 0 To DockingList.Count-1 Do
  1646.         Begin
  1647.              ATempDock := TDockingToolbar(DockingList[I]);
  1648.  
  1649.              If ATempDock.Name = Data.PanelName Then
  1650.                If ATempDock.Owner Is TForm Then
  1651.                Begin
  1652.                     OwnerName := ATempDock.Owner.Name;
  1653.                     UpcaseStr(OwnerName);
  1654.                     If OwnerName = Data.FormName Then
  1655.                     Begin
  1656.                          ADockTool := ATempDock;
  1657.                          break;
  1658.                     End;
  1659.                End;
  1660.         End;
  1661.         If ADockTool = Nil Then continue; {no Panel found For Data}
  1662.  
  1663.         {Panel found - Update the Status}
  1664.  
  1665.         If ADockTool.Designed Then continue; {no Designed dockbars}
  1666.  
  1667.         PanelForm := TForm(ADockTool.Owner);
  1668.         DockForm := Nil;
  1669.  
  1670.         For J := 0 To Screen.FormCount-1 Do
  1671.         Begin
  1672.              AForm := Screen.Forms[J];
  1673.              If AForm.Designed Then continue;
  1674.  
  1675.              AFormName := AForm.Name;
  1676.              UpcaseStr(AFormName);
  1677.  
  1678.              If DockForm = Nil Then
  1679.                If Data.DockName = AFormName Then DockForm := AForm;
  1680.         End;
  1681.  
  1682.         ADockTool.UndockPanel;
  1683.  
  1684.         ADockTool.FPanelForm := PanelForm;
  1685.         ADockTool.DockingForm := DockForm;
  1686.  
  1687.  
  1688.         AToolbar := Nil;
  1689.         If Data.DockOrder >= 0 Then
  1690.         Begin
  1691.           If DockForm <> Nil Then
  1692.           Begin // Search the Right Toolbar In the DockForm
  1693.             For J := 0 To DockForm.ControlCount-1 Do
  1694.             Begin
  1695.               AControl := DockForm.Controls[J];
  1696.               If AControl Is TDockingFrame Then
  1697.                 If TDockingFrame(AControl).Alignment = Data.PanelAlign Then
  1698.                   If TDockingFrame(AControl).DockOrder = Data.DockOrder Then
  1699.                   Begin
  1700.                        AToolbar := TDockingFrame(AControl);
  1701.                        AToolbar.DockOrder := Data.DockOrder;
  1702.                        break;
  1703.                   End;
  1704.             End;
  1705.           End;
  1706.         End;
  1707.  
  1708.         ADockTool.FToolAlign := Data.PanelAlign;
  1709.         ADockTool.LastDockLeft := 0;
  1710.         ADockTool.LastDockBottom := 0;
  1711.  
  1712.  
  1713.         If PanelForm <> Nil Then
  1714.         Begin
  1715.              PanelForm.SetWindowPos(Data.FormPosition.Left,
  1716.                                     Data.FormPosition.Bottom,
  1717.                                     Data.FormPosition.Width,
  1718.                                     Data.FormPosition.Height);
  1719.         End;
  1720.  
  1721.  
  1722.         If Data.DockingState = dsDock Then
  1723.         Begin
  1724.              {Set Size For non wrapped Panels}
  1725.              ADockTool.SetWindowPos(Data.PanelPosition.Left,
  1726.                                     Data.PanelPosition.Bottom,
  1727.                                     Data.PanelPosition.Width,
  1728.                                     Data.PanelPosition.Height);
  1729.  
  1730.              ADockTool.DockPanel(AToolbar);
  1731.  
  1732.              {Set New Toolbar order}
  1733.              If Data.DockOrder >= 0 Then
  1734.              Begin
  1735.                   AToolbar := TDockingFrame(ADockTool.parent);
  1736.                   AToolbar.order := Data.DockOrder;
  1737.                   AToolbar.DockOrder := Data.DockOrder;
  1738.              End;
  1739.         End;
  1740.  
  1741.  
  1742.         Case Data.DockingState Of
  1743.           dsDock:
  1744.           Begin
  1745.                {Set Size within the Toolbar}
  1746.                ADockTool.SetWindowPos(Data.PanelPosition.Left,
  1747.                                       Data.PanelPosition.Bottom,
  1748.                                       Data.PanelPosition.Width,
  1749.                                       Data.PanelPosition.Height);
  1750.           End;
  1751.           dsFloat:
  1752.           Begin
  1753.                ADockTool.FloatPanel;
  1754.           End;
  1755.           dsHide:
  1756.           Begin
  1757.                ADockTool.HidePanel;
  1758.           End;
  1759.         End;
  1760.      End;
  1761.  
  1762.      Close(F);
  1763.      {$I+}
  1764.  
  1765.      AligningPanels := False;
  1766. End;
  1767.  
  1768.  
  1769. Initialization
  1770.      DockingList.Create;
  1771.      OldTitleBarProc := Nil;
  1772.  
  1773. Finalization
  1774.      DockingList.Destroy;
  1775. End.
  1776.  
  1777.