PageRenderTime 65ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/DockPanel.pas

http://github.com/lookias/ProSnooper
Pascal | 1966 lines | 1581 code | 259 blank | 126 comment | 220 complexity | 514364e5bfcc69464af5f60e6c7221ca MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. {$A+,B-,C+,D+,E-,F-,G+,H+,I+,J+,K-,L+,M-,N+,O+,P+,Q-,R-,S-f,T-,U-,V+,W-,X+,Y+,Z1}
  2. {$MINSTACKSIZE $00004000}
  3. {$MAXSTACKSIZE $00100000}
  4. {$IMAGEBASE $00400000}
  5. {$APPTYPE GUI}
  6. {-------------------------------------------------------------------------------
  7. This is a modified version of the dockpanel originally written for the
  8. OpenPerl IDE. It's been made to be as easy to use as physicly possible,
  9. handling a lot of the stuff for you.
  10. }
  11. {-------------------------------------------------------------------------------
  12. The contents of this file are subject to the Mozilla Public License
  13. Version 1.1 (the "License"); you may not use this file except in compliance with
  14. the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
  15. Software distributed under the License is distributed on an "AS IS" basis,
  16. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  17. the specific language governing rights and limitations under the License.
  18. The Original Code is: DockPanel.pas, released 04 Nov 2001.
  19. The Initial Developer of the Original Code is Jürgen Güntherodt.
  20. Portions created by Jürgen Güntherodt <jguentherodt@users.sourceforge.net>
  21. are Copyright (C) 2001-2002 Jürgen Güntherodt. All Rights Reserved.
  22. Contributor: Stefan Ascher <stievie@users.sourceforge.net>
  23. Alternatively, the contents of this file may be used under the terms of the
  24. GNU General Public License Version 2 or later (the "GPL"), in which case
  25. the provisions of the GPL are applicable instead of those above.
  26. If you wish to allow use of your version of this file only under the terms
  27. of the GPL and not to allow others to use your version of this file
  28. under the MPL, indicate your decision by deleting the provisions above and
  29. replace them with the notice and other provisions required by the GPL.
  30. If you do not delete the provisions above, a recipient may use your version
  31. of this file under either the MPL or the GPL.
  32. $Id: DockPanel.pas,v 1.4 2002/05/26 13:47:35 jguentherodt Exp $
  33. You may retrieve the latest version of this file at the Open Perl IDE webpage,
  34. located at http://open-perl-ide.sourceforge.net or http://www.lost-sunglasses.de
  35. -------------------------------------------------------------------------------}
  36. unit DockPanel;
  37. interface
  38. uses
  39. extCtrls, controls, classes, windows, comCtrls, forms, sysUtils,
  40. graphics, messages, ImgList, iniFiles, registry, commctrl;
  41. Type TTabType=(ttText, ttTextIcon, ttIcon);
  42. type
  43. TDockHandler = class;
  44. TPageControlHost = class;
  45. TDockPanel = class(TPanel)
  46. private
  47. m_iWidth: Integer;
  48. m_bUnDocking: Boolean;
  49. TabPos: TTabPosition;
  50. m_iMinSize: Integer;
  51. m_bDockOnPageControl: Boolean;
  52. pSizer: TSplitter;
  53. protected
  54. procedure PSizerMoved(Sender: TObject);
  55. function CreateDockManager: IDockManager; override;
  56. procedure DockOver(Source: TDragDockObject; X, Y: Integer; State: TDragState; var Accept: Boolean); override;
  57. procedure UnDock(Sender: TObject; Client: TControl; NewTarget: TWinControl; var Allow: Boolean);
  58. procedure DoEndDock(Target: TObject; X, Y: Integer); override;
  59. procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean); override;
  60. procedure DoStartDock(var DragObject: TDragObject); override;
  61. function DoUnDock(NewTarget: TWinControl; Client: TControl): Boolean; override;
  62. procedure Resize(Sender: TObject);
  63. function GetAsString: String; virtual;
  64. procedure SetAsString(s: String); virtual;
  65. public
  66. constructor Create(AOwner: TComponent); override;
  67. destructor Destroy; override;
  68. procedure DockDrop(Source: TDragDockObject; X, Y: Integer); override;
  69. property AsString: String Read GetAsString Write SetAsString;
  70. property MinSizeWidth: Integer Read m_iMinSize Write m_iMinSize;
  71. published
  72. property TabPosition: TTabPosition read TabPos write TabPos;
  73. end;
  74. TSetOtherHostAsStringEvent = procedure(Sender: TDockHandler; sValue: String) of object;
  75. TGetOtherHostAsStringEvent = function(Sender: TDockHandler): String of object;
  76. TDockHandler = class
  77. private
  78. m_iMinSize: Integer;
  79. b_ShowGrabberBars: Boolean;
  80. m_slDockPanels: TStringList;
  81. m_slPageControlHosts: TStringList;
  82. m_slDockClients: TStringList;
  83. m_Owner: TComponent;
  84. m_OnRefresh: TNotifyEvent;
  85. m_slDockHosts: TStringList;
  86. m_OnSetOtherHostsAsString: TSetOtherHostAsStringEvent;
  87. m_OnGetOtherHostsAsString: TGetOtherHostAsStringEvent;
  88. m_pcShadow: TPageControl;
  89. TType: TTabType;
  90. m_nLockRefreshCount: Integer;
  91. function GetDockPanelCount: Integer;
  92. procedure SetTType(s: TTabType); Virtual;
  93. function GetDockPanels(i: Integer): TDockPanel;
  94. function GetPageControlHostCount: Integer;
  95. function GetPageControlHosts(i: Integer): TPageControlHost;
  96. function GetDockHostCount: Integer;
  97. function GetDockHosts(i: Integer): TWinControl;
  98. function GetDockClientCount: Integer;
  99. function GetDockClients(i: Integer): TWinControl;
  100. procedure BuildOldPageControl(sAlign, sData: String);
  101. procedure DoRefresh; virtual;
  102. procedure DoSetOtherHostsAsString(sValue: String);
  103. function DoGetOtherHostsAsString: String;
  104. protected
  105. function GetAsString: String; virtual;
  106. procedure SetAsString(s: String); virtual;
  107. procedure RegisterDockPanel(pnl: TDockPanel); virtual;
  108. procedure UnRegisterDockPanel(pnl: TDockPanel); virtual;
  109. procedure UnregisterPageControlHost(pch: TPageControlHost); virtual;
  110. procedure RegisterPageControlHost(pch: TPageControlHost); virtual;
  111. procedure RegisterDockClient(ctrl: TControl); virtual;
  112. procedure UnRegisterDockClient(ctrl: TControl); virtual;
  113. public
  114. bLoadSuccess: Boolean;
  115. constructor Create(AOwner: TComponent);
  116. destructor Destroy; override;
  117. procedure LockRefresh;
  118. procedure UnlockRefresh;
  119. procedure UnRegisterDockHost(wctrl: TWinControl);
  120. procedure SaveDesktop(regPath: String);
  121. procedure LoadDesktop(regPath: String);
  122. procedure RegisterDockHost(wctrl: TWinControl);
  123. procedure Refresh;
  124. property DockClientCount: Integer Read GetDockClientCount;
  125. property DockClients[i: Integer]: TWinControl Read GetDockClients;
  126. property DockHostCount: Integer Read GetDockHostCount;
  127. property DockHosts[i: Integer]: TWinControl Read GetDockHosts;
  128. property DockPanelCount: Integer Read GetDockPanelCount;
  129. property DockPanels[i: Integer]: TDockPanel Read GetDockPanels;
  130. property PageControlHostCount: Integer Read GetPageControlHostCount;
  131. property PageControlHosts[i: Integer]: TPageControlHost Read GetPageControlHosts;
  132. property AsString: String Read GetAsString Write SetAsString;
  133. property ShowGrabberBars: Boolean Read b_ShowGrabberBars Write b_ShowGrabberBars;
  134. property Owner: TComponent Read m_Owner;
  135. property OnRefresh: TNotifyEvent Read m_OnRefresh Write m_OnRefresh;
  136. property OnSetOtherHostsAsString: TSetOtherHostAsStringEvent Read m_OnSetOtherHostsAsString Write m_OnSetOtherHostsAsString;
  137. property OnGetOtherHostsAsString: TGetOtherHostAsStringEvent Read m_OnGetOtherHostsAsString Write m_OnGetOtherHostsAsString;
  138. property TabType: TTabType Read TType Write SetTType;
  139. end;
  140. TPageControlHost = class(TForm)
  141. PageControl: TPageControl;
  142. tmr: TTimer;
  143. img: TImageList;
  144. Timer1: TTimer;
  145. procedure PageControlUnDock(Sender: TObject; Client: TControl;
  146. NewTarget: TWinControl; var Allow: Boolean);
  147. procedure tmrTimer(Sender: TObject);
  148. procedure PageControlGetSiteInfo(Sender: TObject; DockClient: TControl;
  149. var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);
  150. procedure PageControlDockDrop(Sender: TObject; Source: TDragDockObject;
  151. X, Y: Integer);
  152. procedure PageControlChange(Sender: TObject);
  153. procedure PageControlDrawTab(Control: TCustomTabControl;
  154. TabIndex: Integer; const Rect: TRect; Active: Boolean);
  155. procedure TabSheet1Show(Sender: TObject);
  156. procedure TabSheet1Hide(Sender: TObject);
  157. procedure FormShow(Sender: TObject);
  158. private
  159. { Private declarations }
  160. m_bOnClose: Boolean;
  161. function GetVisibleDockClientCount: Integer;
  162. // procedure TextRotate(const S: string; x,y, deg : integer);
  163. protected
  164. function GetAsString: String; virtual;
  165. procedure SetAsString(s: String); virtual;
  166. procedure DoShow; override;
  167. procedure DoHide; override;
  168. procedure DoStartDock(var DragObject: TDragObject); override;
  169. procedure DoEndDock(Target: TObject; X, Y: Integer); override;
  170. public
  171. bUnDocking: Boolean;
  172. { Public declarations }
  173. constructor Create(AOwner: TComponent); override;
  174. destructor Destroy; override;
  175. property AsString: String Read GetAsString Write SetAsString;
  176. end;
  177. TDockableForm = class(TForm)
  178. private
  179. m_CaptionPanel: TPanel;
  180. m_LastHostDockSiteClass: TClass;
  181. SizePer: Integer;
  182. function GetVisible: Boolean;
  183. procedure SetVisible(b: Boolean);
  184. procedure FormHide(Sender: TObject);
  185. protected
  186. function GetAsString: String; virtual;
  187. procedure SetAsString(s: String); virtual;
  188. procedure DoEndDock(Target: TObject; X, Y: Integer); override;
  189. procedure DoShow; override;
  190. procedure DoHide; override;
  191. property AsString: String Read GetAsString Write SetAsString;
  192. public
  193. { Public declarations }
  194. constructor Create(AOwner: TComponent); override;
  195. destructor Destroy; override;
  196. procedure RefreshCaption; virtual;
  197. property Visible: Boolean Read GetVisible Write SetVisible;
  198. property LastHostDockSiteClass: TClass Read m_LastHostDockSiteClass;
  199. end;
  200. type
  201. TXPDockTree = class(TDockTree)
  202. FGrabberSize: Integer;
  203. protected
  204. property DockSite;
  205. public
  206. procedure AdjustDockRect(Control: TControl; var ARect: TRect); override;
  207. procedure PaintDockFrame(Canvas: TCanvas; Control: TControl; const ARect: TRect); override;
  208. procedure PaintSite(DC: HDC); override;
  209. constructor Create(DockSite: TWinControl);
  210. end;
  211. var
  212. bDontSize: BOolean;
  213. function DockHandler(AOwner: TComponent = nil): TDockHandler;
  214. procedure Register;
  215. implementation
  216. {$R *.DFM}
  217. // {$R F_DOCKABLEFORM.DFM}
  218. const
  219. InternalDockHandler: TDockHandler = nil;
  220. procedure Register;
  221. begin
  222. RegisterComponents('DockPanel', [TDockPanel]);
  223. end;
  224. function GetVisibleDockClientCount(win: TWinControl): Integer;
  225. var
  226. i: Integer;
  227. begin
  228. Result := 0;
  229. for i := 0 to win.DockClientCount - 1 do begin
  230. if win.DockClients[i].Visible then inc(Result);
  231. end;
  232. end;
  233. function DockHandler(AOwner: TComponent): TDockHandler;
  234. begin
  235. if InternalDockHandler = nil then InternalDockHandler := TDockHandler.Create(AOwner);
  236. Result := InternalDockHandler;
  237. end;
  238. function StrToBool(s: String): Boolean;
  239. begin
  240. if s = 'FALSE' then Result := False else Result := True;
  241. end;
  242. function BoolToStr(b: Boolean): String;
  243. begin
  244. if b then Result := 'TRUE' else Result := 'FALSE';
  245. end;
  246. ////////////////////////////////////////////////////////////////////////////////
  247. // TDockHandler = class(TComponent)
  248. ////////////////////////////////////////////////////////////////////////////////
  249. constructor TDockHandler.Create(AOwner: TComponent);
  250. begin
  251. inherited Create;
  252. m_Owner := AOwner;
  253. if not (csDesigning in m_Owner.ComponentState) then begin
  254. m_pcShadow := TPageControl.Create(m_Owner);
  255. m_pcShadow.Parent := TWinControl(m_Owner);
  256. m_pcShadow.Visible := False;
  257. m_pcShadow.DockSite := True;
  258. end;
  259. m_slDockPanels := TStringList.Create;
  260. m_slDockPanels.Sorted := True;
  261. m_slDockPanels.Duplicates := dupIgnore;
  262. m_slPageControlHosts := TStringList.Create;
  263. m_slPageControlHosts.Sorted := True;
  264. m_slPageControlHosts.Duplicates := dupIgnore;
  265. m_slDockClients := TStringList.Create;
  266. m_slDockClients.Sorted := True;
  267. m_slDockClients.Duplicates := dupIgnore;
  268. m_slDockHosts := TStringList.Create;
  269. m_slDockHosts.Sorted := True;
  270. m_slDockHosts.Duplicates := dupIgnore;
  271. AsString := '';
  272. end;
  273. destructor TDockHandler.Destroy;
  274. begin
  275. while DockPanelCount > 0 do UnRegisterDockPanel(DockPanels[0]);
  276. while PageControlHostCount > 0 do UnregisterPageControlHost(PageControlHosts[0]);
  277. while DockHostCount > 0 do UnregisterDockHost(DockHosts[0]);
  278. m_slDockHosts.Free;
  279. m_slDockPanels.Free;
  280. m_slPageControlHosts.Free;
  281. m_slDockClients.Free;
  282. inherited Destroy;
  283. end;
  284. procedure TdockHandler.SetTType(s: TTabType);
  285. begin
  286. TType := s;
  287. end;
  288. procedure TDockHandler.LockRefresh;
  289. begin
  290. inc(m_nLockRefreshCount);
  291. end;
  292. procedure TDockHandler.UnlockRefresh;
  293. begin
  294. if m_nLockRefreshCount > 0 then dec(m_nLockRefreshCount);
  295. if m_nLockRefreshCount = 0 then Refresh;
  296. end;
  297. function TDockHandler.GetDockClientCount: Integer;
  298. begin
  299. Result := m_slDockClients.Count;
  300. end;
  301. function TDockHandler.GetDockClients(i: Integer): TWinControl;
  302. begin
  303. Result := TWinControl(m_slDockClients.Objects[i]);
  304. end;
  305. function TDockHandler.DoGetOtherHostsAsString: String;
  306. begin
  307. if Assigned(m_OnGetOtherHostsAsString) then Result := m_OnGetOtherHostsAsString(Self);
  308. end;
  309. procedure TDockHandler.DoSetOtherHostsAsString(sValue: String);
  310. begin
  311. if Assigned(m_OnSetOtherHostsAsString) then m_OnSetOtherHostsAsString(Self, sValue);
  312. end;
  313. function TDockHandler.GetDockHostCount: Integer;
  314. begin
  315. Result := m_slDockHosts.Count;
  316. end;
  317. function TDockHandler.GetDockHosts(i: Integer): TWinControl;
  318. begin
  319. Result := TWinControl(m_slDockHosts.Objects[i]);
  320. end;
  321. procedure TDockHandler.UnRegisterDockHost(wctrl: TWinControl);
  322. var
  323. idx: Integer;
  324. begin
  325. idx := m_slDockHosts.IndexOf(IntToStr(Integer(wctrl)));
  326. if idx > -1 then m_slDockHosts.Delete(idx);
  327. end;
  328. procedure TDockHandler.RegisterDockHost(wctrl: TWinControl);
  329. begin
  330. m_slDockHosts.AddObject(IntToStr(Integer(wctrl)), wctrl);
  331. end;
  332. procedure TDockHandler.Refresh;
  333. begin
  334. if m_nLockRefreshCount = 0 then DoRefresh;
  335. end;
  336. procedure TDockHandler.DoRefresh;
  337. var i,b: Integer;
  338. pg: TPageControlHost;
  339. tf: TDockableForm;
  340. Icon: TIcon;
  341. begin
  342. for i := 0 to GetDockPanelCount-1 do
  343. if GetVisibleDockClientcount(GetDockPanels(i)) = 0 then begin
  344. With GetDockPanels(i) do begin
  345. Width := 0;
  346. Height := 0;
  347. if pSizer <> nil then begin
  348. pSizer.Align := alNone;
  349. pSizer.Visible := False;
  350. pSizer.Destroy;
  351. pSizer := nil;
  352. end;
  353. end;
  354. end
  355. else begin
  356. With GetDockPanels(i) do begin
  357. if (Align = alLeft) or (Align = alRight) then begin
  358. if Width < m_iMinSize then begin
  359. Width := m_iMinSize;
  360. end;
  361. end
  362. else begin
  363. if Height < m_iMinSize then begin
  364. Height := m_iMinSize;
  365. end;
  366. end;
  367. if pSizer = nil then begin
  368. // Place a splitter
  369. pSizer := TSplitter.Create(Parent);
  370. pSizer.OnMoved := PSizerMoved;
  371. pSizer.MinSize := m_iMinSize;
  372. pSizer.Color := clBtnFace;
  373. pSizer.Parent := Parent;
  374. pSizer.Align := Align;
  375. pSizer.Visible := True;
  376. pSizer.Width := 4;
  377. end;
  378. if Align = alTop then
  379. pSizer.Top := Height + Top;
  380. if Align = alBottom then
  381. pSizer.Top := Top;
  382. if Align = alLeft then
  383. pSizer.Left := Left + Width;
  384. if Align = alRight then
  385. pSizer.Left := Left;
  386. end;
  387. end;
  388. if Assigned(m_OnRefresh) then m_OnRefresh(Self);
  389. end;
  390. procedure TDockHandler.RegisterDockClient(ctrl: TControl);
  391. begin
  392. m_slDockClients.AddObject(IntToStr(Integer(ctrl)), ctrl);
  393. if ctrl.Owner <> nil then ctrl.Owner.RemoveComponent(ctrl);
  394. if Owner <> nil then Owner.InsertComponent(ctrl);
  395. end;
  396. procedure TDockHandler.UnRegisterDockClient(ctrl: TControl);
  397. var
  398. idx: Integer;
  399. begin
  400. idx := m_slDockClients.IndexOf(IntToStr(Integer(ctrl)));
  401. if idx > -1 then m_slDockClients.Delete(idx);
  402. end;
  403. function TDockHandler.GetDockPanelCount: Integer;
  404. begin
  405. Result := m_slDockPanels.Count;
  406. end;
  407. function TDockHandler.GetDockPanels(i: Integer): TDockPanel;
  408. begin
  409. Result := TDockPanel(m_slDockPanels.Objects[i]);
  410. end;
  411. function TDockHandler.GetPageControlHostCount: Integer;
  412. begin
  413. Result := m_slPageControlHosts.Count;
  414. end;
  415. function TDockHandler.GetPageControlHosts(i: Integer): TPageControlHost;
  416. begin
  417. Result := TPageControlHost(m_slPageControlHosts.Objects[i]);
  418. end;
  419. procedure TDockHandler.UnregisterPageControlHost(pch: TPageControlHost);
  420. var
  421. idx: Integer;
  422. begin
  423. idx := m_slPageControlHosts.IndexOf(IntToStr(Integer(pch)));
  424. if idx > -1 then m_slPageControlHosts.Delete(idx);
  425. end;
  426. procedure TDockHandler.RegisterPageControlHost(pch: TPageControlHost);
  427. begin
  428. m_slPageControlHosts.AddObject(IntToStr(Integer(pch)), pch);
  429. end;
  430. function TDockHandler.GetAsString: String;
  431. var
  432. sl: TStringList;
  433. i: Integer;
  434. sPageControlHosts: String;
  435. sDockPanels: String;
  436. sFloatingDockForms: String;
  437. frm: TDockableForm;
  438. begin
  439. sl := TStringList.Create;
  440. for i := 0 to m_slDockClients.Count - 1 do begin
  441. frm := TDockableForm(m_slDockClients.Objects[i]);
  442. if frm.HostDockSite = nil then sl.Values[frm.Name] := frm.AsString;
  443. end;
  444. sFloatingDockForms := sl.CommaText;
  445. sl.Clear;
  446. for i := 0 to PageControlHostCount - 1 do begin
  447. sl.Values[PageControlHosts[i].Name] := PageControlHosts[i].AsString;
  448. end;
  449. sPageControlHosts := sl.CommaText;
  450. sl.Clear;
  451. for i := 0 to DockPanelCount - 1 do begin
  452. sl.Values[DockPanels[i].Name] := DockPanels[i].AsString;
  453. end;
  454. sDockPanels := sl.CommaText;
  455. sl.Clear;
  456. sl.Values['FloatingDockForms'] := sFloatingDockForms;
  457. sl.Values['PageControlHosts'] := sPageControlHosts;
  458. sl.Values['DockPanels'] := sDockPanels;
  459. sl.Values['OtherHosts'] := DoGetOtherHostsAsString;
  460. sl.Values['Version'] := '1';
  461. Result := sl.CommaText;
  462. sl.Free;
  463. end;
  464. procedure TDockHandler.LoadDesktop(regPath: string);
  465. var
  466. reg: TRegistry;
  467. tmp: String;
  468. begin
  469. reg := TRegistry.Create;
  470. reg.OpenKey(regPath, True);
  471. bLoadSuccess := False;
  472. tmp:=AsString;
  473. if reg.ValueExists('dockData') then begin
  474. SetAsString(reg.ReadString('dockData'));
  475. bLoadSuccess := True;
  476. end;
  477. reg.Free;
  478. end;
  479. procedure TDockHandler.SaveDesktop(regPath: string);
  480. var
  481. reg: TRegistry;
  482. begin
  483. reg := TRegistry.Create;
  484. reg.OpenKey(regPath, True);
  485. reg.WriteString('dockData', AsString);
  486. reg.Free;
  487. end;
  488. procedure TDockHandler.BuildOldPageControl(sAlign, sData: String);
  489. var
  490. sl: TStringList;
  491. pch: TPageControlHost;
  492. cmp: TComponent;
  493. i: Integer;
  494. dp: TDockPanel;
  495. nTabIndex: Integer;
  496. begin
  497. sl := TStringList.Create;
  498. sl.CommaText := sData;
  499. if sl.Count > 3 then begin
  500. pch := TPageControlHost.Create(Owner);
  501. if DockHandler.TType = ttIcon then
  502. pch.PageControl.Images := pch.img;
  503. pch.Name := 'pc' + sAlign;
  504. cmp := Owner.FindComponent('dp' + sAlign);
  505. if (cmp <> nil) and (cmp is TDockPanel) then begin
  506. dp := TDockPanel(cmp);
  507. dp.Width := StrToIntDef(sl.Values['Width'], 200);
  508. dp.Height := StrToIntDef(sl.Values['Height'], 200);
  509. for i := 3 to sl.Count - 1 do begin
  510. cmp := Owner.FindComponent(sl.Names[i]);
  511. if (cmp <> nil) and (cmp is TDockableForm) then begin
  512. TDockableForm(cmp).AsString := sl.Values[cmp.Name];
  513. TDockableForm(cmp).ManualDock(pch.PageControl);
  514. end;
  515. end;
  516. pch.ManualDock(dp);
  517. nTabIndex := StrToIntDef(sl.Values['TabIndex'], -1);
  518. if (nTabIndex > -1) and (nTabIndex < pch.PageControl.PageCount) then
  519. pch.PageControl.ActivePage := pch.PageControl.Pages[nTabIndex];
  520. pch.Visible := True;
  521. end;
  522. end;
  523. sl.Free;
  524. end;
  525. procedure TDockHandler.SetAsString(s: String);
  526. var
  527. sl: TStringList;
  528. i: Integer;
  529. slFloatingDockForms: TStringList;
  530. slPageControlHosts: TStringList;
  531. slDockPanels: TStringList;
  532. cmp: TComponent;
  533. ctrl: TControl;
  534. rct: TRect;
  535. sVersion: String;
  536. begin
  537. // Lock updates
  538. LockRefresh;
  539. try
  540. bDontSize:=True;
  541. // Hide and float all registered dock clients
  542. for i := 0 to m_slDockClients.Count - 1 do begin
  543. ctrl := TControl(m_slDockClients.Objects[i]);
  544. TControl(m_slDockClients.Objects[i]).ManualDock(m_pcShadow);
  545. TControl(m_slDockClients.Objects[i]).Hide;
  546. if ctrl is TDockableForm then TDockableForm(ctrl).m_LastHostDockSiteClass := nil;
  547. rct := ctrl.BoundsRect;
  548. if ctrl.Parent <> nil then begin
  549. rct.TopLeft := ctrl.Parent.ClientToScreen(rct.TopLeft);
  550. rct.BottomRight := ctrl.Parent.ClientToScreen(rct.BottomRight);
  551. end;
  552. ctrl.ManualFloat(rct);
  553. end;
  554. // Destroy all dynamic page control hosts
  555. while PageControlHostCount > 0 do PageControlHosts[0].Free;
  556. sl := TStringList.Create;
  557. sl.CommaText := s;
  558. sVersion := UpperCase(sl.Values['Version']);
  559. if sVersion = '1' then begin
  560. // Handle floating dockable forms
  561. slFloatingDockForms := TStringList.Create;
  562. slFloatingDockForms.CommaText := sl.Values['FloatingDockForms'];
  563. for i := 0 to slFloatingDockForms.Count - 1 do begin
  564. cmp := Owner.FindComponent(slFloatingDockForms.Names[i]);
  565. if cmp <> nil then begin
  566. TDockableForm(cmp).AsString := slFloatingDockForms.Values[cmp.Name];
  567. end;
  568. end;
  569. slFloatingDockForms.Free;
  570. // Create dynamic page control hosts
  571. slPageControlHosts := TStringList.Create;
  572. slPageControlHosts.CommaText := sl.Values['PageControlHosts'];
  573. for i := 0 to slPageControlHosts.Count - 1 do begin
  574. cmp := Owner.FindComponent(slPageControlHosts.Names[i]);
  575. if cmp = nil then begin
  576. cmp := TPageControlHost.Create(Owner);
  577. TPageControlHost(cmp).SetParent(nil); //Owner as TWinControl);
  578. cmp.Name := slPageControlHosts.Names[i];
  579. end;
  580. TPageControlHost(cmp).AsString := slPageControlHosts.Values[cmp.Name];
  581. end;
  582. slPageControlHosts.Free;
  583. // Create dockpanels
  584. slDockPanels := TStringList.Create;
  585. slDockPanels.CommaText := sl.Values['DockPanels'];
  586. for i := 0 to slDockPanels.Count - 1 do begin
  587. cmp := Owner.FindComponent(slDockPanels.Names[i]);
  588. if cmp <> nil then begin
  589. TDockPanel(cmp).AsString := slDockPanels.Values[cmp.Name];
  590. if TDockPanel(cmp).DockClientCount = 0 then begin
  591. TDockPanel(cmp).Width := 0;
  592. TDockPanel(cmp).Height := 0;
  593. end;
  594. end;
  595. end;
  596. slDockPanels.Free;
  597. // Handle forms, which are docked in another way
  598. DoSetOtherHostsAsString(sl.Values['OtherHosts']);
  599. end else begin
  600. // Handle floating dockable forms
  601. slFloatingDockForms := TStringList.Create;
  602. slFloatingDockForms.CommaText := sl.Values['Floating'];
  603. for i := 0 to slFloatingDockForms.Count - 1 do begin
  604. cmp := Owner.FindComponent(slFloatingDockForms.Names[i]);
  605. if (cmp <> nil) and (cmp is TDockableForm) then begin
  606. TDockableForm(cmp).AsString := slFloatingDockForms.Values[cmp.Name];
  607. end;
  608. end;
  609. DoSetOtherHostsAsString('MainForm=' + slFloatingDockForms.Values['MainForm']);
  610. slFloatingDockForms.Free;
  611. BuildOldPageControl('Left', sl.Values['pcLeft']);
  612. BuildOldPageControl('Top', sl.Values['pcTop']);
  613. BuildOldPageControl('Right', sl.Values['pcRight']);
  614. BuildOldPageControl('Bottom', sl.Values['pcBottom']);
  615. end;
  616. sl.Free;
  617. finally
  618. // Unlock updates
  619. UnlockRefresh;
  620. bDontSize:=False;
  621. end;
  622. end;
  623. procedure TDockHandler.RegisterDockPanel(pnl: TDockPanel);
  624. begin
  625. m_slDockPanels.AddObject(IntToStr(Integer(pnl)), pnl);
  626. end;
  627. procedure TDockHandler.UnRegisterDockPanel(pnl: TDockPanel);
  628. var
  629. idx: Integer;
  630. begin
  631. idx := m_slDockPanels.IndexOf(IntToStr(Integer(pnl)));
  632. if idx > -1 then m_slDockPanels.Delete(idx);
  633. end;
  634. ////////////////////////////////////////////////////////////////////////////////
  635. // TDockPanel = class(TPanel)
  636. ////////////////////////////////////////////////////////////////////////////////
  637. constructor TDockPanel.Create(AOwner: TComponent);
  638. begin
  639. inherited Create(AOwner);
  640. // DockManager := TXPDockTree.Create(Self);
  641. m_iWidth := 200;
  642. m_iMinSize := 50;
  643. OnUnDock := UnDock;
  644. OnResize := Resize;
  645. DockHandler(AOwner).RegisterDockPanel(Self);
  646. end;
  647. procedure TDockPanel.PSizerMoved(Sender: TObject);
  648. begin
  649. if (Align = alLeft) or (Align = alRight) then begin
  650. if Width < m_iMinSize then begin
  651. Width := m_iMinSize;
  652. Dockhandler.Refresh;
  653. end;
  654. end
  655. else begin
  656. if Height < m_iMinSize then begin
  657. Height := m_iMinSize;
  658. DockHandler.Refresh;
  659. end;
  660. end;
  661. end;
  662. procedure TDockPanel.Resize(Sender: TObject);
  663. begin
  664. end;
  665. procedure TDockPanel.UnDock(Sender: TObject; Client: TControl; NewTarget: TWinControl; var Allow: Boolean);
  666. begin
  667. m_bUndocking := True;
  668. if (Align = alLeft) or (align = alRight) then
  669. m_iWidth := Width
  670. else
  671. m_iWidth := Height;
  672. if GetVisibleDockClientCount(Self) = 1 then begin
  673. if (Align = alLeft) or (Align = alRight) then
  674. Width := 0
  675. else
  676. Height := 0;
  677. if pSizer <> nil then begin
  678. // This should never be the case but better safe than
  679. // sorry :)
  680. pSizer.Align := alNone;
  681. pSizer.Destroy;
  682. pSizer := nil;
  683. end;
  684. end;
  685. end;
  686. destructor TDockPanel.Destroy;
  687. begin
  688. DockHandler.UnRegisterDockPanel(Self);
  689. inherited Destroy;
  690. end;
  691. function TDockPanel.CreateDockManager: IDockManager;
  692. begin
  693. Result := inherited CreateDockManager;
  694. (*
  695. if (DockManager = nil) and DockSite and UseDockManager then
  696. Result := TCustomDockTree.Create(Self)
  697. else
  698. Result := DockManager;
  699. *)
  700. end;
  701. procedure TDockPanel.SetAsString(s: String);
  702. var
  703. sl: TStringList;
  704. slDockClients: TStringList;
  705. cmp: TComponent;
  706. i: Integer;
  707. ms: TMemoryStream;
  708. h: String;
  709. begin
  710. sl := TStringList.Create;
  711. sl.CommaText := s;
  712. bDontSize := True;
  713. // Restore dock clients
  714. slDockClients := TStringList.Create;
  715. slDockClients.CommaText := sl.Values['DockClients'];
  716. for i := 0 to slDockClients.Count - 1 do begin
  717. cmp := Owner.FindComponent(slDockClients.Names[i]);
  718. if (cmp <> nil) and (cmp is TDockableForm) then begin
  719. TDockableForm(cmp).AsString := slDockClients.Values[cmp.Name];
  720. TDockableForm(cmp).m_CaptionPanel.Visible := True;
  721. end;
  722. end;
  723. slDockClients.Free;
  724. // Load width and height
  725. Width := StrToIntDef(sl.Values['Width'], 200);
  726. Height := StrToIntDef(sl.Values['Height'], 200);
  727. m_iWidth := StrToIntDef(sl.Values['iWidth'], 200);
  728. // Load and apply docking information
  729. h := sl.Values['DockingData'];
  730. ms := TMemoryStream.Create;
  731. ms.SetSize(Length(h) div 2);
  732. HexToBin(PChar(h), ms.Memory, Length(h));
  733. ms.Seek(0, soFromBeginning);
  734. DockManager.LoadFromStream(ms);
  735. DockManager.ResetBounds(True);
  736. ms.Free;
  737. bDontSize:=False;
  738. sl.Free;
  739. end;
  740. function TDockPanel.GetAsString: String;
  741. var
  742. i: Integer;
  743. sl: TStringList;
  744. ms: TMemoryStream;
  745. sDockingData: String;
  746. sDockClients: String;
  747. begin
  748. Result := '';
  749. sl := TStringList.Create;
  750. for i := 0 to DockClientCount - 1 do begin
  751. sl.Values[DockClients[i].Name] := TDockableForm(DockClients[i]).AsString;
  752. end;
  753. sDockClients := sl.CommaText;
  754. sl.Clear;
  755. // Use DockManager to store docking information
  756. ms := TMemoryStream.Create;
  757. DockManager.SaveToStream(ms);
  758. SetLength(sDockingData, 2 * ms.Size);
  759. BinToHex(ms.Memory, PChar(sDockingData), ms.Size);
  760. ms.Free;
  761. sl.Values['DockClients'] := sDockClients;
  762. sl.Values['Width'] := IntToStr(Width);
  763. sl.Values['Height'] := IntToStr(Height);
  764. sl.Values['iWidth'] := IntToStr(m_iWidth);
  765. sl.Values['DockingData'] := sDockingData;
  766. Result := sl.CommaText;
  767. if (Self.DockClientCount = 0) then begin
  768. Width := 0;
  769. Height := 0;
  770. end;
  771. sl.Free;
  772. end;
  773. procedure TDockPanel.DockDrop(Source: TDragDockObject; X, Y: Integer);
  774. var
  775. pch: TPageControlHost;
  776. begin
  777. m_bUndocking := True;
  778. if (Source.Control is TPageControlHost) then begin
  779. (Source.Control as TPageControlHost).PageControl.TabPosition := Self.TabPos;
  780. if ((Source.Control as TPageControlHost).PageControl.TabPosition <> tpLeft) and ((Source.Control as TPageControlHost).PageControl.TabPosition <> tpRight) then
  781. (Source.Control as TPageControlHost).PageControl.MultiLine := False;
  782. end;
  783. if m_bDockOnPageControl then begin
  784. pch := TPageControlHost.Create(Owner);
  785. pch.Parent := Self;
  786. pch.BoundsRect := Source.DropOnControl.ClientRect;
  787. pch.Visible := True;
  788. m_bDockOnPageControl := False;
  789. pch.PageControl.OwnerDraw := False;
  790. pch.ReplaceDockedControl(Source.DropOnControl, pch.PageControl, nil, alClient);
  791. Source.Control.ManualDock(pch.PageControl);
  792. pch.Caption := pch.PageControl.ActivePage.Caption;
  793. pch.PageControl.OwnerDraw := True;
  794. pch.PageControl.TabPosition := Self.TabPos;
  795. if (pch.PageControl.TabPosition <> tpLeft) and (pch.PageControl.TabPosition <> tpRight) then
  796. pch.PageControl.MultiLine := False;
  797. end else begin
  798. inherited DockDrop(Source, x, y);
  799. if m_iWidth < m_iMinSize then m_iWidth := m_iMinSize;
  800. if pSizer = nil then begin
  801. // Place a splitter
  802. pSizer := TSplitter.Create(Self.Parent);
  803. pSizer.OnMoved := PSizerMoved;
  804. pSizer.MinSize := m_iMinSize;
  805. pSizer.Color := clBtnFace;
  806. pSizer.Parent := Self.Parent;
  807. pSizer.Align := Self.Align;
  808. pSizer.Visible := True;
  809. pSizer.Width := 4;
  810. end;
  811. if (Self.DockClientCount =1) and (bDontSize=False) then
  812. if (Self.Align = alLeft) or (Align = alRight) then
  813. Width := m_iWidth
  814. else
  815. Height := m_iWidth;
  816. if Align = alTop then
  817. pSizer.Top := Self.Height + Self.Top;
  818. if Align = alBottom then
  819. pSizer.Top := Self.Top;
  820. if Align = alLeft then
  821. pSizer.Left := Self.Left + Self.Width;
  822. if Align = alRight then
  823. pSizer.Left := Self.Left;
  824. end;
  825. end;
  826. procedure TDockPanel.DockOver(Source: TDragDockObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
  827. var
  828. rct: TRect;
  829. nFrameWidth, nFrameHeight: Integer;
  830. begin
  831. inherited DockOver(Source, x, y, State, Accept);
  832. m_bDockOnPageControl := False;
  833. if GetVisibleDockClientCount(Self) = 0 then begin
  834. if m_iWidth < m_iMinSize then m_iWidth := m_iMinSize;
  835. if Self.Align = alLeft then begin
  836. rct.TopLeft := Point(0, 0);
  837. rct.BottomRight := Point(m_iWidth, ClientHeight);
  838. rct.TopLeft := ClientToScreen(rct.TopLeft);
  839. rct.BottomRight := ClientToScreen(rct.BottomRight);
  840. Source.DockRect := rct;
  841. end
  842. else if Self.Align = alRight then begin
  843. rct.TopLeft := Point(Width - m_iWidth, 0);
  844. rct.BottomRight := Point(ClientWidth, ClientHeight);
  845. rct.TopLeft := ClientToScreen(rct.TopLeft);
  846. rct.BottomRight := ClientToScreen(rct.BottomRight);
  847. Source.DockRect := rct;
  848. end
  849. else if Self.Align = alBottom then begin
  850. rct.TopLeft := Point(0, ClientHeight - m_iWidth);
  851. rct.BottomRight := Point(Width, ClientHeight);
  852. rct.TopLeft := ClientToScreen(rct.TopLeft);
  853. rct.BottomRight := ClientToScreen(rct.BottomRight);
  854. Source.DockRect := rct;
  855. end
  856. else begin
  857. rct.TopLeft := Point(0, 0);
  858. rct.BottomRight := Point(Width, Top + m_iWidth);
  859. rct.TopLeft := ClientToScreen(rct.TopLeft);
  860. rct.BottomRight := ClientToScreen(rct.BottomRight);
  861. Source.DockRect := rct;
  862. end;
  863. end;
  864. if (Source.DropOnControl <> nil) and (not (Source.Control is TPageControlHost)) then begin
  865. if Source.Control.HostDockSite <> nil then begin
  866. if Source.Control.HostDockSite.Parent = Source.DropOnControl then exit;
  867. end;
  868. if Source.Control = Source.DropOnControl then exit;
  869. rct := Source.DropOnControl.BoundsRect;
  870. nFrameWidth := (rct.Right - rct.Left) div 5;
  871. nFrameHeight := (rct.Bottom - rct.Top) div 5;
  872. rct.Left := rct.Left + nFrameWidth;
  873. rct.Top := rct.Top + nFrameHeight;
  874. rct.Right := rct.Right - nFrameWidth;
  875. rct.Bottom := rct.Bottom - nFrameHeight;
  876. if PtInRect(rct, Point(x, y)) then begin
  877. rct.TopLeft := ClientToScreen(rct.TopLeft);
  878. rct.BottomRight := ClientToScreen(rct.BottomRight);
  879. Source.DockRect := rct;
  880. m_bDockOnPageControl := True;
  881. end;
  882. end;
  883. end;
  884. procedure TDockPanel.DoEndDock(Target: TObject; X, Y: Integer);
  885. begin
  886. inherited DoEndDock(Target, x, y);
  887. end;
  888. procedure TDockPanel.GetSiteInfo(Client: TControl; var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);
  889. begin
  890. inherited GetSiteInfo(Client, InfluenceRect, MousePos, CanDock);
  891. end;
  892. procedure TDockPanel.DoStartDock(var DragObject: TDragObject);
  893. begin
  894. inherited DoStartDock(DragObject);
  895. end;
  896. function TDockPanel.DoUnDock(NewTarget: TWinControl; Client: TControl): Boolean;
  897. begin
  898. Result := inherited DoUndock(NewTarget, Client);
  899. DockHandler.Refresh;
  900. end;
  901. ////////////////////////////////////////////////////////////////////////////////
  902. // TPageControlHost = class(TForm)
  903. ////////////////////////////////////////////////////////////////////////////////
  904. constructor TPageControlHost.Create(AOwner: TComponent);
  905. begin
  906. inherited Create(AOwner);
  907. DragKind := dkDock;
  908. DragMode := dmAutomatic;
  909. PageControl.HotTrack := True;
  910. DockHandler.RegisterPageControlHost(Self);
  911. PageControl.OwnerDraw := True;
  912. PageControl.DoubleBuffered := True;
  913. if DockHandler.TType = ttIcon then begin
  914. PageControl.TabWidth := 40;
  915. PageControl.TabHeight := 26;
  916. end
  917. else if DockHandler.TType = ttTextIcon then begin
  918. PageControl.TabWidth := 120;
  919. PageControl.TabHeight := 30;
  920. end
  921. else begin
  922. PageControl.TabWidth := 100;
  923. PageControl.TabHeight := 30;
  924. end;
  925. PageControl.Font.Name := 'Arial';
  926. end;
  927. destructor TPageControlHost.Destroy;
  928. begin
  929. DockHandler.UnregisterPageControlHost(Self);
  930. inherited Destroy;
  931. end;
  932. procedure TPageControlHost.DoStartDock(var DragObject: TDragObject);
  933. begin
  934. PageControl.SetFocus;
  935. inherited DoStartDock(DragObject);
  936. end;
  937. procedure TPageControlHost.DoEndDock(Target: TObject; X, Y: Integer);
  938. begin
  939. inherited DoEndDock(Target, x, y);
  940. { if (not (Self.Parent is TDockPanel)) then begin}
  941. Self.Left := Self.Left;
  942. Self.Top := Self.Top;
  943. // end;
  944. DockHandler.Refresh;
  945. end;
  946. procedure TPageControlHost.DoShow;
  947. begin
  948. inherited DoShow;
  949. DockHandler.Refresh;
  950. end;
  951. procedure TPageControlHost.DoHide;
  952. begin
  953. inherited DoHide;
  954. DockHandler.Refresh;
  955. end;
  956. function TPageControlHost.GetVisibleDockClientCount: Integer;
  957. var
  958. i: Integer;
  959. begin
  960. Result := 0;
  961. for i := 0 to PageControl.DockClientCount - 1 do begin
  962. if PageControl.DockClients[i].Visible then inc(Result);
  963. end;
  964. end;
  965. function TPageControlHost.GetAsString: String;
  966. var
  967. sl: TStringList;
  968. i: Integer;
  969. s: String;
  970. ctrl: TControl;
  971. pt: TPoint;
  972. begin
  973. sl := TStringList.Create;
  974. // Docked Controls, ActivePage, Visibility
  975. for i := 0 to PageControl.DockClientCount - 1 do begin
  976. ctrl := PageControl.DockClients[i];
  977. sl.Values[ctrl.Name] := TDockableForm(ctrl).AsString;
  978. end;
  979. s := sl.CommaText;
  980. sl.Clear;
  981. sl.Values['DockedControls'] := s;
  982. sl.Values['ActivePage'] := PageControl.ActivePage.Caption;
  983. pt := Point(Left, Top);
  984. if HostDockSite <> nil then pt := HostDockSite.ClientToScreen(pt);
  985. sl.Values['Left'] := IntToStr(pt.x);
  986. sl.Values['Top'] := IntToStr(pt.y);
  987. sl.Values['Width'] := IntToStr(Width);
  988. sl.Values['Height'] := IntToStr(Height);
  989. // PageControl.TabPosition := TTabPosition(StrToIntDef(sl.Values['TabPos'], 0);
  990. sl.Values['TabPos'] := IntToStr(Integer(PageControl.TabPosition));
  991. sl.Values['Visible'] := BoolToStr(Visible);
  992. sl.Values['Floating'] := BoolToStr(HostDockSite = nil);
  993. Result := sl.CommaText;
  994. sl.Free;
  995. end;
  996. procedure TPageControlHost.SetAsString(s: String);
  997. var
  998. sl, slDockedControls: TStringList;
  999. sCaption: String;
  1000. i: Integer;
  1001. cmp: TComponent;
  1002. nLeft, nTop, nWidth, nHeight: Integer;
  1003. bFloating: Boolean;
  1004. begin
  1005. Visible := False;
  1006. sl := TStringList.Create;
  1007. sl.CommaText := s;
  1008. // Apply page control docking
  1009. slDockedControls := TStringList.Create;
  1010. slDockedControls.CommaText := sl.Values['DockedControls'];
  1011. for i := 0 to slDockedControls.Count - 1 do begin
  1012. cmp := Owner.FindComponent(slDockedControls.Names[i]);
  1013. if (cmp <> nil) and (cmp is TDockableForm) then begin
  1014. TDockableForm(cmp).AsString := slDockedControls.Values[cmp.Name];
  1015. TDockableForm(cmp).m_CaptionPanel.Visible := False;
  1016. TControl(cmp).ManualDock(PageControl);
  1017. end;
  1018. end;
  1019. slDockedControls.Free;
  1020. // Set active page
  1021. sCaption := sl.Values['ActivePage'];
  1022. for i := 0 to PageControl.PageCount - 1 do begin
  1023. if PageControl.Pages[i].Caption = sCaption then
  1024. PageControl.ActivePage := PageControl.Pages[i];
  1025. end;
  1026. nLeft := StrToIntDef(sl.Values['Left'], 0);
  1027. nTop := StrToIntDef(sl.Values['Top'], 0);
  1028. nWidth := StrToIntDef(sl.Values['Width'], 200);
  1029. nHeight := StrToIntDef(sl.Values['Height'], 200);
  1030. PageControl.TabPosition := TTabPosition(StrToIntDef(sl.Values['TabPos'], 0));
  1031. if (PageControl.TabPosition <> tpLeft) and (PageControl.TabPosition <> tpRight) then
  1032. PageControl.MultiLine := False;
  1033. BoundsRect := Rect(nLeft, nTop, nLeft + nWidth, nTop + nHeight);
  1034. bFloating := StrToBool(sl.Values['Floating']);
  1035. if not bFloating then begin
  1036. ManualDock(DockHandler.m_pcShadow);
  1037. Align := alNone;
  1038. end;
  1039. // Set visibility
  1040. Visible := StrToBool(sl.Values['Visible']);
  1041. Caption := PageControl.ActivePage.Caption;
  1042. sl.Free;
  1043. end;
  1044. procedure TPageControlHost.PageControlUnDock(Sender: TObject;
  1045. Client: TControl; NewTarget: TWinControl; var Allow: Boolean);
  1046. begin
  1047. bUnDocking := True;
  1048. if m_bOnClose then exit;
  1049. // if PageControl.DockClientCount = 2 then begin
  1050. if GetVisibleDockClientCount <= 2 then begin
  1051. // at maximum one visible DockClient remains on page control
  1052. m_bOnClose := True;
  1053. tmr.Enabled := True;
  1054. end;
  1055. end;
  1056. procedure TPageControlHost.tmrTimer(Sender: TObject);
  1057. var
  1058. i,b: Integer;
  1059. ctrl: TControl;
  1060. sl: TStringList;
  1061. tf: TDockableForm;
  1062. rct: TRect;
  1063. begin
  1064. tmr.Enabled := False;
  1065. sl := TStringList.Create;
  1066. i := 0;
  1067. ctrl := nil;
  1068. while i < PageControl.DockClientCount do begin
  1069. if PageControl.DockClients[i].Visible then begin
  1070. ctrl := PageControl.DockClients[i];
  1071. end else begin
  1072. sl.AddObject('', PageControl.DockClients[i]);
  1073. end;
  1074. inc(i);
  1075. end;
  1076. for i := 0 to sl.Count - 1 do begin
  1077. rct := TControl(sl.Objects[i]).BoundsRect;
  1078. rct.TopLeft := ClientToScreen(rct.TopLeft);
  1079. rct.BottomRight := ClientToScreen(rct.BottomRight);
  1080. TControl(sl.Objects[i]).ManualFloat(rct);
  1081. end;
  1082. sl.Free;
  1083. if ctrl <> nil then ctrl.ReplaceDockedControl(Self, nil, nil, alNone);
  1084. PostMessage(Handle, WM_CLOSE, 0, 0);
  1085. end;
  1086. procedure TPageControlHost.PageControlGetSiteInfo(Sender: TObject;
  1087. DockClient: TControl; var InfluenceRect: TRect; MousePos: TPoint;
  1088. var CanDock: Boolean);
  1089. begin
  1090. CanDock := DockClient.HostDockSite <> PageControl;
  1091. if CanDock = true then
  1092. CanDock := (DockClient.Tag <> 1) and (DockClient.Tag <> 2);
  1093. end;
  1094. procedure TPageControlHost.PageControlDockDrop(Sender: TObject;
  1095. Source: TDragDockObject; X, Y: Integer);
  1096. var
  1097. pch: TPageControlHost;
  1098. Icon: TIcon;
  1099. begin
  1100. //MessageBox(0, PChar(IntToStr(PageControl.PageCount)), 'test' , MB_OK);
  1101. if Source.Control is TPageControlHost then begin
  1102. pch := Source.Control as TPageControlHost;
  1103. while pch.PageControl.DockClientCount > 0 do begin
  1104. pch.PageControl.DockClients[0].ManualDock(PageControl);
  1105. end;
  1106. end;
  1107. if Source.Control is TDockableForm then begin
  1108. PageControl.Pages[PageControl.PageCount - 1].OnHide := TabSheet1Hide;
  1109. if (DockHandler.TType = TTIcon) or (DockHandler.TType = TTTextIcon) then begin
  1110. if (Source.Control as TdockableForm).Icon <> nil then begin
  1111. PageControl.Images := img;
  1112. Icon := TIcon.Create;
  1113. Icon := (Source.Control as TDockableForm).Icon;
  1114. PageControl.Pages[PageControl.PageCount - 1].ImageIndex := img.AddIcon(Icon);
  1115. PageControl.Pages[PageControl.PageCount - 1].OnShow := TabSheet1Show;
  1116. end;
  1117. end;
  1118. end;
  1119. Caption := PageControl.ActivePage.Caption;
  1120. end;
  1121. ////////////////////////////////////////////////////////////////////////////////
  1122. // TDockableForm = class(TForm)
  1123. ////////////////////////////////////////////////////////////////////////////////
  1124. constructor TDockableForm.Create(AOwner: TComponent);
  1125. var
  1126. pnl: TPanel;
  1127. begin
  1128. OnHide := FormHide;
  1129. inherited Create(AOwner);
  1130. m_CaptionPanel := TPanel.Create(Self);
  1131. m_CaptionPanel.Parent := Self;
  1132. with m_CaptionPanel do begin
  1133. Height := 0;
  1134. Align := alTop;
  1135. BevelInner := bvNone;
  1136. BevelOuter := bvNone;
  1137. end;
  1138. // Caption
  1139. pnl := TPanel.Create(Self);
  1140. pnl.Parent := m_CaptionPanel;
  1141. pnl.Align := alClient;
  1142. pnl.Alignment := taLeftJustify;
  1143. pnl.Caption := ' ' + Self.Caption;
  1144. pnl.BevelInner := bvNone;
  1145. pnl.BevelOuter := bvNone;
  1146. pnl.Font.Color := clNavy;
  1147. DockHandler(AOwner).RegisterDockClient(Self);
  1148. end;
  1149. destructor TDockableForm.Destroy;
  1150. begin
  1151. DockHandler.UnRegisterDockClient(Self);
  1152. inherited Destroy;
  1153. end;
  1154. function TDockableForm.GetVisible: Boolean;
  1155. var
  1156. ctr: TWinControl;
  1157. begin
  1158. Result := inherited Visible;
  1159. ctr := Parent;
  1160. while Result and (ctr <> nil) do begin
  1161. if not (ctr is TTabSheet) then Result := ctr.Visible;
  1162. ctr := ctr.Parent;
  1163. end;
  1164. end;
  1165. procedure TDockableForm.SetVisible(b: Boolean);
  1166. var
  1167. ctr: TWinControl;
  1168. pc: TPageControl;
  1169. begin
  1170. if b then begin
  1171. if (m_LastHostDockSiteClass <> nil) and (Parent = nil) then begin
  1172. DockHandler.DoSetOtherHostsAsString(m_LastHostDockSiteClass.ClassName + '=' + Name);
  1173. inherited Visible := True;
  1174. exit;
  1175. end;
  1176. inherited Visible := True;
  1177. ctr := Parent;
  1178. while ctr <> nil do begin
  1179. ctr.Visible := True;
  1180. if ctr is TTabSheet then begin
  1181. pc := TTabSheet(ctr).PageControl;
  1182. if pc <> nil then pc.ActivePage := TTabSheet(ctr);
  1183. end else if ctr is TForm then begin
  1184. ctr.BringToFront;
  1185. end;
  1186. ctr := ctr.Parent;
  1187. end;
  1188. end else begin
  1189. inherited Visible := False;
  1190. end;
  1191. end;
  1192. procedure TDockableForm.RefreshCaption;
  1193. begin
  1194. m_CaptionPanel.Visible := (HostDockSite <> nil) and (HostDockSite is TDockPanel);
  1195. end;
  1196. procedure TDockableForm.DoShow;
  1197. begin
  1198. if HostDockSite <> nil then begin
  1199. m_LastHostDockSiteClass := HostDockSite.ClassType;
  1200. end else begin
  1201. m_LastHostDockSiteClass := nil;
  1202. end;
  1203. if (HostDockSite is TDockPanel) then begin
  1204. if (HostDockSite.VisibleDockClientCount = 1) then
  1205. (HostDockSite as TDockPanel).Width := (HostDockSite as TDockPanel).m_iWidth;
  1206. end;
  1207. inherited DoShow;
  1208. DockHandler.Refresh;
  1209. end;
  1210. procedure TDockableForm.DoHide;
  1211. begin
  1212. if HostDockSite <> nil then begin
  1213. m_LastHostDockSiteClass := HostDockSite.ClassType;
  1214. end else begin
  1215. m_LastHostDockSiteClass := nil;
  1216. end;
  1217. if HostDockSite is TDockPanel then begin
  1218. (HostDockSite as TDockPanel).m_iWidth := (HostDockSite as TDockPanel).Width;
  1219. end;
  1220. inherited DoHide;
  1221. DockHandler.Refresh;
  1222. end;
  1223. procedure TDockableForm.DoEndDock(Target: TObject; X, Y: Integer);
  1224. begin
  1225. if HostDockSite <> nil then begin
  1226. m_LastHostDockSiteClass := HostDockSite.ClassType;
  1227. end else begin
  1228. m_LastHostDockSiteClass := nil;
  1229. end;
  1230. inherited DoEndDock(Target, x, y);
  1231. if (not (Self.Parent is TDockPanel)) and (not (Self.Parent is TTabSheet)) then begin
  1232. Self.Left := Self.Left;
  1233. Self.Top := Self.Top;
  1234. end;
  1235. DockHandler.Refresh;
  1236. end;
  1237. function TDockableForm.GetAsString: String;
  1238. var
  1239. sl: TStringList;
  1240. pt: TPoint;
  1241. begin
  1242. sl := TStringList.Create;
  1243. pt := Point(Left, Top);
  1244. if HostDockSite <> nil then pt := HostDockSite.ClientToScreen(pt);
  1245. sl.Values['Left'] := IntToStr(pt.x);
  1246. sl.Values['Top'] := IntToStr(pt.y);
  1247. sl.Values['Width'] := IntToStr(Width);
  1248. sl.Values['Height'] := IntToStr(Height);
  1249. sl.Values['Visible'] := BoolToStr(inherited Visible);
  1250. sl.Values['Floating'] := BoolToStr(HostDockSite = nil);
  1251. Result := sl.CommaText;
  1252. sl.Free;
  1253. end;
  1254. procedure TDockableForm.SetAsString(s: String);
  1255. var
  1256. sl: TStringList;
  1257. nLeft, nTop, nWidth, nHeight: Integer;
  1258. bFloating: Boolean;
  1259. begin
  1260. sl := TStringList.Create;
  1261. sl.CommaText := s;
  1262. nLeft := StrToIntDef(sl.Values['Left'], 0);
  1263. nTop := StrToIntDef(sl.Values['Top'], 0);
  1264. nWidth := StrToIntDef(sl.Values['Width'], 200);
  1265. nHeight := StrToIntDef(sl.Values['Height'], 200);
  1266. BoundsRect := Rect(nLeft, nTop, nLeft + nWidth, nTop + nHeight);
  1267. bFloating := StrToBool(sl.Values['Floating']);
  1268. if not bFloating then ManualDock(DockHandler.m_pcShadow);
  1269. inherited Visible := StrToBool(sl.Values['Visible']);
  1270. sl.Free;
  1271. end;
  1272. procedure DrawRaisedEdge (DC: HDC; R: TRect; const FillInterior: Boolean);
  1273. const
  1274. FillMiddle: array[Boolean] of UINT = (0, BF_MIDDLE);
  1275. begin
  1276. DrawEdge (DC, R, BDR_RAISEDINNER, BF_RECT or FillMiddle[FillInterior]);
  1277. end;
  1278. procedure TPageControlHost.PageControlChange(Sender: TObject);
  1279. begin
  1280. Caption := PageControl.ActivePage.Caption;
  1281. if (PageControl.ActivePage.Controls[0] is TDockableForm) then
  1282. (PageControl.ActivePage.Controls[0] as TDockableForm).Resize;
  1283. end;
  1284. procedure TPageControlHost.PageControlDrawTab(Control: TCustomTabControl;
  1285. TabIndex: Integer; const Rect: TRect; Active: Boolean);
  1286. var
  1287. ar, ar2: TRect;
  1288. Icon: TIcon;
  1289. imgX, imgY, txtX, txtY, bSize: Integer;
  1290. i, s: Integer;
  1291. bFound: Boolean;
  1292. begin
  1293. for i := 0 to TabIndex do begin
  1294. if PageControl.Pages[i].TabVisible = false then
  1295. Inc(TabIndex, 1);
  1296. end;
  1297. //
  1298. {bFound := False;
  1299. for i := TabIndex to PageControl.PageCount - 1 do begin
  1300. if PageControl.Pages[i].TabVisible = true then begin
  1301. TabIndex := i;
  1302. bFound := True;
  1303. break;
  1304. end;
  1305. end;
  1306. if bFound = false then exit;}
  1307. if DockHandler.b_ShowGrabberBars then
  1308. bSize := 8
  1309. else
  1310. bSize := 10;
  1311. if (PageControl.TabPosition <> tpBottom) and (PageControl.TabPosition <> tpTop) then begin
  1312. PageControl.TabWidth := 32 + bSize;
  1313. PageControl.TabHeight := 26;
  1314. end
  1315. else begin
  1316. if DockHandler.TType = ttIcon then begin
  1317. PageControl.TabWidth := 32 + bSize;
  1318. PageControl.TabHeight := 26;
  1319. end
  1320. else if DockHandler.TType = ttTextIcon then begin
  1321. PageControl.TabWidth := 112 + bSize;
  1322. PageControl.TabHeight := 30;
  1323. end
  1324. else begin
  1325. PageControl.TabWidth := 96 + bSize;
  1326. PageControl.TabHeight := 30;
  1327. end;
  1328. end;
  1329. PageControl.Canvas.Pen.Color := clBtnFace;
  1330. PageControl.Canvas.FillRect(Rect);
  1331. if Active then begin
  1332. if PageControl.TabPosition = tpTop then begin
  1333. With ar do begin
  1334. Left := rect.Left + 7;
  1335. Right := rect.Left + 9;
  1336. Bottom := rect.Bottom - 11;
  1337. Top := rect.Top + 7;
  1338. end;
  1339. With ar2 do begin
  1340. Left := rect.Left + 10;
  1341. Right := rect.Left + 12;
  1342. Bottom := rect.Bottom - 11;
  1343. Top := rect.Top + 7;
  1344. end;
  1345. end
  1346. else if PageControl.TabPosition = tpBottom then begin
  1347. With ar do begin
  1348. Left := rect.Left + 7;
  1349. Right := rect.Left + 9;
  1350. Bottom := rect.Bottom - 9;
  1351. Top := rect.Top + 9;
  1352. end;
  1353. With ar2 do begin
  1354. Left := rect.Left + 10;
  1355. Right := rect.Left + 12;
  1356. Bottom := rect.Bottom - 9;
  1357. Top := rect.Top + 9;
  1358. end;
  1359. end
  1360. else begin
  1361. if PageControl.TabPosition = tpLeft then begin
  1362. With ar do begin
  1363. Left := rect.Left + 9;
  1364. Right := Rect.Right - 7;
  1365. Bottom := rect.Bottom - 10;
  1366. Top := rect.Bottom - 12;
  1367. end;
  1368. With ar2 do begin
  1369. Left := rect.Left + 9;
  1370. Right := Rect.Right - 7;
  1371. Bottom := rect.Bottom - 7;
  1372. Top := rect.Bottom - 9;
  1373. end;
  1374. end else begin
  1375. With ar do begin
  1376. Left := rect.Right - 9;
  1377. Right := Rect.Left + 7;
  1378. Bottom := rect.Bottom - 10;
  1379. Top := rect.Bottom - 12;
  1380. end;
  1381. With ar2 do begin
  1382. Left := rect.Right - 9;
  1383. Right := Rect.Left + 7;
  1384. Bottom := rect.Bottom - 7;
  1385. Top := rect.Bottom - 9;
  1386. end;
  1387. end;
  1388. end;
  1389. end
  1390. else begin
  1391. if (PageControl.TabPosition = tpBottom) or (PageControl.TabPosition = tpTop) then begin
  1392. With ar do begin
  1393. Left := rect.Left + 3;
  1394. Right := rect.Left + 5;
  1395. Bottom := rect.Bottom - 5;
  1396. Top := rect.Top + 7;
  1397. end;
  1398. With ar2 do begin
  1399. Left := rect.Left + 6;
  1400. Right := rect.Left + 8;
  1401. Bottom := rect.Bottom - 5;…

Large files files are truncated, but you can click here to view the full file