实现无边框窗体的拖动及窗体大小变化

无边框窗体如何实现用鼠标拖动窗体边缘实现窗体大小变动呢?通过以下几个步骤即可实现:

1.实现WM_NCHITTEST消息,实现四条边框的模拟

2.实现WM_NCLBUTTONDOWN,发送窗体拖曳变化的消息

具体阐述如下:

1. 实现WM_NCHITTEST消息,实现四条边框的模拟,参考代码如下:

LRESULT CNoBorderWndChangeSizeDlg::OnNcHitTest(CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值  

	CRect rect;
	GetWindowRect(&rect);
	CRect rect1 = rect;
	rect1.DeflateRect(10, 10, -10, -10);
	rect1.NormalizeRect();  

	if (point.x <= rect.left+3)
	    return HTLEFT;
	else if (point.x >= rect.right-3)
	    return HTRIGHT;
	else if (point.y <= rect.top+3)
	    return HTTOP;
	else if (point.y >= rect.bottom-3)
	    return HTBOTTOM;
	else if (point.x <= rect.left+10 && point.y <= rect.top+10)
	    return HTTOPLEFT;
	else if (point.x >= rect.right-10 && point.y <= rect.top+10)
	    return HTTOPRIGHT;
	else if (point.x <= rect.left+10 && point.y >= rect.bottom-10)
	    return HTBOTTOMLEFT;
	else if (point.x >= rect.right-10 && point.y >= rect.bottom-10)
	    return HTBOTTOMRIGHT;
	else if (!rect.IsRectEmpty())
	{
	    LRESULT uRet = CWnd::OnNcHitTest(point);
	    uRet = (uRet == HTCLIENT) ? HTCAPTION : uRet;
	    return uRet;
	}
	else
	{
	    return CWnd::OnNcHitTest(point);
	} 

	return 0;
} 

2. 实现WM_NCLBUTTONDOWN,发送窗体拖曳变化的消息

void CNoBorderWndChangeSizeDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值 

    if (nHitTest == HTTOP)
    {
        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_TOP, MAKELPARAM(point.x, point.y));
    }
    else if (nHitTest == HTBOTTOM)
        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOM, MAKELPARAM(point.x, point.y));
    else if (nHitTest == HTLEFT)
        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_LEFT, MAKELPARAM(point.x, point.y));
    else if (nHitTest == HTRIGHT)
        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_RIGHT, MAKELPARAM(point.x, point.y));
    else if (nHitTest == HTTOPLEFT)
        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPLEFT, MAKELPARAM(point.x, point.y));
    else if (nHitTest == HTTOPRIGHT)
        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_TOPRIGHT, MAKELPARAM(point.x, point.y));
    else if (nHitTest == HTBOTTOMLEFT)
        SendMessage( WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMLEFT, MAKELPARAM(point.x, point.y));
    else if (nHitTest == HTBOTTOMRIGHT)
        SendMessage(WM_SYSCOMMAND, SC_SIZE | WMSZ_BOTTOMRIGHT, MAKELPARAM(point.x, point.y));
    else if (nHitTest==HTCAPTION)
        SendMessage(WM_SYSCOMMAND, SC_MOVE | 4, MAKELPARAM(point.x, point.y));
} 

通常,使用上述的代码即可实现要求。

我们进行一下扩展。在窗体大小发生变化时,有两种表现形式:一种是出现虚线框,一种没有。这个选择依赖于操作系统,你可以右击桌面/属性/外观/效果中通过选择或取消“拖动时显示窗口内容”来表现这两种形式。那么如何在程序中实现而不依赖于当前机器的设置呢(这里的意思是不依赖手动选择“拖动时显示窗口内容”项),我们可以在OnNcLButtonDown函数中通过加入如下的代码实现:

if(nHitTest == HTTOP)
{
    SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
    SendMessage(WM_SYSCOMMAND, SC_SIZE | WMSZ_TOP, MAKELPARAM(point.x, point.y));
    SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, FALSE, NULL, 0);
}

这段代码意思是在拖动上边缘动作之前,设置“拖动时显示窗口内容”,当该动作结束后,恢复原来的设置。当然,更好的做法是你首先获取机器当前的选项是什么,函数依旧是SystemParametersInfo,只是选项变化,具体查看MSDN即可。

时间: 2024-10-20 19:53:25

实现无边框窗体的拖动及窗体大小变化的相关文章

Qt:无标题栏无边框程序的拖动和改变大小

From: http://blog.csdn.net/kfbyj/article/details/9284923 最近做项目遇到的问题,总结下. 有时候我们觉得系统的标题栏和按钮太丑太呆板,想做自己的标题栏以及最大化.最小化.关闭,菜单按钮,我们就需要 [cpp] view plaincopyprint? setWindowFlags(Qt::FramelessWindowHint); 但是这样过后,我们就不能拖动窗口改变位置,以及拖动边缘改变窗口大小了. 有两种方案处理这种情况: 1.自己对m

Qt 无标题无边框程序的拖动和改变大小

2013-7-9阅读5435 评论16 最近做项目遇到的问题,总结下. 有时候我们觉得系统的标题栏和按钮太丑太呆板,想做自己的标题栏以及最大化.最小化.关闭,菜单按钮,我们就需要 setWindowFlags(Qt::FramelessWindowHint); 但是这样过后,我们就不能拖动窗口改变位置,以及拖动边缘改变窗口大小了. 有两种方案处理这种情况: 1.自己对mouseMoveEvent,mousePressEvent,mouseReleaseEvent 等事件进行处理. 2.Qt可以处

Qt无边框MainWindow如何拖动四周改变大小

原来还有winEvent(), x11Event() and macEvent() 这些东西...不过貌似还需要找更好的办法,否则就无法跨平台了. 你需要重新处理部分窗体事件,以下代码适用于Windows平台,仅供参考! bool MainWindow::winEvent(MSG *msg, long *result) { switch (msg->message) { case WM_NCHITTEST: { *result = 0; const LONG border_width = 8;

【Qt编程】无边框窗口的拖动

在上一篇文章中,我们讲述了如何进行无边框窗口的缩放与拖动,而在一些情况下,我们的窗口只需要进行拖动也不需要改变其大小,比如:QQ的登录窗口.本来在上一篇文章中已经讲述了如何进行窗口的拖动,但是却与窗口的缩放相关的程序放在一起,下面专门单独分离出来. 窗口的拖放只涉及到鼠标事件:按下操作.释放操作和移动操作,因此只需要重写这三个函数.由于程序比较简单,并且注释也比较详细,就不作过多介绍.新建一个基类为QWidget的Qt Gui应用程序,只需修改widget.h和widget.cpp文件如下: 1

C# 窗体打开拖动到窗体的文件

1 private void Form3_DragEnter(object sender, DragEventArgs e) 2 { 3 if (e.Data.GetDataPresent(DataFormats.FileDrop)) 4 { 5 e.Effect = DragDropEffects.All; 6 } 7 else 8 { 9 e.Effect = DragDropEffects.None; 10 } 11 12 } 13 14 private void Form3_DragDr

无边框窗体和后台创建控件

1.无边框窗体 最小化 最大化 关闭 按钮 不一定非要用按钮来做, 可以用图片 写事件,加上鼠标 移入移出 点击 来操作 MouseEnter-鼠标移入的时候发生的事件 private void pictureBox1_MouseEnter(object sender, EventArgs e) { pictureBox1.BackgroundImage = Image.FromFile(Application.StartupPath + "\\..\\..\\images\\btn_close

【Qt编程】无边框窗口的缩放与拖动

在现在,绝大多数软件都向着简洁,时尚发展.就拿有道的单词本和我做的单词本来说,绝大多数用户肯定喜欢我所做的单词本(就单单界面,关于颜色搭配和布局问题,大家就不要在意了). 有道的单词本: 我所做的单词本: 很明显,两者的主要区别就是周围的边框问题.你可以对比QQ以前的版本和这几年的版本,就会发现都倾向于下面这种窗口模式.下面我们就说说如何用Qt实现无边框窗口的缩放与拖动. 对于无边框窗口的拖动其实很简单,其基本思想是,在鼠标移动前后记录鼠标的坐标,然后将窗口移动这两个坐标之差的距离即可,具体实现

猎豹MFC、--拖动无边框窗体

以上窗口为无边框窗体: 在窗口属性中  去除窗口边框: 首先定义两个变量: 在构造函数中进行初始化: 因为要按下鼠标左键才能进行拖动,所以增加鼠标左键消息: 小技巧: 捕获鼠标  放置鼠标跑出当前窗口: 增加移动鼠标消息: 鼠标按下去的小时函数如下: 增加鼠标离开弹起的消息: 鼠标移动的消息函数实现如下: 鼠标当前位置减去鼠标开始的位置为鼠标移动的距离,为减少窗口的闪烁,让距离大于两个像素的才让他移动,因为不停的移动就会有明显的闪烁感. GetWIndowsRect()获取窗口原来的位置. Of

C# WinForm 拖动无边框窗体 改变无边框窗体尺寸

经常遇到这种情况.窗体的边框去掉了.然后种种问题就出来了:不能拖动.不能改变窗体大小.不能......当然.肯定有解决方案滴*^_^*今天的目标就是:可以直接拖动没有边框的窗体.可以直接拉拽窗体改变其大小.制作步骤如下:新建WinForm程序.添加一个启动的窗体.将其边框设置为None.进入代码编辑界面.定义如下常量值: const int Guying_HTLEFT = 10; const int Guying_HTRIGHT = 11; const int Guying_HTTOP = 12