在Delphi编程中有时要对无标题窗体进行移动,以下就结合本人的经验介绍几种对无标题窗体移动的方法。
方法一:
通过响应“wm_NCHitTest”消息来移动窗体。Windows发送“wM_NCHitTest”消息来确定鼠标操作是否发生在窗体的客户区,或边框的特殊区上(非客户区)。如果Windows发现用户单击了窗体标题,系统将移动窗体,单击了窗体边框,则系统将开始改变窗体大小。
例程如下:
.
.
private
{ Private declarations }
Procedure MoveForm(var M:TWMNCHITTEST);
Message WM_NCHITTEST;
//声明一自定义事件,拦截“WM_NCHITTEST”消息
public
.
.
{$R *.DFM}
Procedure TForm1.MoveForm (var M:TWMNCHITTEST);
begin
inHerited;//继承,窗体可以继续处理以后的事件
if (M.Result=HTCLIENT) //如果发生在客户区
and ((GetKeyState(vk_CONTROL) < 0)
//检测“Ctrl”键是否按下
then M.Result:=HTCAPTION;
//更改“.Result”域的值
end;
方法二:
通过为Application.OnMessage创建一个处理程序获得Windows消息,可以调整应用程序对不同消息的响应或为不能正常识别的消息提供服务。这里受到窗体客户区的鼠标按下的消息后,发送一条在标题栏内按下的消息。
例程如下:
.
.
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure AppMessage(var Msg:TMsg;var Handled:Boolean);
.
.
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage:=AppMessage;
//捕捉消息:将程序的收到消息事件与消息过滤过程关联起来
end;
procedure TForm1.AppMessage(var Msg:TMsg;var Handled:Boolean);
begin
if (Msg.message=WM_LButtonDown) and
//如果鼠标左键按下的话
(DefWindowProc(Handle,WM_NCHitTest,
0,GetMessagePos)=HTClient) and
//判断光标是否在客户区内
((GetKeyState(vk_CONTROL) < 0)
//检测“Ctrl”键是否按下
then
begin
SendMessage(Handle,WM_NCLButtonDown,
HTCaption,GetMessagePos);
//发送鼠标在标题栏内按下的消息
Handled:=true;
end;
end;
方法三:
直接向窗体发送一条“wm_SysCommand”消息,
需要使用未归档的“sc_DragMove”标志,定义如
下:
const
sc_DragMove:LongInt=$F012;
我们只能向TWinControl派生组件发送该消息,而且只
能响应鼠标按下事件,因为系统会在此时捕获鼠标(当
释放鼠标键时,拖动操作是没有意义的)。
例程如下:
.
.
const
sc_DragMove:longint=$F012;
implementation
{$R *.DFM}
procedure TForm1.FormMouseDown
(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ssCtrl in Shift then
//判断“Ctrl”键是否按下
Begin
ReleaseCapture;
//释放鼠标事件的对象
(Sender as TWinControl).PerForm(wm_SysCommand,
sc_DragMove,0);
//发送消息
end;
end;
这种方法适用与窗体与组件,如想移动组件,将其“OnMouseDown”事件写成与Form的“OnMouseDown”事件一样即可。如只想移动窗体可按以下方法编写代码:
.
.
procedure TForm1.FormMouseDown
(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if SsCtrl in Shift then
Begin
ReleaseCapture;
SendMessage(handle,wm_SysCommand,
sc_DragMove,0);
end;
end;
运行结果:
按下“Ctrl”键拖动鼠标即可移动窗体。
总结:
要实现无标题窗体的移动有很多种方法,还可以通过检测鼠标的位置(坐标)来确定Form的“left”与“top值等方法,在此不再详细举例.
以上程序均在Delphi3.0下编译通过。