您的位置:首页 > 其它

关于WM_NCLBUTTONUP消息

2014-06-19 10:37 260 查看
今天写代码时想要响应鼠标在标题栏释放时的消息,但是在DefWindowProc函数中却没有收到WM_NCLBUTTONUP这个消息,网上查看了一些资料,总结如下:

1、网上找到这么一段话:“当在非客户区点击鼠标左键并释放时,系统会发送窗口的WM_LBUTTONUP(注意不是WM_NCLBUTTONUP,这是客户区的鼠标释放消息,但是我们现在在非客户区释放鼠标!如之奈何)消息到线程的消息队列,但线程的消息队列压根就不把这个消息发送给这个窗口的窗口过程!”。

但是,我在测试的时候发现,鼠标左键在标题栏按下并释放后,确实没有触发WM_NCLBUTTONUP消息,但是也没有触发WM_LBUTTONUP消息。因为鼠标在标题栏按下(未释放前)移动鼠标的效果是移动程序窗口,而此时鼠标相对窗口的位置是不会改变的。也就是说鼠标一直在非客户区,因为鼠标没有在客户区释放,所以理应不触发WM_LBUTTONUP消息。

2、回到WM_NCLBUTTONUP消息上来,一般情况下,其实响应鼠标的down和up消息没有什么差别,但是某些特殊情况下还是有差别的,不能光靠响应down消息。解决该问题普遍有两种方法:一是用钩子,这个实现起来比较复杂,这里就不提了;二是重载OnSysCommand这个函数,在这个函数中当鼠标左键在标题栏释放时会产生相应地消息。

3、具体实现过程:

OnSysCommand这个函数对应的消息是WM_SYSCOMMAND,可以通过ClassWizard直接添加,也可以手动添加。需要注意的是,通过ClassWizard添加是可能找不到这个消息,在Class Info选项卡中将Message filter改成Window即可。另外,该函数的声明为:

afx_msg void OnSysCommand( UINT nID, LPARAM lParam );


消息映射为:

BEGIN_MESSAGE_MAP(CEdgeHiddenDlg, CDialog)
……
ON_WM_SYSCOMMAND()
……
END_MESSAGE_MAP()


函数实现:
void CxxxDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
CDialog::OnSysCommand(nID, lParam);  // 这句要放在前面
// TODO: Add your message handler code here and/or call default

if( (nID & 0xFFF0) == SC_MOVE )
{
PostMessage(WM_NCLBUTTONUP, HTCAPTION, lParam);   // 发送WM_NCLBUTTONUP消息
}
}


4、添加了上述函数后,程序就能收到在非客户区释放鼠标左键的消息了。其实需要相应鼠标左键释放的操作完全可以放在上述函数的if语句中,这里发送一条WM_NCLBUTTONUP消息是为了更合理而已。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: