- 0
- 0
- 约2.08万字
- 约 40页
- 2020-11-07 发布于江苏
- 举报
高级停靠(Dock)技术实现
介绍
所谓停靠就是能够用鼠标拖动窗体或控件,并将其从一个父窗体移出或移动到另一个父窗体上,能够按水平,垂直方向整齐排列, 而且能够停靠在分页控制组件上。下面示意图是一个Delphi IDE窗口停靠示意图:
考察部分常见软件如Office等大型软件,会发觉大多提供窗体停靠功效。微软MFC很早就引入了工具条拖放功效,能够将工具条上窗口上边拖放到窗口下边。而Borland则最早在Delphi 4中开始引入停靠功效支持,它实际上就是基于前面我们讲到VCL拖放技术基础之上,后面我们会看到二者有多么类似。Borland提供了停靠功效一个演示程序,能够在..\Demos\Docking目录下找到它,不过这个例子问题就是太过复杂,使用了很多高级技巧,不易了解。所以我将抛开复杂示例,一步一步揭开停靠秘密。
一个简单停靠实现
工具条停靠功效是最常见功效需求,新建一个程序,在窗体上放置一个工具条,然后任意添加多个按钮,为了让工具条能够从窗体上移出,最简单措施是设定工具条DragMode属性为dmAutomatic,将DragKind属性设定为dkDock。就像在拖放类一章我们说,DragMode设定为dmAutomatic表示当鼠标在工具条上点击并移动后,会自动提议拖放动作。而DragKind为dkDock表示接下来操作是一个停靠操作而不是一般拖放操作。
运行这个简单程序,然后拖放工具条,我们发觉确实能够将工具条拖离主窗体使其变成一个浮动工具条。注意在工具条从窗体拖离时,VCL会在屏幕上画一个矩形表示工具条,我们称其为停靠图像。见下图:
?
能够看到,VCL强大停靠支持使我们不用写一行代码就能够实现简单停靠功效了,不过上面程序存在多个问题:
1、?? 因为使用了dmAutomatic属性,哪怕是单击一下工具条不做任何拖动,全部会使它变成浮动工具条。
2、?? 拖离窗体后变成浮动工具条无法停靠回原来位置。
3、?? 浮动工具条窗口能够被关闭,而关闭后再也没措施调出工具条了。
?
对于第一个问题,为了实现工具条在鼠标点击后,必需拖放多个像素后才能被拖离界面,能够像前面拖放类章节中所讲那样,设定工具条DragMode为dmManual手工模式,然后在工具条OnMouseDown事件中使用拖放函数BeginDrag来提议拖离动作:
procedure TForm1.ToolBar1MouseDown(Sender: TObject; Button: TMouseButton;
? Shift: TShiftState; X, Y: Integer);
begin
? Toolbar1.BeginDrag(False);
end;
?
而为了让浮动工具条能够被停靠回主界面,我们需要设定窗体DockSite属性为True,表示窗体是一个停靠锚点,许可别控件停靠在它上面。
?
而当关闭浮动工具条窗口时,VCL其实并没有销毁工具条,它只是将工具条Visible属性设为False,使其不可见,为了重新显示工具条,我们能够经过一个菜单命令,将其属性设为True。下面是添加察看工具条Action代码,其中Update 事件判定工具条是否可见,假如不可见,则许可实施ActionOnExecute事件:
procedure TForm1.ActionViewToolBarUpdate(Sender: TObject);
begin
? (Sender as TAction).Enabled:=not Toolbar1.Visible;
end;
?
procedure TForm1.ActionViewToolBarExecute(Sender: TObject);
begin
? Toolbar1.Visible:=True;
end;
?再次运行修改后停靠程序,多拖放停靠几次后,我们又会发觉一个新问题,那就是即使浮动工具条能够被停靠回主界面
,不过位置不再是同界面顶部对齐,而是能够停靠在任意位置上,这显然不是我们想要效果,什么原因造成呢?怎么解
决呢?
原来,VCL在拖离任何控件后,全部会将控件Align属性修改为alNone,要想处理这个问题,就需要在工具条停靠在窗体上之后将工具条Align属性重新设定为alTop。幸好同拖放操作一样,在停靠组件时,VCL一样会产生一系列事件,其中 OnEndDock事件会在停靠完成后发生,恰好满足我们需要,实现工具条OnEndDock事件以下:
procedure TForm1.ToolBar1EndDock(Sender, Target: TObject; X, Y: Integer);
begin
? Toolbar1.Align:=alTop;
end;
?复杂界面
原创力文档

文档评论(0)