在查看代码时,对docksite这个属性很好奇,百度搜了很久,发现了一个很好玩的东西。关于如何制作类似工具栏的东东,可以把它拖出来作为浮动工具条。还有可以把它拖到窗体的左边,形成竖条工具条。 大体的内容如下: 在Delphi中只要是从TWinControl继承的控件都支持被停靠(如上面的LeftDockPanel),也就是有DockSite这个属性;所有从TControl继承的控件都支持停靠(如上面的DockableForm),也就是有DragKind这个属性.所以支持被停靠的控件都支持停靠,支持停靠的控件不一定支持被停靠,道理很简单,因为TWinControl继承于TControl。 基本的步骤: 在TWinControl类中有一个DockSite属性(boolean),它的作用是是否允许别的控件停靠在它的上面,在TControl类中有一个DragKind属性,如果要这个控件能停靠在别的控件上,就把DragKind属性设成dkDock。就这么简单,只要设置一下属性,一个支持停靠的程序就完成了。 假定主窗口左边可以停靠,在主窗口上放一个Align属性为alLeft的Panel(可用其他能被停靠的控件),取名为LeftDockPanel,宽度为0,DockSite属性为True。在它右边再放一个TSplitter,取名为LeftSplitter,Align属性为alLeft。建一个窗体,取名叫DockableForm,DragKind属性设成dkDock,DragMode属性设为dmAutomatic(自动停靠)。 上面操作完成之后,并不能达到想要的效果,停靠的窗体停靠进去后就不见了。这与其触发的事件有关系,分别为: OnDockOver(Sender: TObject; Source: TDragDockObject; X, Y: Integer; State: TDragState; var Accept: Boolean); OnDockDrop(Sender: TObject; Source: TDragDockObject; X, Y: Integer); OnGetSiteInfo(Sender: TObject; DockClient: TControl; var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean); OnStartDock(Sender: TObject; var DragObject: TDragDockObject); OnEndDock(Sender, Target: TObject; X, Y: Integer); OnUnDock(Sender: TObject; Client: TControl; NewTarget: TWinControl; var Allow: Boolean); OnDockOver事件是控制停靠窗体的预览位置;OnDockDrap事件是控制停靠窗体的最终位置;OnGetSiteInfo是询问是否可以停靠;OnStartDock是停靠开始,OnEndDock是停靠结尾,OnUnDock是不停靠(也就是被拖出来时)。 OnDockOver是在停靠控件(DockableForm)掠过被停靠控件(LeftDockPanel)时触发的。Source包含了停靠—拖动操作的信息,其中有一个重要的属性是Control,就是DockableForm,另一个重要的属性是DockRect,就是停靠的位置;X,Y是鼠标的位置,State的状态有dsDragEnter, dsDragLeave, dsDragMove,分别表示拖动进入,拖动离开,拖动移动;Accept是是否同意停靠的意思。OnDockOver事件主要作用是控制停靠窗体的预览位置。在该方法中添加如下代码: 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; OnDockDrop是在停靠窗体进入被停靠控件时发生的,作用是控制停靠窗体的最终位置。参数和OnDockOver差不多。在该方法中添加如下代码: begin LeftDockPanel.Width := ClientWidth div 3; LeftSplitter.Left := LeftDockPanel.Width+LeftSplitter.Width; end; 添加了以上代码之后,当我们把停靠窗体关闭时,会发现装载DockableForm的LeftDockPanel不能还原,此时,可以在DockableForm的OnClose事件中,把LeftDockPanel的宽度设为0。在OnClose事件中添加如下代码: begin MainForm.LeftDockPanel.Width := 0; Action := caHide; end; 停靠窗体设置完成。。同理可以在主窗体的其他位置都实现这个功能。 OnGetSiteInfo是在窗体移动时触发的,所以经常触发,它里面的DockClient就是TDockableForm。有一个引用参数叫CanDock,和OnDockOver中的Accept差不多,都是询问是否允许停靠。在这里可以不写,CanDock默认就是True,也可以写上CanDock := DockClient is TDockableForm; OnStartDock,OnEndDock,OnUnDock这三个事件都是在DockableForm上面有用,意思分别是停靠开始,停靠结尾,不停靠。OnStartDock和OnEndDock经常会被触发,OnUnDock只在停靠窗体变成浮动时触发。 什么时候装下Delphi验证。。\(^o^)/~
|