使用Delphi自带的TDockTabSet组件实现停靠功能(Jeremy North)

源地址:http://edn.embarcadero.com/article/33446

摘要: 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

  1. TPanel
AlignalLeft
BevelOuterbvNone
DockSiteTrue
NamepDockLeft
Width0

  1. TSplitter
AlignalLeft

  1. TMemo
AlignClient

  1. Drop a TButton on the top aligned Panel and set its caption to Show Form
  2. Set the Forms caption to TDockTabSetDemo Application
  3. 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.

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);beginManualFloat(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

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);vari: Integer;begin// close all previously dockable forms before recreatingfor i := 0 to Screen.FormCount - 1 doif Screen.Forms[i] is TfrmDock thenScreen.Forms[i].Close;// dock to the component called pDockLeftTfrmDock.CreateDockForm(clBlue).ManualDock(pDockLeft);// dock to the top on the pDockLeft panelTfrmDock.CreateDockForm(clGreen).ManualDock(pDockLeft, nil, alTop);// dock to the right on the pDockLeft panelTfrmDock.CreateDockForm(clRed).ManualDock(pDockLeft, nil, alRight);// dock directly to the DockTabSetTfrmDock.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);
beginif pDockLeft.Width = 0 thenpDockLeft.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);
beginif pDockLeft.DockClientCount = 1 thenbeginpDockLeft.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);
varlRect: TRect;
beginAccept := Source.Control is TfrmDock;if Accept thenbeginlRect.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);
beginDockTabSet1.Visible := DockTabSet1.Tabs.Count > 0;
end;
How the created forms should look in the Structure View window

More action shots


Application appearance on startup

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.


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;
Build the new package 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. 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


转载于:https://www.cnblogs.com/DxSoft/archive/2010/12/15/1906408.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/475794.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安装linux出现基础系统出错,Linux系统出错提示信息详解

ERROR PCI: cannot allocate(无法指派)这样的错误有许多,他们主要在启动系统时出现。他们有一个共同的起因:错误的电源管理行为。罪魁祸首是一个叫做ACPI的东西,即高级配置与电源接口。尽管他是一种电源管理标准,但在十几年的时间…

c语言基本数据类型常量,C语言基础学习基本数据类型-变量和常量

变量和常量什么是变量和常量?有些数据在程序运行前就预先设定,并在运行过程中不发生变化,称之为常量;有些数据在程序运行中可能发生变化或被赋值,称之为变量。使用变量前必须先声明一个变量。变量定义的语法是&#xf…

2011年影响3G手机发展四大因素

今晨闻讯,中电信明年3季度将推出iPhone。据称CDMA版本的iPhone推出,对中国电信意义重大,售价会高于WCDMA版。联通、移动、电信争夺“苹果血案”将继续上演。 截止2010年12月31日,中国3G用户不超过5000万。而工信部落实3G发展规划是…

Feature Engineering 特征工程 1. Baseline Model

文章目录1. 读取数据2. 处理label3. 添加特征4. 数据集切片5. 训练6. 预测learn from https://www.kaggle.com/learn/feature-engineering下一篇:Feature Engineering 特征工程 2. Categorical Encodings 1. 读取数据 预测任务:用户是否会下载APP&…

[转载] 湖北:星空团队——海燕计划

2010-7-1 来源:网易科技报道 本文网址:http://tech.163.com/10/0701/16/6AH5MA4S00094II8.html 1.项目及团队名称:星空团队——海燕计划 2.所在的赛区、所在的城市、所属高校:湖北赛区、武汉、华中科技大学 3.所处的公益领域&…

c语言静态存储和动态存储,为了便于计算机存储管理,C语言把保存所有变量的数据区,分成动态存储区和静态存储区,静态局部变量被存放在动态存储区。...

在向旅游者致欢迎词时,便于保存变量部变地陪的态度要热情,感情要真挚,内容要依情而异,语言要( )计算机存据区静山西省总的地势是()。储管成动储区储区存放储区提出到2020年要将我国旅游业建设成国民经济的战略性支柱产业和人民群众…

Feature Engineering 特征工程 3. Feature Generation

文章目录1. 组合特征2. 过去7天的数据3. 上一个相同类型的项目的时间4. 转换数值特征learn from https://www.kaggle.com/learn/feature-engineering上一篇:Feature Engineering 特征工程 2. Categorical Encodings 下一篇:Feature Engineering 特征工程…

C# 转繁体转简体转拼音,超级文本大转换

最近项目中遇到一个需求:把员工的中文姓名根据系统配置转换成中文简体或中文繁体。 原以为需要一个很大的一个简体和繁体相对应的字符对应表之类的东西。 后来发现,VB中就包含了这样的函数Strings.StrConv(this.TextBox1.Text.Trim(), VbStrConv.Traditi…

Feature Engineering 特征工程 4. Feature Selection

文章目录1. Univariate Feature Selection 单变量特征选择2. L1 regularization L1正则learn from https://www.kaggle.com/learn/feature-engineering上一篇:Feature Engineering 特征工程 3. Feature Generation 经过各种编码和特征生成后,通常会拥有…

分销平台使用手册

分销平台使用手册 分销商和供应商流程图 基本资料维护 1、分销联系人资料:包括:联系人;联系固话(手机号码);email;阿里旺旺(建议用已认证过的账号或商城店铺的阿里旺旺子账号&#x…

LeetCode 474. 一和零(01背包动态规划)

1. 题目 在计算机界中,我们总是追求用有限的资源获取最大的收益。 现在,假设你分别支配着 m 个 0 和 n 个 1。另外,还有一个仅包含 0 和 1 字符串的数组。 你的任务是使用给定的 m 个 0 和 n 个 1 ,找到能拼出存在于数组中的字…

android es管理工具,Android

Android ES文件管理器在文件管理器中,ES文件管理器的名气是比较大的,这款文件管理器也在近日进行了更新,更新后的ES文件管理器支持了更多网络存储空间,可以直接访问百度网盘、快盘、酷盘、微盘、box、sugarsync、dropbox和skydriv…

深入浅出InfoPath——让管理员来部署InfoPath表单

应用场景: 我们(乙方)在给客户提供基于InfoPath表单(尤其是包含托管代码的)的工作流解决方案的时候,常常需要客户(甲方)的SharePoint管理员来帮忙在安装SharePoint Server的服务器上…

LeetCode 932. 漂亮数组(分治递归/循环)

文章目录1. 题目2. 解题2.1 分治递归2.2 循环1. 题目 对于某些固定的 N&#xff0c;如果数组 A 是整数 1, 2, …, N 组成的排列&#xff0c;使得&#xff1a; 对于每个 i < j&#xff0c;都不存在 k 满足 i < k < j 使得 A[k] * 2 A[i] A[j]。 那么数组 A 是漂亮…

android 修改系统参数设置,2021-05-15 [RK3399][Android7.1] 调试笔记 ---显示参数动态设置接口...

系统环境&#xff1a;Platform: RK3399OS: Android 7.1Kernel: v4.4.83接口代码所在位置为&#xff1a;/frameworks/base/core/java/android/os/DisplayOutputManager.java如图&#xff1a;image.png1. 设置背光亮度public void setBrightness(int display, int brightness)设置…

Lucene.Net:关于索引的一些补充说明和总结

在前面的几篇关于lucene的文章中&#xff0c;我已经简要说明了如何利用lucene进行分词、索引和搜索。最近大部分时间耗在查资料上&#xff0c;看得比较多比较杂但是一贯的不够深入&#xff0c;还好多数都是不会影响编程实践的概念性的东西。有时候我自己也感觉到有心无力&#…

在2008 server安装vm server时发生的错误error1718、error1335……

;转载于:https://www.cnblogs.com/minglog/archive/2011/02/15/1955290.html

hibernate3.6.0日志配置

hibernate3 自带的默认的日志框架是slf4j&#xff0c;hibernate3的slf只是一个日志的接口&#xff0c;而hibernate3 自带默认的日志框架&#xff0c;在实际开发中很少有公司或者是项目中用到&#xff0c;这里记录一种使用log4j的日志框架来代替slf4j日志框架的实现&#xff0c;…

android stackview,Android StackView 使用示例

cell.xml 布局文件&#xff1a;xmlns:android"http://schemas.android.com/apk/res/android"android:id"id/cellImage"android:layout_width"200dp"android:layout_height"200dp"/>主布局文件&#xff1a;android:id"id/activ…

WCF 体系结构图

转载于:https://www.cnblogs.com/agressivo/articles/1958858.html