CnDelphiDockStyle.pas 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. {******************************************************************************}
  2. { CnPack For Delphi/C++Builder }
  3. { 中国人自己的开放源码第三方开发包 }
  4. { (C)Copyright 2001-2018 CnPack 开发组 }
  5. { ------------------------------------ }
  6. { }
  7. { 本开发包是开源的自由软件,您可以遵照 CnPack 的发布协议来修 }
  8. { 改和重新发布这一程序。 }
  9. { }
  10. { 发布这一开发包的目的是希望它有用,但没有任何担保。甚至没有 }
  11. { 适合特定目的而隐含的担保。更详细的情况请参阅 CnPack 发布协议。 }
  12. { }
  13. { 您应该已经和开发包一起收到一份 CnPack 发布协议的副本。如果 }
  14. { 还没有,可访问我们的网站: }
  15. { }
  16. { 网站地址:http://www.cnpack.org }
  17. { 电子邮件:master@cnpack.org }
  18. { }
  19. {******************************************************************************}
  20. {*******************************************************}
  21. { }
  22. { 具有类似Delphi的停靠风格 }
  23. { CnDelphiDockStyle 单元 }
  24. { }
  25. { 版权 (C) 2002,2003 鲁小班 }
  26. { }
  27. {*******************************************************}
  28. unit CnDelphiDockStyle;
  29. {* |<PRE>
  30. ================================================================================
  31. * 软件名称:不可视工具组件包停靠单元
  32. * 单元名称:具有类似Delphi的停靠风格的单元
  33. * 单元作者:CnPack开发组 周益波(鲁小班)
  34. * 备 注:本单元由原作者授权CnPack开发组移植,已保留原作者版权信息
  35. * 开发平台:
  36. * 兼容测试:PWin9X/2000/XP + Delphi 5/6/7
  37. * 本 地 化:该单元中的字符串均符合本地化处理方式
  38. * 单元标识:$Id$
  39. * 修改记录:2007.07.13 V1.0
  40. * 移植单元
  41. ================================================================================
  42. |</PRE>}
  43. interface
  44. {$I CnPack.inc}
  45. uses
  46. Windows, Classes, Controls, Math, Messages, Graphics,
  47. CnDockFormControl, CnDockSupportControl, CnDockTree, CnConsts, CnCompConsts;
  48. type
  49. TCnDelphiDockStyle = class(TCnBasicDockStyle)
  50. protected
  51. procedure GetComponentInfo(var AName, Author, Email, Comment: string); override;
  52. procedure FormDockDrop(DockClient: TCnDockClient;
  53. Source: TCnDragDockObject; X, Y: Integer); override;
  54. public
  55. constructor Create(AOwner: TComponent); override;
  56. // class function GetControlName: string; override;
  57. function GetControlName: string; override;
  58. published
  59. property ConjoinServerOption;
  60. property TabServerOption;
  61. end;
  62. TCnDelphiDockSplitter = class(TCnDockSplitter);
  63. TCnDelphiDockPanel = class(TCnDockPanel);
  64. TCnDelphiConjoinPanel = class(TCnConjoinPanel);
  65. TCnDelphiTabPageControl = class(TCnTabPageControl)
  66. protected
  67. procedure CMDockClient(var Message: TCMDockClient); message CM_DOCKCLIENT;
  68. end;
  69. TCnDelphiDockZone = class(TCnDockZone);
  70. TCnDelphiDockTree = class(TCnDockTree);
  71. TCnDelphiDragDockObject = class(TCnDragDockObject);
  72. implementation
  73. uses
  74. Forms, SysUtils, CnDockSupportProc, CnDockGlobal;
  75. { TCnDelphiDockStyle }
  76. constructor TCnDelphiDockStyle.Create(AOwner: TComponent);
  77. begin
  78. inherited Create(AOwner);
  79. CnDockPanelClass := TCnDelphiDockPanel;
  80. CnDockSplitterClass := TCnDelphiDockSplitter;
  81. CnConjoinPanelClass := TCnDelphiConjoinPanel;
  82. CnTabDockClass := TCnDelphiTabPageControl;
  83. CnDockPanelZoneClass := TCnDelphiDockZone;
  84. CnDockPanelTreeClass := TCnDelphiDockTree;
  85. CnConjoinPanelZoneClass := TCnDelphiDockZone;
  86. CnConjoinPanelTreeClass := TCnDelphiDockTree;
  87. end;
  88. procedure TCnDelphiDockStyle.FormDockDrop(DockClient: TCnDockClient;
  89. Source: TCnDragDockObject; X, Y: Integer);
  90. var
  91. ARect,DRect: TRect;
  92. DockType: TAlign;
  93. Host: TForm;
  94. APanelDock: TWinControl;
  95. ADockClient: TCnDockClient;
  96. begin
  97. if IsDockable(DockClient.ParentForm, Source.Control, Source.DropOnControl, Source.DropAlign) then
  98. begin
  99. // 调用ComputeDockingRect函数知道停靠的类型
  100. Host := nil;
  101. { 锁住Windows桌面 }
  102. if not IsLoading then
  103. Cn_LockWindow(nil);
  104. try
  105. with DockClient do
  106. begin
  107. DockType := ComputeDockingRect(DockClient.ParentForm, ARect, Point(X, Y));
  108. if (ParentForm.HostDockSite is TCnDockPanel) then
  109. begin
  110. // 如果停靠服务器是TDockPanel,就停靠在TDockServer的DockPanel上。
  111. if DockType = alClient then
  112. begin
  113. // 如果停靠类型是alClient
  114. if Source.Control is TCnTabDockHostForm then
  115. begin
  116. // 如果停靠客户是TCnTabDockHostForm,
  117. // 就先把Parent停靠到TCnTabDockHostForm中,
  118. // 再把TCnTabDockHostForm停靠到TCnDockPanel中。
  119. APanelDock := ParentForm.HostDockSite;
  120. ARect := ParentForm.BoundsRect;
  121. ParentForm.ManualDock(TCnTabDockHostForm(Source.Control).PageControl, nil, alClient);
  122. TCnTabDockHostForm(Source.Control).PageControl.ActivePage.PageIndex := 0;
  123. Source.Control.BoundsRect := ARect;
  124. Source.Control.ManualDock(APanelDock, nil, alClient);
  125. if ParentForm.FormStyle = fsStayOnTop then
  126. TForm(Source.Control).FormStyle := fsStayOnTop;
  127. end else
  128. begin
  129. // 否则就创建TCnTabDockHostForm,
  130. // 把把Parent停靠到TCnTabDockHostForm中,
  131. // 再把TCnTabDockHostForm停靠到TCnDockPanel中。
  132. APanelDock := ParentForm.HostDockSite;
  133. DRect.TopLeft := ParentForm.HostDockSite.ClientToScreen(Point(0, 0));
  134. Host := CreateTabHostAndDockControl(ParentForm, Source.Control);
  135. SetDockSite(ParentForm, False);
  136. SetDockSite(TWinControl(Source.Control), False);
  137. Host.Top := DRect.Top;
  138. Host.Left := DRect.Left;
  139. Host.ManualDock(APanelDock, nil, alClient);
  140. Host.Visible := True;
  141. end;
  142. end
  143. else
  144. begin
  145. // 如果停靠类型不是alClient,
  146. // 就把停靠窗体停靠到TCnDockPanel.
  147. DRect := ParentForm.HostDockSite.BoundsRect;
  148. Source.Control.ManualDock(ParentForm.HostDockSite, nil, DockType);
  149. ParentForm.HostDockSite.BoundsRect := DRect;
  150. end;
  151. Exit;
  152. end;
  153. // 创建分页的服务窗体
  154. if DockType = alClient then
  155. begin
  156. if Source.Control is TCnTabDockHostForm then
  157. begin
  158. ARect := DockClient.ParentForm.BoundsRect;
  159. DockClient.ParentForm.ManualDock(TCnTabDockHostForm(Source.Control).PageControl, nil, alClient);
  160. TCnTabDockHostForm(Source.Control).PageControl.ActivePage.PageIndex := 0;
  161. Source.Control.BoundsRect := ARect;
  162. if DockClient.ParentForm.FormStyle = fsStayOnTop then
  163. TCnTabDockHostForm(Source.Control).FormStyle := fsStayOnTop;
  164. Exit;
  165. end else
  166. begin
  167. Host := DockClient.CreateTabHostAndDockControl(DockClient.ParentForm, Source.Control);
  168. Host.Visible := True;
  169. end;
  170. end
  171. // 创建平铺的服务窗体
  172. else if DockType <> alNone then
  173. begin
  174. Host := CreateConjoinHostAndDockControl(ParentForm, Source.Control, DockType);
  175. ADockClient := FindDockClient(Host);
  176. if ADockClient <> nil then
  177. ADockClient.EnableDock := False;
  178. SetDockSite(ParentForm, False);
  179. SetDockSite(TWinControl(Source.Control), False);
  180. Host.Visible := True;
  181. end;
  182. if Host <> nil then
  183. begin
  184. Host.LRDockWidth := Source.Control.LRDockWidth;
  185. Host.TBDockHeight := Source.Control.TBDockHeight;
  186. end;
  187. end;
  188. finally
  189. { 解锁Windows桌面 }
  190. if not IsLoading then
  191. Cn_UnLockWindow;
  192. end;
  193. end;
  194. end;
  195. procedure TCnDelphiDockStyle.GetComponentInfo(var AName, Author, Email,
  196. Comment: string);
  197. begin
  198. AName := SCnDelphiDockStyleName;
  199. Author := SCnPack_LuXiaoban;
  200. Email := SCnPack_LuXiaobanEmail;
  201. Comment := SCnDelphiDockStyleComment;
  202. end;
  203. function TCnDelphiDockStyle.GetControlName: string;
  204. begin
  205. Result := Format(gs_LikeDelphiStyle, [inherited GetControlName]);
  206. end;
  207. { TCnDelphiTabPageControl }
  208. procedure TCnDelphiTabPageControl.CMDockClient(var Message: TCMDockClient);
  209. var i: Integer;
  210. AControl: TControl;
  211. APageCount: Integer;
  212. begin
  213. if Message.DockSource.Control is TCnTabDockHostForm then
  214. begin
  215. with TCnTabDockHostForm(Message.DockSource.Control) do
  216. begin
  217. APageCount := Self.PageCount;
  218. for i := PageControl.DockClientCount - 1 downto 0 do
  219. begin
  220. AControl := PageControl.DockClients[i];
  221. DoFloat(PageControl, AControl);
  222. AControl.ManualDock(Self, nil, alClient);
  223. Self.ActivePage.PageIndex := APageCount;
  224. end;
  225. end;
  226. end else
  227. inherited;
  228. end;
  229. end.