当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 再谈客户区对话框拖动操作

VC++
如何有效地使用对话框
一个定制CFileDialog对话框的实例
XP风格复活节彩蛋的实现
程序界面多模式显示的实现
改变视图单调的背景
使窗体拥有透明效果的API
《电子尺》V1.02程序开发实例
美化你的应用程序的外观界面
个人考勤软件开发实例
使用VC6.0实现窗口的任意分割
如何让一个打开的文档成为活动文档
创建非矩形窗口的简单方法
轻松实现类VC界面
视图的缩放的完整论述
如何获得另一个应用程序窗口中的文本
如何发送命令到文档对象
动画窗口的实现-VC++实例一则
如何在其他程序的窗口上创建按钮并使之能响应
如何在基于对话框的程序中动态设置鼠标指针
扩展COleDropTarget类来支持任意窗口拖放 - 作者:王加宝

VC++ 中的 再谈客户区对话框拖动操作


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 105 ::
收藏到网摘: n/a

再谈客户区对话框拖动操作
——处理上下文菜单


编译/NorthTibet

下载源代码


    在线杂志第十六期有一篇文章《无标题对话框的拖动》,示范了如何用鼠标点击窗口或对话框背景(即客户区)进行拖动操作,文章中提供的解决方法在没有上下文菜单的情况下运行很正常,一旦有上下文菜单时,文中所提供的方法便显现出了缺陷——上下文菜单无法显示出来。本文将针对这个问题对前一篇提出的方法进行改进。
    当初实现拖动的基本思路是改写 OnNcHitTest 例程,让鼠标在客户区中的点击始终返回 HTCAPTION 而不是 HTCLIENT,从而诱使 Windows 实现拖动操作。没想到这样做使上下文菜单的操作出现了混乱,原因是如果强制 OnNcHitTest 在客户区返回 HTCAPTION,Windows 不会发送 WM_CONTEXTMENU 消息。有一个解决是调用 GetKeyState 函数,在返回 HTCAPTION 之前检查鼠标右键状态。这个方法要求跟踪鼠标左右键的交换操作。 也就是要自己处理虚拟键,而且如果用户是个左撇子的话,这个方法是否还灵呢?如果有兴趣,自己试试吧!除此之外,还有一个方案可以考虑,思路是当 Windows 得到 WM_NCHITTEST 消息时,鼠标按键已经释放。我查阅了 MSDN 有关鼠标消息处理的资料,利用这一间隙,可以通过改写 OnNcRButtonUp 例程对 WM_NCRBUTTONUP 消息进行处理:

// OnNcRButtonUp 函数代码void CMyDialog::OnNcRButtonUp(UINT nHitTest, CPoint pt){ if (nHitTest==HTCAPTION && PtInClientRect(pt))	SendMessage(WM_CONTEXTMENU, (WPARAM)m_hWnd, MAKELPARAM(pt.x,pt.y)); else	CDialog::OnNcRButtonUp(nHitTest, pt);} 
    从代码中不难看出,如果鼠标命中代码所反映的鼠标位置为标题栏,而实际位置是在客户区里,那么你必须自己发送 WM_CONTEXTMENU 消息。此为解决问题的关键,代码既要在 OnNcHitTest 中诱使 Windows 把 HTCLIENT 当作 HTCAPTION 处理来实现拖动,又要判断右键发出单击操作时是否处在客户区。如果是,则发送 WM_CONTEXTMENU 消息。注意当用户在标题栏上单击右键时,仍然要显示系统菜单,这时让 OnNcRButtonUp 做默认处理即可。下面是本文例子程序运行画面:


图一 例子程序运行画面

详细的处理细节请下载源代码。

最后,大家身体健康,编程愉快!