uDockForm.pas
上传用户:lmk588
上传日期:2013-04-16
资源大小:5120k
文件大小:7k
源码类别:

按钮控件

开发平台:

Delphi

  1. unit uDockForm;
  2. interface
  3. uses
  4.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus,
  5.   ExtCtrls, StdCtrls, ComCtrls;
  6. type
  7.   TDockableForm = class(TForm)
  8.     Button1: TButton;
  9.     CheckBox1: TCheckBox;
  10.     UpDown1: TUpDown;
  11.     procedure FormDockOver(Sender: TObject; Source: TDragDockObject; X,
  12.       Y: Integer; State: TDragState; var Accept: Boolean);
  13.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  14.     procedure FormShow(Sender: TObject);
  15.   private
  16.     function ComputeDockingRect(var DockRect: TRect; MousePos: TPoint): TAlign;
  17.     procedure CMDockClient(var Message: TCMDockClient); message CM_DOCKCLIENT;
  18.   public
  19.   end;
  20. implementation
  21. {$R *.dfm}
  22. uses uTabHost, uConjoinHost, uMain;
  23. procedure TDockableForm.FormDockOver(Sender: TObject;
  24.   Source: TDragDockObject; X, Y: Integer; State: TDragState;
  25.   var Accept: Boolean);
  26. var
  27.   ARect: TRect;
  28. begin
  29.   Accept := (Source.Control is TDockableForm);
  30.   //Draw dock preview depending on where the cursor is relative to our client area
  31.   if Accept and (ComputeDockingRect(ARect, Point(X, Y)) <> alNone) then
  32.     Source.DockRect := ARect;
  33. end;
  34. function TDockableForm.ComputeDockingRect(var DockRect: TRect; MousePos: TPoint): TAlign;
  35. var
  36.   DockTopRect,
  37.   DockLeftRect,
  38.   DockBottomRect,
  39.   DockRightRect,
  40.   DockCenterRect: TRect;
  41. begin
  42.   Result := alNone;
  43.   //divide form up into docking "Zones"
  44.   DockLeftRect.TopLeft := Point(0, 0);
  45.   DockLeftRect.BottomRight := Point(ClientWidth div 5, ClientHeight);
  46.   DockTopRect.TopLeft := Point(ClientWidth div 5, 0);
  47.   DockTopRect.BottomRight := Point(ClientWidth div 5 * 4, ClientHeight div 5);
  48.   DockRightRect.TopLeft := Point(ClientWidth div 5 * 4, 0);
  49.   DockRightRect.BottomRight := Point(ClientWidth, ClientHeight);
  50.   DockBottomRect.TopLeft := Point(ClientWidth div 5, ClientHeight div 5 * 4);
  51.   DockBottomRect.BottomRight := Point(ClientWidth div 5 * 4, ClientHeight);
  52.   DockCenterRect.TopLeft := Point(ClientWidth div 5, ClientHeight div 5);
  53.   DockCenterRect.BottomRight := Point(ClientWidth div 5 * 4, ClientHeight div 5 * 4);
  54.   //Find out where the mouse cursor is, to decide where to draw dock preview.
  55.   if PtInRect(DockLeftRect, MousePos) then
  56.     begin
  57.       Result := alLeft;
  58.       DockRect := DockLeftRect;
  59.       DockRect.Right := ClientWidth div 2;
  60.     end
  61.   else
  62.     if PtInRect(DockTopRect, MousePos) then
  63.       begin
  64.         Result := alTop;
  65.         DockRect := DockTopRect;
  66.         DockRect.Left := 0;
  67.         DockRect.Right := ClientWidth;
  68.         DockRect.Bottom := ClientHeight div 2;
  69.       end
  70.     else
  71.       if PtInRect(DockRightRect, MousePos) then
  72.         begin
  73.           Result := alRight;
  74.           DockRect := DockRightRect;
  75.           DockRect.Left := ClientWidth div 2;
  76.         end
  77.       else
  78.         if PtInRect(DockBottomRect, MousePos) then
  79.           begin
  80.             Result := alBottom;
  81.             DockRect := DockBottomRect;
  82.             DockRect.Left := 0;
  83.             DockRect.Right := ClientWidth;
  84.             DockRect.Top := ClientHeight div 2;
  85.          end
  86.         else
  87.           if PtInRect(DockCenterRect, MousePos) then
  88.           begin
  89.             Result := alClient;
  90.             DockRect := DockCenterRect;
  91.           end;
  92.   if Result = alNone then Exit;
  93.   //DockRect is in screen coordinates.
  94.   DockRect.TopLeft := ClientToScreen(DockRect.TopLeft);
  95.   DockRect.BottomRight := ClientToScreen(DockRect.BottomRight);
  96. end;
  97. procedure TDockableForm.FormClose(Sender: TObject;
  98.   var Action: TCloseAction);
  99. begin
  100.   //the action taken depends on how the form is docked.
  101.   if (HostDockSite is TConjoinDockHost) then
  102.   begin
  103.     //remove the form's caption from the conjoin dock host's caption list
  104.     TConjoinDockHost(HostDockSite).UpdateCaption(Self);
  105.     //if we're the last visible form on a conjoined form, hide the form
  106.     if HostDockSite.VisibleDockClientCount <= 1 then
  107.       HostDockSite.Hide;
  108.   end;
  109.   //if docked to a panel, tell the panel to hide itself. If there are other
  110.   //visible dock clients on the panel, it ShowDockPanel won't allow it to
  111.   //be hidden
  112.   if (HostDockSite is TPanel) then
  113.     MainForm.ShowDockPanel(HostDockSite as TPanel, False, nil);
  114.   Action := caHide;
  115. end;
  116. procedure TDockableForm.CMDockClient(var Message: TCMDockClient);
  117. var
  118.   ARect: TRect;
  119.   DockType: TAlign;
  120.   Host: TForm;
  121.   Pt: TPoint;
  122. begin
  123.   //Overriding this message allows the dock form to create host forms
  124.   //depending on the mouse position when docking occurs. If we don't override
  125.   //this message, the form will use VCL's default DockManager.
  126.   //NOTE: the only time ManualDock can be safely called during a drag
  127.   //operation is we override processing of CM_DOCKCLIENT.
  128.   if Message.DockSource.Control is TDockableForm then
  129.   begin
  130.     //Find out how to dock (Using a TAlign as the result of ComputeDockingRect)
  131.     Pt.x := Message.MousePos.x;
  132.     Pt.y := Message.MousePos.y;
  133.     DockType := ComputeDockingRect(ARect, Pt);
  134.     //if we are over a dockable form docked to a panel in the
  135.     //main window, manually dock the dragged form to the panel with
  136.     //the correct orientation.
  137.     if (HostDockSite is TPanel) then
  138.     begin
  139.       Message.DockSource.Control.ManualDock(HostDockSite, nil, DockType);
  140.       Exit;
  141.     end;
  142.     //alClient => Create a TabDockHost and manually dock both forms to the PageControl
  143.     //owned by the TabDockHost.
  144.     if DockType = alClient then
  145.     begin
  146.       Host := TTabDockHost.Create(Application);
  147.       Host.BoundsRect := Self.BoundsRect;
  148.       Self.ManualDock(TTabDockHost(Host).PageControl1, nil, alClient);
  149.       Message.DockSource.Control.ManualDock(TTabDockHost(Host).PageControl1, nil, alClient);
  150.       Host.Visible := True;
  151.     end
  152.     //if DockType <> alClient, create the ConjoinDockHost and manually dock both
  153.     //forms to it. Be sure to make dockable forms non-dockable when hosted by
  154.     // ConjoinDockForm, since it is using the VCL default DockManager.
  155.     else begin
  156.       Host := TConjoinDockHost.Create(Application);
  157.       Host.BoundsRect := Self.BoundsRect;
  158.       Self.ManualDock(Host, nil, alNone);
  159.       Self.DockSite := False;
  160.       Message.DockSource.Control.ManualDock(Host, nil, DockType);
  161.       TDockableForm(Message.DockSource.Control).DockSite := False;
  162.       Host.Visible := True;
  163.     end;
  164.   end;
  165. end;
  166. procedure TDockableForm.FormShow(Sender: TObject);
  167. begin
  168.   if HostDockSite is TConjoinDockHost then
  169.     TConjoinDockHost(HostDockSite).UpdateCaption(nil);
  170.   if MainForm.skindata1.active then
  171.      MainForm.skindata1.skinform(handle);
  172. end;
  173. end.