思路:(1) 如果用图片做背景。可以根据图片设置窗体的形状;
(2) 再加写代码;
转自:http://blog.sina.com.cn/s/blog_495671f50100dkvz.html
为了使标题栏不显示,我们可以在窗体BorderStyle特性中选取bsNone值即可。但选取bsNone值后,窗体周围什么也没有。当我们只想去掉标题栏时又怎么办呢?
实际上窗体的位置、大小、显示风格等均由Windows API的CreateWindowEx函数所指定,这个API的参数是在Delphi的CreateParams过程中被初始化的。Delphi是依据以下的TCreateParams记录的值生成窗体的。TCreateParams记录包含窗体的位置、大小以及其他各种特性,在Delphi的 Control.Pas单元中记录的定义为:
TCreateParams = record
Caption: PChar; //标题
Style: DWORD; //窗体的显示风格
ExStyle: DWORD; //窗体的扩展显示风格
X, Y: Integer; //显示位置
Width,Height:Integer; //窗体的大小
WndParent: HWnd; //父窗体
Param: Pointer; //指向窗口生成参数(WM_CREATE消息的 //LParam)的指针
WindowClass: TWndClass; //窗体的类别
WinClassName: array[0..63] of Char; //类别名
end;
该记录中包含窗体的位置、大小和窗体显示风格的标志。因此,一般通过其值的改变来控制生成窗体的位置、大小和窗体显示风格。由于我们要设置窗体初始的风格,所以在Params.Style变量中设定窗体的风格。又因为该变量是取标志形式,所以使用and或or布尔运算来演算,从而完成各个位的on或 off。
例如,当BorderStyle特性为bsNone时,再给窗体加上可变更大小的粗框架,则对CreateParams方法进行重载。处理过程如下即可:
Procedure TForm1.CreateParams(var Params:TCreateParams);
begin
inherited CreateParams(Params);
if BorderStyle = bsNone then
with Params do Style:= Style or WS_THICKFRAME;
end;
需要注意,一般情况下的继承关系,单纯使用inherited,则派生类的方法即可被调出执行;但继承使用了CreateParams方法时,必须明确按inheritedCreateParams(Params)编制程序。
关于窗体风格标志值用以下定量来指定,这里列举的只是具有代表性的一部分。详情请参考Windows API的CreateWindow的help。
WS_BORDER边框
WS_CAPTION标题栏
WS_CHILD子窗体
WS_HSCROLL水平滚动条
WS_MAXIMIZE全屏化窗体
WS_MAXIMIZEBOX全屏按钮
WS_MINIMIIE图标化窗体
WS_MINIMIZEBOX图标化按钮
WS_SYSMENU系统菜单
WS_THICKFRAME可变更窗体大小的粗边框
WS_VISIBLE初始为可视的窗体
到此,没有标题栏的,大小可以变更的窗体已完成。
此窗体由于没有标题栏所以关闭、全屏化等按钮的操作均不可能,并且想通过拉拖标题栏移动窗体也不可能,下面我们先讨论关于移动的问题。
关于WM_NCHITTEST消息前面已经作了解说。当拖拉标题栏移动窗体时,窗体伴随鼠标器的移动,系统向窗体传送WM_NCHITTEST消息,当确认光标在标题栏上,并同时检测出鼠标器左按钮被按下时,移动成开始状态。
只要光标在窗体,则使窗体的移动成为可能。为此,WMNCHitTest处理过程如下。
porcedure TForm1.WMNCHitTest(var Msg:TWMNCHitTest);
begin inherited; //当标题栏非显示时,光标在窗体领域即可移动
if (BorderStyle = brNone) and
(Msg.Result = HTCLIENT) then
Msg.Result:= HTCAPTION;
end;
当鼠标光标在窗体领域内时,并且无标题栏,WM_NCHITTEST消息传回值为HTCLIENT时,将传回值作为HTCAPTION处理,系统则判断鼠标光标在标题栏上,这样就完成了窗体领域可移动的处理。这里再次给Windows系统一个骗局。
另外,讨论一下标题栏的消除和追加的方法。从而解决关闭、全屏化、图标化的问题。首先想到的方法是在窗体(Form)被单击或双击后,改变 BorderStyle特性的值。就是说对Form的OnClick事件进行定义,创建子程序将bsNone变为bsSizeable。
可是我们测试一下,它并不动作。实际上这是因为在前面为了处理移动,在WMNCHitTest过程中,将窗体领域的返回值变更成了标题栏的返回值,因此系统只判断鼠标光标在标题栏上单击。
要想移动和单击同时起作用需要下一点功夫。当用WinSight32来确认显示正常的窗体返回给系统的消息时,与通常窗体领域返回WM_LBUTTONDOWN消息相对,在标题上单击时返回WM_NCLBUTTONDOWN消息。
这里不使用窗体(Form)的OnClik事件,而是通过WM_NCLBUTTONDOWN消息的处理来得到希望的动作。如下编程即可 :
interface
--------------------------------------------------------------------------------
type
TForm1 = Class(TForm);
:
protected WMNCLButtonDown(var Msg:TWMNCLButtonDown);
message WM_NCLBUTTONDOWN;
implemention //鼠标单击窗体追加标题栏
porcedure TForm1.WMNCLButtonDown(var Msg:TWMNCLButtonDown);
begin
if BorderStyle = bsNone then
borderStyle = bsSizeble;
end;
当然,如果在窗体上配置其他可视构件,从而可以简单地通过对构件的单击来完成以上动作。