您的位置:首页 > 编程语言 > Delphi

Delphi 停靠技术的应用1(在一个窗体中停靠另一个窗体)

2016-06-16 08:43 453 查看


一、基础知识介绍

1、VCL组件的基础知识

在TWinControl类中有一个DockSite属性(boolean),它的作用是是否允许别的控件停靠在它的上面;在TControl类中有一个DragKind属性,如果要这个控件能停靠在别的控件上,就把DragKind属性设成dkDock。就这么简单,只要设置一下属性,一个支持停靠的程序就完成了。当然,上面说的只是最最基本的步骤,有了以上两步,我们就可以继续编写代码实现更复杂的功能。

2、停靠操作常用的属性

  1>.TControl. TBDockHeight     // 停靠控件在停靠时的的高度;

  2>.TControl. LRDockWidth      // 停靠控件在停靠时的的宽度;

  3>.TControl. UnDockHeight     // 停靠控件在浮动时的的高度;

  4>.TControl. UnDockWidth      // 停靠控件在浮动时的的宽度;

  5>.TControl. HostDockSite     // 被停靠控件的实例;

  6>.TControl. FloatingDockSiteClass // 为停靠控件在浮动时创建容器(自动装载);

  7>.TControl. Floating       // 是否浮动

  9>.TControl. DockOrientation    // 停靠控件的方位

  10>.TWinControl .DockClientCount  // 被停靠控件里面有几个已经停靠的控件

  11>.TWinControl . DockClients   // 被停靠控件里面有已经停靠的控件的列表

  12>.TWinControl . DockManager   // 一个控制停靠的类,其实是一个ActiveX控件,和它对应的类是TDockTree.

  13>. TWinControl .UseDockManager  // 是否使用DockManager。

3、停靠操作常用的消息:

  1>.CM_DOCKCLIENT // 在DockDrop方式前发生此消息

  2>.CM_DOCKNOTIFICATION,

  3>.CM_UNDOCKCLIENT

  如果读者想对停靠技术有更深入的了解,可以看Delphi自带的例子,路径是Delphi5DemoDocking.

4、停靠时Delphi会产生的方法和事件

1>、OnDockOver:在停靠控件掠过被停靠控件时触发的。主要作用是控制停靠控件的预览位置,出现虚线包含的范围(Source.DockRect)(是被停靠控件的事件)。

OnDockOver(Sender: TObject; Source: TDragDockObject;X, Y: Integer; State: TDragState; var Accept: Boolean);

参数说明:

  Source:包含了停靠—拖动操作的信息,其中有一个重要的属性是Control,就是停靠控件,另一个重要的属性是DockRect,就是停靠的位置;

  X,Y:是鼠标的位置,

  State:的状态有dsDragEnter, dsDragLeave, dsDragMove,分别表示拖动进入,拖动离开,拖动移动;

  Accept:是是否同意停靠的意思。

2>、OnDockDrop,在停靠控件进入被停靠控件时发生的,作用是控制停靠控件的最终位置。它才是决定停靠控件在哪里出现的罪魁祸首(是被停靠控件的事件)。

OnDockDrop(Sender: TObject; Source: TDragDockObject;X, Y: Integer);

参数说明:

  和OnDockOver差不多,只是少了State: TDragState和var Accept: Boolean。

3>、OnGetSiteInfo当停靠控件移动时触发的,所以经常触发(是被停靠控件的事件)。

OnGetSiteInfo(Sender: TObject; DockClient: TControl; var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);

参数说明:

  DockClient:就是停靠控件。

CanDock:和OnDockOver中的Accept差不多,都是询问是否允许停靠。当为False时,DragOver事件不会执行。

(在这里可以不写,CanDock默认就是True,也可以写上CanDock := DockClient is TDockableForm;)

4>、OnStartDock:停靠开始时触发(是停靠控件的事件)。

OnStartDock(Sender: TObject; var DragObject: TDragDockObject);// 经常会被触发

5>、OnEndDock:停靠结尾时触发(是停靠控件的事件)。

OnEndDock(Sender, Target: TObject; X, Y: Integer);// 经常会被触发

6>、OnUnDock:不停靠(也就是被拖出来变成浮动时触发)(是停靠控件的事件)。 

OnUnDock(Sender: TObject; Client: TControl; NewTarget: TWinControl; var Allow: Boolean);//停靠窗体变成浮动时触发


二、在一个窗体中停靠另一个窗体的实例

一般的支持停靠的程序都可以在主窗口的上下左右停靠,也就是说在主窗口的边上放上能被停靠的控件比较好(只要是从TWinControl继承的都行),一般我们都选择TPanel,为了便于读者理解,我们可以假定主窗口的左边可以停靠。

1、基本步骤:

1>、在主窗口上放一个Panel,称为被停靠控件:

设置属性Name:LeftDockPanel;Align:alLeft; width:0,DockSite:True;

2>、然后再放一个TSplitter,可以调节LeftDockPanel的大小:

设置属性Name:LeftSplitter;Align:alLeft。

3>、再建一个窗体TForm,用于停靠,称为停靠控件。

设置属性: Name:DockableForm;DragKind:dkDock;DragMode:dmAutomatic(自动停靠)。

现在我们可以运行这个程序了(鼠标要进入Panel区域才能停靠)。停靠的窗体停靠进去后就不见了!这是可以使用停靠时Delphi会产生一些事件,控制它的显示情况。

2、控制它的显示,需要添加以下事件:

1>、OnDockOver:控制停靠窗体的预览位置

procedure TMainForm.LeftDockPanelDockOver(Sender: TObject;

Source: TDragDockObject; X, Y: Integer; State: TDragState;

 var Accept: Boolean);

var

 ARect: TRect;

begin

 Accept := Source.Control is TDockableForm;

 if Accept then

 begin

//修改预览停靠位置

ARect.TopLeft := LeftDockPanel.ClientToScreen(Point(0, 0));

  ARect.BottomRight := LeftDockPanel.ClientToScreen(

   Point(Self.ClientWidth div 3, LeftDockPanel.Height));

  Source.DockRect := ARect;

 end;

end;

现在再运行程序,当你把DockableForm拖动到主窗口左边时,已经出现了预览停靠位置,也就是虚线包含的范围。

2>、OnDockDrop:控制停靠窗体的最终位置

procedure TMainForm.LeftDockPanelDockDrop(Sender: TObject; Source: TDragDockObject; X, Y: Integer);

Begin

 LeftDockPanel.Width := ClientWidth div 3;

 LeftSplitter.Left := LeftDockPanel.Width + LeftSplitter.Width;

End;

现在再运行程序,出现了一个和Delphi的IDE完全一样的停靠窗体,上面是两条横线,用来把它拖出来,右上角有一个小X是用来关闭的。

3>、onClose:停靠窗体的关闭事件中控制侧边栏的关闭

点击右上角那个小X关闭DockableForm时,它会触发DockableForm的OnClose事件,在OnClose事件中把LeftDockPanel的宽度设为0就行了。

procedure TDockableForm.FormClose(Sender: TObject;

 var Action: TCloseAction);

begin

 MainForm.LeftDockPanel.Width := 0;

 Action := caHide;

end;

以上所讲的是如何在主窗口上停靠窗体,原代码都通过测试。同理,我们可以在主窗口的右边,下边,上边都实现停靠功能。


三、总结:

在Delphi中只要是从TWinControl继承的控件都支持被停靠(如上面的LeftDockPanel),也就是有DockSite这个属性;所有从TControl继承的控件都支持停靠(如上面的DockableForm),也就是有DragKind这个属性.所以支持被停靠的控件都支持停靠,支持停靠的控件不一定支持被停靠,道理很简单,因为TWinControl继承于TControl。OnDockOver事件是控制停靠窗体的预览位置;OnDockDrap事件是控制停靠窗体的最终位置;OnGetSiteInfo是询问是否可以停靠;OnStartDock是停靠开始,OnEndDock是停靠结尾,OnUnDock是不停靠(也就是被拖出来时)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: