oScreen(
Point(Self.ClientWidth div 3, LeftDockPanel.Height));
Source.DockRect := ARect;
end;
end;
现在再运行
程序,当你把DockableForm拖动到主窗口左边时,已经出现了预览停靠位置,也就是虚线包含的范围。
怎么?窗体又不见了?那当然了,我们只是讲了OnDockOver,还没详细讲解OnDockDrop呢,它才是决定停靠窗体在哪里出现的罪魁祸首:
OnDockDrop(Sender: TObject;
Source: TDragDockObject; X, Y: Integer);
参数和OnDockOver差不多,只是少了State: TDragState和var Accept: Boolean
它是在停靠窗体进入被停靠控件时发生的,作用是控制停靠窗体的最终位置。下面添加如下代码:
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是用来关闭的。
不过好景不长,当我们把它关闭时,装载DockableForm的LeftDockPanel不能还原,还是霸占着主窗口的客户区,怎么办?
嘻嘻,忘了告诉你们了,其实Delphi早就为我们作好了一切。
请打开DockableForm的关闭事件,你会发现原来当你点击右上角那个小X关闭DockableForm时,它会触发DockableForm的OnClose事件,在OnClose事件中把LeftDockPanel的宽度设为0就行了。
procedure TDockableForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
MainForm.LeftDockPanel.Width := 0;
Action := caHide;
end;
以上所讲的是如何在主窗口上停靠窗体,原代码都通过测试。同理,我们可以在主窗口的右边,下边,上边都实现停靠功能。
对了,刚才我们只介绍了OnDockOver和OnDockDrop,忘了介绍别的事件,下面简单介绍一下:
3.OnGetSiteInfo(Sender: TObject; DockClient: TControl;
var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);
这个事件是在窗体移动时触发的,所以经常触发,它里面的DockClient就是TDockableForm,
有一个引用参数叫CanDock,和OnDockOver中的Accept差不多,都是询问是否允许停靠。在这里可以不写,CanDock默认就是True,也可以写上CanDock := DockClient is TDockableForm;
4.OnStartDock(Sender: TObject;
var DragObject: TDragDockObject);
5.OnEndDock(Sender, Target: TObject; X, Y: Integer);
6.OnUnDock(Sender: TObject; Client: TControl;
NewTarget: TWinControl; var Allow: Boolean);
这三个事件都是在DockableForm上面有用,意思分别是停靠开始,停靠结尾,不停靠(也就是被拖出来时)。
OnStartDock和OnEndDock经常会被触发,
OnUnDock只在停靠窗体变成浮动时触发
讲了那么多,大家有没有被搞糊涂?那好,我来做一下总结:
在Delphi中只要是从TWinControl继承的控件都支持被停靠(如上面的LeftDockPanel),也就是有DockSite这个属性;所有从TControl继承的控件都支持停靠(如上面的DockableForm),也就是有DragKind这个属性.所以支持被停靠的控件都支持停靠,支持停靠的控件不一定支持被停靠,道理很简单,因为TWinControl继承于TControl。OnDockOver事件是控制停靠窗体的预览位置;OnDockDrap事件是控制停靠窗体的最终位置;OnGetSiteInfo是询问是否可以停靠;OnSta