MFC中非模态对话框不响应PreTranslateMessage函数的解决方法
2015-10-26 22:37
459 查看
程序员真心不容易啊,为了一个好的用户体验真可谓是操碎了心。今天由于项目需要,需要在非模态对话框上,当鼠标处于某个位置的时候有提示框显示。实现这个功能本来很简单,但是却遇到了一个郁闷的问题:PreTranslateMessage函数没响应。于是各种度娘,可惜度娘非谷歌,找了一个小时终于在一个隐蔽的地方找到了解决方法。
首先我介绍下当鼠标处于特定位置的时候有提示信息显示的实现方法。
需要使用MFC的CToolTipCtrl控件。
1.首先在Dialog类中添加一个成员对象
2.在OnInitDialog()函数中创建消息提示框
3.捕获鼠标的移动消息OnMouseMove,当鼠标处在某一特定区域的时候,弹出消息提示框。切换消息内容使用CToolTipCtrl::UpdateTipText函数。
4.重写基类的PreTranslateMessage函数
好了,做到这四部就基本完成了。当自己满怀信息一运行发现根本没有弹出提示信息。经过调试发现,PreTranslateMessage函数并没有被调用,于是引出了重要的主题,非模态对话框如何响应PreTranslateMessage函数的问题。经过一番百度,终于找到了解决方法。
在MFC的App类中需要用Hook来勾取消息,需要注意的是GetMessageProc是个回调函数,所以我们需要将它设成类的静态成员函数。
即:
此时才算是打工告成,信息弹出框如愿以偿的弹出了。
首先我介绍下当鼠标处于特定位置的时候有提示信息显示的实现方法。
需要使用MFC的CToolTipCtrl控件。
1.首先在Dialog类中添加一个成员对象
//消息提示框 CToolTipCtrl m_toolTip;</span></span>
2.在OnInitDialog()函数中创建消息提示框
//创建消息提示框 EnableToolTips(TRUE);//enable use it BOOL bRet = m_toolTip.Create(this, TTS_ALWAYSTIP | WS_CHILD | WS_VISIBLE); m_toolTip.AddTool(this); m_toolTip.Activate(TRUE); m_toolTip.SetDelayTime(150);</span></span>
3.捕获鼠标的移动消息OnMouseMove,当鼠标处在某一特定区域的时候,弹出消息提示框。切换消息内容使用CToolTipCtrl::UpdateTipText函数。
void CDisplayPicDlg::OnMouseMove(UINT nFlags, CPoint point) { //如果鼠标在矩形所在区域,需要把箭头鼠标变成手型的 int iSel = GetSelectCameraNo(point); if(-1 != iSel) { SetCursor(LoadCursor(NULL, IDC_HAND)); m_toolTip.UpdateTipText(m_stMonitorCamera[iSel].szCamereName, this); } else//还原成箭头鼠标形式 { SetCursor(LoadCursor(NULL, IDC_ARROW)); m_toolTip.UpdateTipText("", this); } if(-1 != m_lCameraIdPre) { SetCursor(LoadCursor(NULL, IDC_ARROW) ); } //..................... }
4.重写基类的PreTranslateMessage函数
BOOL CDisplayPicDlg::PreTranslateMessage(MSG* pMsg) { m_toolTip.RelayEvent(pMsg); return CDialog::PreTranslateMessage(pMsg); } <span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>
好了,做到这四部就基本完成了。当自己满怀信息一运行发现根本没有弹出提示信息。经过调试发现,PreTranslateMessage函数并没有被调用,于是引出了重要的主题,非模态对话框如何响应PreTranslateMessage函数的问题。经过一番百度,终于找到了解决方法。
在MFC的App类中需要用Hook来勾取消息,需要注意的是GetMessageProc是个回调函数,所以我们需要将它设成类的静态成员函数。
即:
class CStaticMapGPSApp : public COleControlModule { public: BOOL InitInstance(); int ExitInstance(); static LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam); HHOOK m_hHook; protected: };
LRESULT CALLBACK CStaticMapGPSApp::GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); LPMSG lpMsg = (LPMSG) lParam; if(AfxGetApp()->PreTranslateMessage(lpMsg)) { lpMsg->message = WM_NULL; lpMsg->lParam = 0L; lpMsg->wParam = 0; } // Passes the hook information to the next hook procedure in // the current hook chain. return ::CallNextHookEx(theApp.m_hHook, nCode, wParam, lParam); } // CStaticMapGPSApp::InitInstance - DLL initialization BOOL CStaticMapGPSApp::InitInstance() { BOOL bInit = COleControlModule::InitInstance(); if (bInit) { // TODO: Add your own module initialization code here. m_hHook = ::SetWindowsHookEx( WH_GETMESSAGE, GetMessageProc, AfxGetInstanceHandle(), GetCurrentThreadId()); ASSERT (hHook); return CWinApp::InitInstance(); } return bInit; } // CStaticMapGPSApp::ExitInstance - DLL termination int CStaticMapGPSApp::ExitInstance() { // TODO: Add your own module termination code here. UnhookWindowsHookEx((HHOOK)m_hHook); return COleControlModule::ExitInstance(); }
此时才算是打工告成,信息弹出框如愿以偿的弹出了。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- MooBox 基于Mootools的对话框插件
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C#实现在前端网页弹出警告对话框(alert)的方法
- C++联合体转换成C#结构的实现方法
- Android开发必知 九种对话框的实现方法
- Android列表对话框用法实例分析
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例