Using the TDockTabSet component by Jeremy North

http://edn.embarcadero.com/article/33446

 

Abstract: Instructions on how to use the TDockTabSet component to make advanced docking user interfaces.

Introduction 

This article discusses the use of the TDockTabSet component that was originally introduced in Delphi 2005.

Creating the applications main form

Create a File | New | VCL Forms Application - Delphi for Win32.

Setting up the main form 
Locate the TDockTabSet component  on the additional page in the Tool Palette and drop it onto the main form. 
  1. Set the following properties:

    AlignalLeft
    DockSiteFalse
    ShrinkToFitTrue
    StyletsModernTabs
    TabPositiontpLeft
    Width25

You may want to use the tsModernPopup tab style instead of the tsModernTabs. The download that accompanies this article does.


To keep the TDockTabSet component company on the form, drop the following components and modify the properties as indicated.
  1. TPanel 
    AlignalTop
    BevelKindbkTile
    BevelOuterbvNone
    Caption 
  2. TPanel 
    AlignalLeft
    BevelOuterbvNone
    DockSiteTrue
    NamepDockLeft
    Width0
  3. TSplitter
    AlignalLeft
  4. TMemo
    AlignClient
  5. Drop a TButton on the top aligned Panel and set its caption to Show Form
  6. Set the Forms caption to TDockTabSetDemo Application
  7. Name the form frmMain and save the unit as MainForm

If you name your components differently remember to reference the correct name when adding the source code.


The main form of your application should look something like the following.  

Hide image

The setting of the all important property

There is one more property that needs to be set on the TDockTabSet before we can continue. Set the   DestinationDockSite  to be the left aligned panel. Called pDockLeft in this article.  

Now it's time to create another form for the application. There are now 3 ways this can be done in Delphi 2006 and I'll mention all of them:

  1. Select the File | New | Form for Win32 or
  2. Click on the Project Manager
    1. In the Tool Palette you will see the object repository items get added.
    2. Locate the Delphi Projects | Delphi Files category.
    3. Double click on the Form icon to create a New Form.
  3. Right click on the project manager and select the Add New menu item. From the sub menu select Form.
I prefer the 3rd method, which is new to Delphi 2006 and I've discussed previously on my   blog.


Name the new form frmDock and save the unit as DockForm.
In the code editor for this unit do the following.
  1. Delete the global frmDock: TfrmDock variable from the forms implementation section, it isn't required
  2. Make sure the form isn't in the list of forms that are created automatically (I always turn this option off by default). To do this select the Project | Options menu item and move frmDock to the Available Forms list for the Forms option page.
  3. Add an OnClose event that contains the following code
procedure TfrmDock.FormClose(Sender: TObject; var Action: TCloseAction);

begin

  ManualFloat(Rect(0, 0, 0, 0));

  Action := caFree;

end;

4. Add an OnStartDock event that contains the following code
procedure TfrmDock.FormStartDock(Sender: TObject; var DragObject:

  TDragDockObject);

begin

  DragObject := TDragDockObjectEx.Create(Self);

  DragObject.Brush.Color := clAqua; // this will display a red outline

end;

5. Create a new class function called CreateDockForm that accepts a TColor, returns a TCustomForm and contains the following code.
class function TfrmDock.CreateDockForm(const aColor: TColor): TCustomForm;

begin

  result := TfrmDock.Create(Application);

  result.Color := aColor;

  result.Caption := ColorToString(aColor);

  result.Show;

end;

6. Finally modify the following properties on the dock form
  1. BorderStylebsSizeToolWin
    DragKinddkDock
    DragModedmAutomatic

You may also want to modify the size of the frmDock form to not be so wide.  
That is the form that will be docked completed. Time to write some in the main unit!

Switch to the MainForm unit now and make the following changes.

1. Invoke the Use Unit dialog (Alt+F11 or File | Use Unit) and select the DockForm unit.
2. Create an OnClick event for the TButton with the following code
procedure TfrmMain.Button1Click(Sender: TObject);

var

  i: Integer;

begin

  // close all previously dockable forms before recreating

  for i := 0 to Screen.FormCount - 1 do

    if Screen.Forms[i] is TfrmDock then

      Screen.Forms[i].Close;

  // dock to the component called pDockLeft

  TfrmDock.CreateDockForm(clBlue).ManualDock(pDockLeft);

  // dock to the top on the pDockLeft panel

  TfrmDock.CreateDockForm(clGreen).ManualDock(pDockLeft, nil, alTop);

  // dock to the right on the pDockLeft panel

  TfrmDock.CreateDockForm(clRed).ManualDock(pDockLeft, nil, alRight);

  // dock directly to the DockTabSet

  TfrmDock.CreateDockForm(clWhite).ManualDock(DockTabSet1);

end;


The remaining code is required to get the docking behavior to play nice amongst each other.

1. Create an OnDockDrop event for the pDockLeft panel and add the following code
This OnDockDrop event makes sure that the width of the pDockLeft panel is sufficient for when the frmDock form is dropped on it. If the panel previously had a width of 0 (which means you can't see it) then set the width to 150. This value is hardcoded for the demo but I could have easily read the current width of the control being dropped and using that value. You can get the width of the control being dropped from the TDragDockObject passed in as the   Source  parameter. You would use the following to get the width of the control that is being dropped:
  pDockLeft.Width := Source.Control.Width;
The OnDockDrop code also makes sure that the splitter is visible when a form is being docked and that it is in the correct position.
procedure TfrmMain.pDockLeftDockDrop(Sender: TObject; Source: TDragDockObject; X, Y: Integer);

begin

  if pDockLeft.Width = 0 then

    pDockLeft.Width := 150;

  Splitter1.Visible := True;

  Splitter1.Left := pDockLeft.Width;

end;

2. Create an OnUndock event for the pDockLeft panel and add the following code
If the form being undocked is the last one on it then we need to set the Panels width back to 0 and hide the Splitter.
procedure TfrmMain.pDockLeftUnDock(Sender: TObject; Client: TControl; NewTarget: TWinControl; var Allow: Boolean);

begin

  if pDockLeft.DockClientCount = 1 then

  begin

    pDockLeft.Width := 0;

    Splitter1.Visible := False;

  end;

end;

3. Create an OnDockOver event for the pDockLeft panel and add the code below.
The DockOver event is the event responsible for drawing the forms outline at the dock site.
procedure TfrmMain.pDockLeftDockOver(Sender: TObject; Source: TDragDockObject; X, Y: Integer; State: TDragState;

  var Accept: Boolean);

var

  lRect: TRect;

begin

  Accept := Source.Control is TfrmDock;

  if Accept then

  begin

    lRect.TopLeft := pDockLeft.ClientToScreen(Point(0, 0));

    lRect.BottomRight := pDockLeft.ClientToScreen(Point(150, pDockLeft.Height));

    Source.DockRect := lRect;

  end;

end;


4. Create an OnDockDrop event for the DockTabSet1 component and add the code below.
If a control is being docked to the DockTabSet component we want to make sure it is visible.
procedure TfrmMain.DockTabSet1DockDrop(Sender: TObject; Source: TDragDockObject; X, Y: Integer);

begin

  DockTabSet1.Visible := True;

end;

5. Create an OnTabRemoved event for the DockTabSet1 component and add the following below.
The DockTabSet1 component should only be visible if there is a control docked to it.
procedure TfrmMain.DockTabSet1TabRemoved(Sender: TObject);

begin

  DockTabSet1.Visible := DockTabSet1.Tabs.Count > 0;

end;


How the created forms should look in the Structure View window

Hide image


More action shots

Hide image
Click to see full-sized image 
Application appearance on startup

Hide image
 
After clicking on the Show Forms button four times.

Hide image
 
Tab selected. Note you can click on the pin button to pin the green form to the docksite or click on the cross to close the form. To not do anything, click in the memo to change the focus away from the green form to hide it.

Hide image
 
Dragging an undocked form, note the red drag outline

Hide image
 
All windows unpinned


What about VCL.NET support?

Unfortunately there is a bug in the VCL.NET implementation of the TDockTabSet component. It is currently logged in QualityCentral and hopefully it will be addressed in the next major Delphi release.


Report No: 24640 ( RAID: 238759 ) Status: Open
TDockTabSet control doesn't work correctly in VCL.NET
http://qc.borland.com/wc/qcmain.aspx?d=24640



The bug cannot be fixed in an update as it requires an interface change to the TDockTabSet class. If you wish to fix the bug yourself you can use the following workaround:

Move the   DoAddDockClient  method from   strict private  to   protected  and   override  it.  

previously...  
  TDockTabSet = class(TTabSet)
  strict private
    procedure DoAddDockClient(Client: TControl; const ARect: TRect);
should become...
  TDockTabSet = class(TTabSet)
  protected
    procedure DoAddDockClient(Client: TControl; const ARect: TRect); override;

You also have to take the necessary steps to ensure that the modified unit is compiled into your assembly as well.  

An alternate approach might be:
  1. Create a new Delphi.NET package
  2. Save the package and name it FixedDockTabSetNET100
  3. Open the Borland.VCL.TDockTabSet unit from the sourceDotNetVCL folder
  4. Select File | Save As... and save a copy of the unit in the folder where you saved the package and rename the package to FixedDockTabSet
  5. In the FixedDockTabSet unit right click on the TDockTabSet class name and select Rename refactoring. Rename the class to TFixedDockTabSet
  6. Create a global function called Register and implement it as follows:
    procedure Register;
    begin
      RegisterComponents('Fixed DockTabSet', [TFixedDockTabSet]);
    end;
    
  7. Build the new package
  8. Install the package using the Installed .NET Components menu item from the components menu, making sure to add it to the VCL.NET components tab.
  9. If all worked well when you create a new VCL.NET Application you will get a Fixed DockTabSet palette page that has the new TDockTabSet control on it.


Closing comments

With the help of the TDockTabSet component you can now create more advanced user interfaces with dockable windows which is sure to annoy most users. With a lot more hair pulling and sleepless nights, you can use the code in this article as a basis to create your our docking framework. I've done this as part for my QualityCentral windows client I created.  
I encourage you to download and try it out from my website   www.jed-software.com.

Hide image
Click to see full-sized image

Hide image
Click to see full-sized image


While doing so, don't forget to add any issues or enhancements to QualityCentral.  
Source Download

You can download the source to this article from Code Central:
   Download Source Code
 
 
 
 
 
 
 
http://www.cnblogs.com/goldli/archive/2009/10/27/1590562.html
 
http://blog.csdn.net/xiongmao000738/article/details/6860550
 
http://blog.csdn.net/chenyq2008/article/details/8982355
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个免费程序(目前还是测试版),作者不但提供控件, 而且还无偿提供控件的所有源代码,您可以在个人或者商业程序中免费使用DockPresident 地址: http://www.pigtwo.com/CtrlData/WebSite/luxiaoban.htm 如果您下载并且使用了DockPresident,请留下您的感受和意见,也算是对作者所做工作的肯定。 下面是她的readme文件中的内容: 作为Delphi的忠实用户,我想大家对Delphi中的停靠窗体应该比较熟悉吧,是不是也希望自己编的程序也具有这样的功能? 使她看起来更漂亮,更专业,更方便。本人做的一套停靠控件DockPresident正好能满足您的要求,DockPresident包含五个控件, 她们分别是TlbDockServer, TlbDockClient, TlbDelphiDockStyle, TlbVCDockStyle, TlbVIDDockStyle。 只要在主窗口上放上TDockServer控件,在一般窗口上放上TlbDockClient控件,这两个窗体就有了停靠功能。不用编写一行代码, 效果和Delphi的IDE一样,并且比她功能更强。并且两个都放了TlbDockClient控件的窗体还可以相互停靠, 分别停靠成平铺型和分页型的窗体。用户还可以改变停靠的风格, TlbDockServer和TlbDockClient都有一个属性叫做DockStyle, 只要把TlbDelphiDockStyle, TlbVCDockStyle或者TlbVIDDockStyle控件赋值给DockStyle属性, 用户您就拥有了Delphi, Visual C++或者Visual InterDev的停靠风格。 这套控件还有很多属性供用户设置,来改变她们的停靠特性。 在当前文件夹中又有一些子文件夹,分别是: Source: 控件的源代码. SupportClass: 一个第三方控件wmEdit的DCU文件,用于Demo程序中. Help: 帮助文件,请读者务必仔细阅读,里面有控件的详细说明. Document: 文档资料,如果读者想对DockPresident有更深入的了解, 阅读里面的文章. Demo: 例子程序,用来演示DockPresident控件的使用方法和效果,里面有两个程序AdviceDemo和VCDemo. AdviceDemo程序演示了所有的DockPresident控件的用法, VCDemo主要用来演示TlbVCDockStyle的用法.由于wmEdit的原因,在VCDemo程序中有两个工程文件, 分别是VCDemoPro_D5和VCDemoPro_D6,如果用户使用的是Delphi5.0,请使用VCDemoPro_D5工程, 反之就使用VCDemoPro_D6. Bin 用来存储Source文件夹中对应文件的DCU,编译后会产生,用户可以把它删除掉. 控件安装: 如果用户使用的是Delphi5.0,请打开DockControl_D5.dpk文件安装,如果用户使用的是Delphi6.0, 请打开DockControl_D6.dpk文件安装.控件安装完成后,用户还需要配置一下Delphi, 好让Delphi能找到源文件的路经, 设置方法: 点击Tools菜单的Environment Options,弹出Environment Options对话框, 点击Library页,然后点击Library path右边的按钮, 在弹出的Directories对话框中添加上控件源文件所在的文件夹,比如:D:DockFormControlSource. 如果用户没有配置Delphi,Demo文件夹中的程序也是可以使用的,因为作者已经帮用户设置好了, 但是如果用户要自己做一个全新的程序,请按照前面的方法配置您的Delphi.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值