码迷,mamicode.com
首页 > Windows程序 > 详细

无标题窗体拖动(三种方法)

时间:2015-09-11 20:39:55      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

通过响应“wm_NCHitTest”消息来移动窗体。
Windows发送“wM_NCHitTest”消息来确定鼠标操作是否发生在窗体
的客户区,或边框的特殊区上(非客户区)。
如果Windows发现用户单击了窗体标题,系统将移动窗体,
单击了窗体边框,则系统将开始改变窗体大小。
例程如下:

//声明一自定义事件,拦截“WM_NCHITTEST”消息
Procedure MoveForm(var M:TWMNCHITTEST);Message WM_NCHITTEST;          

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 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;

方法三:
直接向窗体发送一条“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; XY: 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”值等方法,在此不再详细举例.

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if ssleft in shift then
     releasecapture;
perform(WM_SYSCOMMAND,$F012,0);
end; 

参考:http://www.cnblogs.com/rogee/archive/2010/09/20/1832063.html

无标题窗体拖动(三种方法)

标签:

原文地址:http://www.cnblogs.com/findumars/p/4801943.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!