打印本文 打印本文 关闭窗口 关闭窗口
Delphi中停靠技术的实现
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1806  更新时间:2009/4/23 18:42:52  文章录入:mintao  责任编辑:mintao
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] 

打印本文 打印本文 关闭窗口 关闭窗口