|
bsp; Message.DockSource.Control.ManualDock(Host, nil, alNone);
TDockableForm(Message.DockSource.Control).DockSite := False;
Host.Visible := True;
End;
end;
先解释一下上面的代码,首先创建TTiledHost的实例,然后用ManualDock函数把自己停靠到TTiledHost,把Message.DockSource.Control也停靠到TTiledHost,这样就完成了窗体的相互停靠,当然,要是我们要程序产生停靠的预览效果,就在DockableForm的OnDockOver事件里加入代码:
procedure TDockableForm.FormDockOver(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 := ClientToScreen(Point(0, 0));
ARect.BottomRight := ClientToScreen(
Point(ClientWidth div 2, ClientHeight));
Source.DockRect := ARect;
end;
end;
怎么样,效果还可以吧。对了,需要注意的是,用ManualDock函数可以安全的完成停靠功能,不要用Dock函数。ManualDock函数有一些参数:
function ManualDock(NewDockSite: TWinControl; DropControl: TControl = nil; ControlSide: TAlign = alNone): Boolean;
NewDockSite:要被停靠的窗体;
DropControl:已经存在于NewDockSite的TControl,在这里可以把它设成nil;
ControlSide: 停靠的位置,可以是上,下,左,右,全部等。
当然,我们也可以让TiledHost也具有和LeftDockPanel一样有被停靠的功能,只要把TiledHost看成前面的LeftDockPanel,添加一些属性和事件;把TiledHost看成DockableForm,
就可以有停靠的功能了。具体的做法这里不再阐述了,相信对VCL有深刻研究的大虾都知道怎么做了。
下面我来讲一下两个窗体怎样停靠成PageControl样式。
首先创建一个窗体,叫TabHost,在它上面放一个PageControl,Align属性设成alClient,让它占满整个TabHost,别忘了把PageControl的DockSite属性设成True.
然后我们依次加入代码:
procedure TDockableForm.FormDockOver(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 := ClientToScreen(ClientRect.TopLeft);
ARect.BottomRight := ClientToScreen(ClientRect.BottomRight);
Source.DockRect := ARect;
end;
和
procedure TDockableForm.CMDockClient(var Message: TCMDockClient);
var
Host: TForm;
begin
if Message.DockSource.Control is TDockableForm then
begin
Host := TTabHost.Create(Application);
Host.BoundsRect := Self.BoundsRect;
Self.ManualDock(TTabHost(Host).PageControl1, nil, alClient);
Message.DockSource.Control.ManualDock(TTabHost(Host).PageControl1, nil, alClient);
Host.Visible := True;
End;
End;
代码的具体意思在这里就不再解释了,同理也可以让TabHost具有停靠和被停靠的功能。还需要说明一下,TPageControl封装了一些对停靠的支持,它捕获了CM_DOCKCLIENT,
CM_DOCKNOTIFICATION,CM_UNDOCKCLIENT,WM_LBUTTONDBLCLK消息处理停靠动作。具体可以查看TPageControl的原代码。
工具条的停靠也一样,在主窗体上放一个ControlBar或CoolBar,把他们的DockSite设成True;再在上面放ToolBar, ToolBar的DragKind属性设成dkDock,DragMode属性设为dmAutomatic。在这里,TControl有一个属性叫FloatingDockSiteClass,它的类型是TWinControl的引用(class of TWinControl),只要在主窗口创建时,把ToolBar的FloatingDockSiteClass属性设成某一个窗体A,比如在设计时A这个窗体叫ToolBarDockForm,但在程序里面不用显式的创建A,Delphi会自动创建,当ToolBar被拖动出来时,Delphi自动把它装载到ToolBarDockForm里,当然ToolBarDockForm也要象上面提到的DockableForm一样设置一定的属性和添加一些代码。
讲了一大堆,还是没有把Delphi支持的停靠功能全部讲完,据我所知,还有很多。还是把它们列出来供大家参考(前面介绍的就省略了)
属性:
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。
方法:
1.TControl.ManualFloat //和ManualDock相对应,使浮动。
2.TControl.ReplaceDockedControl //替换停靠控件
3.TWinControl .DoAddDockClient
4.TWinControl .DockDrop
5.TWinControl .DockOver
6.TWinControl .DoDockOver
7.TWinControl .DoUnDock
消息:
CM_DOCKCLIENT,
CM_DOCKNOTIFICATION,
CM_UNDOCKCLIENT
如果读者想对停靠技术有更深入的了解,可以看Delphi自带的例子,路径是Delphi5\Demo\Docking.
本人是菜鸟一个,上面所讲的内容,错误再所难免,希望大虾们不要笑话。
如有疏漏,还请各位指教,谢谢。
上一页 [1] [2] 没有相关教程
|