MFC中无边框窗口的拖动 怎么添加WM_NCLBUTTONDOWN消息映射

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC中无边框窗口的拖动 怎么添加WM_NCLBUTTONDOWN消息映射相关的知识,希望对你有一定的参考价值。

我使用按钮当做标题栏,在Lbuttondown中:

CButton::OnLButtonDown(nFlags, point);
switch(m_ButtonItem)

case MAIN_CAPTION:
::PostMessage(hWndMain,WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y)); break;
default:break;

按下后消息发送了,没有实现拖动窗口的效果,是因为没有添加消息映射吗?

实现方法原帖地址:
http://blog.sina.com.cn/s/blog_6288219501015dwa.html
方法二:当用户在窗口客户区按下鼠标左键时,使Windows认为鼠标是在标题条上,即在处理WM_LBUTTONDOWN消息的处理函数OnLButtonDown中发送一个wParam参数为HTCAPTION,lParam为当前坐标的WM_NCLBUTTONDOWN消息。
下面是使用该方法的实际代码:
void CEllipseWndDlg::OnLButtonDown(UINT nFlags, CPoint point)

// 调用父类处理函数完成基本操作
CDialog::OnLButtonDown(nFlags, point);
// 发送WM_NCLBUTTONDOWN消息
// 使Windows认为鼠标在标题条上
PostMessage(WM_NCLBUTTONDOWN,
HTCAPTION,
MAKELPARAM(point.x, point.y)); //或SendMessage(WM_SYSCOMMAND,0xF012,0); //0xF012 = SC_MOVE | HTCAPTION

2005及以上版本的话,在Dlg类上点右键,属性,看跳出的窗口,在上面的一排工具栏图标中点第4个“事件”,然后里面有各种消息,选择你要的消息,添加即可。
关于无标题栏窗口的移动的代码,确实如楼主所述的方法,一般我也是这么做的,但是如果是在按钮上点击,至少用Windows标准按钮控件是不行的,因为消息队列中的LButtonDown先被按钮拾取了,窗口收不到这条消息,从Windows消息机制里可以了解到。我试了一下,用图片自绘的任意控件都是可以用上述方法实现的,楼主可以使用自绘的图片按钮。
如果要点住这个按钮才让窗口移动,其它按钮不发生这种操作,可以用RECT来判断呀,很方便。追问

图片按钮搞定了,按钮在构造函数中添加了编号,LbuttonDown时消息发送了。
求后面的具体步骤 OTZ

追答

按照你的思路,就需要判断鼠标是不是在这个按钮上方喽,这样的话,你可以获取窗口大小,然后按照你这个按钮所在的区域来判断你的鼠标是不是落在这个区域,如果在的,就发送移动窗口的消息。
你的项目是Win32 应用程序喽?

追问

是对话框,我现在遇到的问题是发送了这个消息,但是没有实现拖动效果

追答

是MFC的基于对话框应用程序?
你创建按钮的代码是怎么样的,使用的按钮是不是Windows控件?,我觉得挺奇怪的,为什么要用按钮当标题栏,一般这类应用都是拿静态文本框和图片控件(有的甚至不用图片控件,直接整个主窗口背景的上边部分来作标题栏)以及最小化,最大化和关闭按钮。

你用SPY++看一下,你鼠标左键按下的时候的消息,然后你单步到你的Case语句那里看看是不是进入该语句。

我刚才做过测试,如果控件不是Windows标准控件,按钮的点击响应会被移动所覆盖。

追问

消息已经发出去了,我不会做消息映射。
在消息中添加的WM_NCLBUTTONDOWN添加出的函数是:
void CClientDemoDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)

我添加ON_MESSAGE(WM_NCLBUTTONDOWN, OnNcLButtonDown)编译时说函数类型不是LRESULT

追答

你用的是什么版本的VS?有没有找到我之前说的“事件”?

追问

用的是VS2008,有控件事件。
控件事件中没有Lbuttondown,我用了自定义类做图片按钮。
调试时postmessage执行了,没见到拖动效果。

追答

不好意思,刚没打开VS所以说错了,应该是消息(第5个),WM_LBUTTONDOWN

追问

我需要的是非客户区的NCLBUTTONDOWN。
PostMessage(hWndMain,WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
“要记得添加消息映射,不然这个代码是不起作用的。”
怎么添加消息映射?

追答

添加消息映射就是我刚才讲的,类视图中,Dlg类上点右键,属性,然后出来的窗口中找到“消息”,然后找到你要映射的消息,其后的下拉框中有 On****

你现在的程序是点击客户区来响应窗口移动,所以要处理WM_LBUTTONDOWN的消息,不需要处理WM_NCLBUTTONDOWN。

追问

我的对话框上面放了个picture控件做标题栏,给对话框的类添加LbuttonDown在图片控件上不会被执行。
所以我用图片按钮替换了picture,把Lbuttondown写在了按钮的类中。在按钮按下时发送WM_NCLBUTTONDOWN消息。
遇到的问题是发送消息语句已经执行了,但是对话框还是不能拖动。
不知道是不是WM_NCLBUTTONDOWN这个消息需要自己添加映射函数

追答

我在Picture控件上按住左键拖动窗口是可以的,处理的时候,你只要添加了WM_LBUTTONDOWN消息映射,然后在// TODO:下一行增加

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

就可以了呀。要么你把工程发来?我的百度账号名@163.com

参考技术A

    注意不能只处理WM_NCLBUTTONDOWN消息,还需要处理WM_NCLBUTTONUP消息,只处理一个肯定无效。

    按钮那么做没试过,感觉不是很靠谱,从对话框处理按钮的LBUTTON消息貌似有问题,第二个方法中,处理对话框客户区鼠标消息是肯定没有问题的,只要DOWN和UP都处理即可。

追问

我按照帖子里的方法判断在按钮上按下左键时发送了WM_NCLBUTTONDOWN,这个消息之后需要怎么处理?
看到有帖子说标题栏按下时是WM_NCLBUTTONDOWN,抬起时是WM_LBUTTONUP。
客户区的方法我试过确实方便,但是只在控件以外生效,我需要一个自绘的标题栏。

参考技术B 你想实现的是点击按钮然后拖动???点击按钮的时候是不响应LButtonDown这个消息。追问

使用了自定义的按钮类,添加了左键按下,调试时postmessage已经执行了,但是没有实现拖动

追答

postmessage中的句柄是主对话框的句柄么?

追问

是的,主对话框句柄的全局变量

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

技术分享
技术分享
以上窗口为无边框窗体:

在窗口属性中  去除窗口边框:
技术分享
技术分享
首先定义两个变量:
技术分享
在构造函数中进行初始化:
技术分享

因为要按下鼠标左键才能进行拖动,所以增加鼠标左键消息:
技术分享
小技巧:
技术分享
 捕获鼠标  放置鼠标跑出当前窗口:
增加移动鼠标消息:
技术分享

鼠标按下去的小时函数如下:
技术分享
增加鼠标离开弹起的消息:
技术分享
鼠标移动的消息函数实现如下:
鼠标当前位置减去鼠标开始的位置为鼠标移动的距离,为减少窗口的闪烁,让距离大于两个像素的才让他移动,因为不停的移动就会有明显的闪烁感。
GetWIndowsRect()获取窗口原来的位置。
OffSetRect()获取矩形偏移以后的新位置



技术分享

之前‘捕获了鼠标 现在要释放,这是一对 要一起使用
技术分享

处理第二个问题 当鼠标失去焦点: 要松手 鼠标弹起,禁止移动。要增加窗口激活消息:
技术分享
移动过程中鼠标变为失去焦点不激活状态
技术分享































































以上是关于MFC中无边框窗口的拖动 怎么添加WM_NCLBUTTONDOWN消息映射的主要内容,如果未能解决你的问题,请参考以下文章

VC++创建一个窗口,要窗口无边框,透明,可拖动,属性栏不显示该怎么做?

MFC 为 WS_CHILD 窗口添加细边框

MFC窗口边框问题

VC/MFC 无边框鼠标拉伸改变窗口大小

VC MFC中如何制作无边框窗口

jqgrid 在拖动列时 能不能不显示 列的边框 虚线?