使用过Borland 系列开发工具产品(Delphi, C++Builder, Jbuilder)的朋友一定注意到Borland产品界面风格的特点,即屏弃了MDI(多文档界面),而采用分离的多窗口,特别是主窗口浮动于屏幕的最上方,当最大化时主窗口并不占满整个客户区,而是仍处在屏幕上方,使用户可以有更多的空间使用。那么如何才能实现类似于主窗口这样的效果呢?现在就在此介绍一下用Delphi实现的方法。www.goodsgy.com
要实现上面所说的主窗口的效果,必须要做到三点:1、程序启动时使主窗口位于屏幕的最上方,且宽度充满整个屏幕;2、当用户拖动停靠工具条(Dockable ToolBar/CoolBar)时,窗口能自动调整大小;3、当用户点击最大化按钮时,窗口保持在屏幕最上方,且大小保持不变。www.goodsgy.com
现在假设当前项目的主窗口(frmMain)中含有一个名为cbMain的CoolBar(一般主窗口只包含菜单和工具条)。将TfrmMain的Autosize属性设为False。www.goodsgy.com
具体步骤如下:www.goodsgy.com
1、 为主窗口添加OnCreate事件,代码如下:www.goodsgy.com
procedure TfrmMain.FormCreate(Sender: TObject);www.goodsgy.com
beginwww.goodsgy.com
Top:=0; //设定主窗口左上角到屏幕左上角www.goodsgy.com
Left:=0; //www.goodsgy.com
Width:=Screen.Width; //设定主窗口宽度为屏幕宽度www.goodsgy.com
end;www.goodsgy.com
Screen为系统预定义的类实例,对应与系统桌面,从其中可获取屏幕的一些参数。www.goodsgy.com
www.goodsgy.com
2、 在TfrmMain的定义部分添加私有成员:www.goodsgy.com
privatewww.goodsgy.com
H:integer ; www.goodsgy.com
为主窗口添加OnResize事件,代码如下:www.goodsgy.com
procedure TfrmMain.FormResize(Sender: TObject);www.goodsgy.com
beginwww.goodsgy.com
ClientHeight:=cbMain.Height; //将窗口客户区高度设为CoolBar的高度www.goodsgy.com
H:=Height; //将当前的窗口高度保存在变量H中www.goodsgy.com
end;www.goodsgy.com
www.goodsgy.com
由于窗口初始化时或点击最大化按钮时都会触发OnResize事件,因此可以保证窗口高度始终正确。www.goodsgy.com
www.goodsgy.com
3、 这是最关键的一步,我们必须改变Windows默认的最大化例程,来控制最大化后的窗口大小和位置。因此,我们重新映射响应WM_ GETMINMAXINFO的句柄。WM_GETMINMAXINFO消息在lparam中返回一个指向MINMAXINFO结构的指针,MINMAXINFO的结构如下:www.goodsgy.com
tagMINMAXINFO =record www.goodsgy.com
ptReserved : TPoint; //系统保留www.goodsgy.com
ptMaxSize : TPoint; //最大化后的大小www.goodsgy.com
ptMaxPosition : TPoint; //最大化后的位置www.goodsgy.com
ptMinTrackSize : TPoint; //窗口的最小尺寸www.goodsgy.com
ptMaxTrackSize : TPoint; //窗口的最大尺寸www.goodsgy.com
End;www.goodsgy.com
MINMAXINFO : tagMINMAXINFO;www.goodsgy.com
www.goodsgy.com
针对我们的目的,只需要ptMaxSize,ptMaxPosition两个成员就够了。Windows在最大化窗口通过调用这个结构作为参数,来取代默认的最大化参数。www.goodsgy.com
具体操作如下:www.goodsgy.com
在TfrmMain的定义部分添加私有成员定义:www.goodsgy.com
privatewww.goodsgy.com
procedure FormMaximum(var Msg:TMessage);Message WM_GETMINMAXINFO;www.goodsgy.com
以定义WM_GETMINMAXINFO的消息处理句柄。www.goodsgy.com
在Implementation部分添加实现代码:www.goodsgy.com
procedure TfrmMain.FormMaximum(var Msg:TMessage);www.goodsgy.com
varwww.goodsgy.com
lpmmi:^tagMINMAXINFO;www.goodsgy.com
beginwww.goodsgy.com
lpmmi:=Pointer(Msg.LParam); //获取指向tagMINMAXINFO的指针www.goodsgy.com
lpmmi^.ptMaxSize:=Point(Screen.width,H); //设定窗口的长宽www.goodsgy.com
lpmmi^.ptMaxPosition:=Point(0,0); //设定窗口左上角的位置www.goodsgy.com
end;www.goodsgy.com
有一点要注意:lpmmi^.ptMaxSize:=Point(Screen.width,H);一句不能写成lpmmi^.ptMaxSize:=Point(Screen.width,frmMain.Height); 这是由于Tform是VCL控件,在此消息处理句柄中不可以直接引用Tform中的成员。www.goodsgy.com
到此,大功告成了!其他一些细节,如是否允许用户改变窗口大小,是否可以拖动窗口,都可以通过简单调节而实现,就全看你的需要了。www.goodsgy.com