VC 实现无标题窗口的拖拽

VC实现无标题窗口拖拽
本文介绍如何通过响应WM_NCHITTEST消息并修改其返回值为HTCAPTION,或者在OnLButtonDown中发送伪造的WM_NCLBUTTONDOWN消息,来实现VC中无标题窗口的拖拽功能。

VC 实现无标题窗口的拖拽

  

到底我们怎样来欺骗Windows呢?

我们主动来响应WM_NCHITTEST消息。//NC == noneclient 非客户区

用ClassWizard添加WM_NCHITTEST的消息响应函数。

注:用ClassWizard添加消息响应函数时候,在右下角的“Filter for message available to”选择“Windows”。否则你找不到WM_NCHITTEST消息。

编写代码如下:

UINT CTestDlg::OnNcHitTest(CPoint point) 

{

    //得到鼠标点击的窗口的部位

    UINT nHitTest = CDialog::OnNcHitTest(point);

 

    // 如果鼠标点击的是客户区,则返回HTCAPTIONWindows

    if (nHitTest == HTCLIENT)

    {

       return HTCAPTION; //HT==hit 点击 ,HTCAPTION== hit caption 点击标题栏

    }

    else

       return nHitTest;

}

Windows会根据紧接着发送的WM_NCLBUTTONDOWN消息的wParam的内容来决定是否启用“拖拽状态”。实际上,就是根据OnNcHitTest的返回值来确定是否启用。如果返回值是HTCAPTION,就启用。我们正是利用这个特性来欺骗了Windows。

你可能觉得这样处理会有问题,因为我们虽然欺骗了Windows,但鼠标确实不在标题栏上。试想鼠标拖动的时候,Windows必须使窗口和鼠标同步移动。此刻Windows误以为我们的鼠标就在标题栏上,要实现“同步移动”,Windows会一下子把标题栏移动到鼠标当前位置。

你的担心是多余的,Windows移动窗口的时候是根据鼠标位置的改变量来改变窗口坐标的。它不是以鼠标的实际坐标来直接确定窗口坐标的。

 

另外一个更简单的处理方法是,是在OnLButtonDown中加上一句话。如下:

void CTsDlg::OnLButtonDown(UINT nFlags, CPoint point) 

{

    SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));

 

    CDialog::OnLButtonDown(nFlags, point);

}

上面已经说过,Windows先向窗口发送WM_NCHITTEST消息以确定鼠标点击的部位,如果点击的是非客户区,则又会发送WM_NCLBUTTONDOWN消息。我们现在伪造了一条WM_NCLBUTTONDOWN消息来欺骗Windows,这样更加直接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值