Window下拖拽窗体 qt实现代码

本文详细解析了WM_NCHITTEST消息的工作原理及其在窗口交互中的应用。通过重定义此消息,可以自定义窗口标题栏及边框的响应行为,实现窗口拖动等功能。
WM_NCHITTEST,该消息在MSDN上面解释如下:
它的消息响应函数会根据鼠标当前坐标来频段鼠标命中了窗口的哪个部位,函数返回值指出部位,如HTTOP, HTTOPLEFT, HTCAPTION等。看到这里就会明白,重新定义WM_NCHITTEST,让他返回当前位置为标题栏或边框的话,就可以达到我们想要的结果了。比如移动只需要将鼠标当前位置指定为HTCAPTION即可,这样看来实现更简单。

One of the mouse hit-test enumerated values listed below.

 下面列出的鼠标击中测试枚举值之一。  

· HTBORDER 在不具有可变大小边框的窗口的边框上。 

· HTBOTTOM 在窗口的水平边框的底部。 

· HTBOTTOMLEFT 在窗口边框的左下角。  

· HTBOTTOMRIGHT 在窗口边框的右下角。  

· HTCAPTION 在标题条中。  

· HTCLIENT 在客户区中。  

· HTERROR 在屏幕背景或窗口之间的分隔线上(与HTNOWHERE相同,除了Windows的DefWndProc函数产生一个系统响声以指明错误)。  

· HTGROWBOX 在尺寸框中。  

· HTHSCROLL 在水平滚动条上。  

· HTLEFT 在窗口的左边框上。  

· HTMAXBUTTON 在最大化按钮上。  

· HTMENU 在菜单区域。  

· HTMINBUTTON 在最小化按钮上。  

· HTNOWHERE 在屏幕背景或窗口之间的分隔线上。  

· HTREDUCE 在最小化按钮上。  

· HTRIGHT 在窗口的右边框上。  

· HTSIZE 在尺寸框中。(与HTGROWBOX相同)  

· HTSYSMENU 在控制菜单或子窗口的关闭按钮上。  

· HTTOP 在窗口水平边框的上方。  

· HTTOPLEFT 在窗口边框的左上角。  

· HTTOPRIGHT 在窗口边框的右上角。  

· HTTRANSPARENT 在一个被其它窗口覆盖的窗口中。  

· HTVSCROLL 在垂直滚动条中。  

· HTZOOM 在最大化按钮上。


----------------------------------------------------------------------------------
以下是代码实现方式。
</pre></div><pre name="code" class="cpp">bool QBaseWidget::winEvent ( MSG * msg, long * result )
{
int captionHeight = 20;
int frameWidth = 5;

if (msg->message != WM_NCHITTEST )
{
return QWidget::winEvent( msg, result);
}


int w = width();
int h = height();
bool bDO =false;
QPoint pos = mapFromGlobal(QCursor::pos());


if (QRect(frameWidth, captionHeight+frameWidth, w-frameWidth-frameWidth, h-captionHeight-frameWidth*2).contains(pos))
{
*result = HTCLIENT;
}
else if (QRect(frameWidth, 0, w-frameWidth*2, frameWidth).contains(pos))
{
*result = HTTOP;
bDO =true;
}
else if (QRect(0, 0, frameWidth, frameWidth).contains(pos))
{
*result = HTTOPLEFT;
bDO =true;
}
else if (QRect(w-frameWidth, 0, frameWidth, frameWidth).contains(pos))
{
*result = HTTOPRIGHT;
bDO =true;
}
else if (QRect(0, frameWidth, frameWidth+1, h-frameWidth*2).contains(pos))
{
*result = HTLEFT;
bDO =true;
}
else if (QRect(w-frameWidth-1, frameWidth, frameWidth+1, h-frameWidth*2).contains(pos))
{
*result = HTRIGHT;
bDO =true;
}
else if (QRect(frameWidth, h-frameWidth, w-frameWidth*2, frameWidth).contains(pos))
{
*result = HTBOTTOM;
bDO =true;
}
else if (QRect(0, h-frameWidth, frameWidth, frameWidth).contains(pos))
{
*result = HTBOTTOMLEFT;
bDO =true;
}
else if (QRect(w-frameWidth, h-frameWidth, frameWidth, frameWidth).contains(pos))
{
*result = HTBOTTOMRIGHT;
bDO =true;
}


if (QRect(frameWidth, frameWidth, w-frameWidth*2-100, captionHeight).contains(pos))
{
*result = HTCAPTION;
bDO =true;
}
if (!bDO)
return QWidget::winEvent( msg, result);
return bDO;
}


来自网友回复。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值