原文:https://blog.csdn.net/guoguojune/article/details/45332511 函数
dlg.DoModal()截住了界面消息,因此返回时原来的pMsg的内容已经更改了,消息,窗口句柄都不在是if之前的值了,spa
并且窗口句柄应该是对话框里的子窗口的句柄,因此调用CFrameWnd::PreTranslateMessage(pMsg); .net
时pMsg的窗口句柄是个无效值(窗口已销毁) 线程
很是对!code
目前我以为两种解决方式:blog
方式一:class
if (pMsg-> message == WM_CHAR) { MSG msg = *pMsg;//后来发现这样仍是有点问题,模态对话框回车后,鼠标不见了 CMyDlg dlg; dlg.DoModal(); *pMsg = msg; //后来发现这样仍是有点问题,模态对话框回车后,鼠标不见了 return TRUE;//最终方法仍是在这里直接返回吧,破坏消息循环老是很差的。 }
方式二:循环
BOOL CXXXView::PreTranslateMessage(MSG* pMsg) { if ( pMsg->message == WM_LBUTTONUP) { GetMainItemID(pMsg);//调用模态对话框函数 return TRUE; // 模态对话框后返回 TURE } }
看看别人写的缘由:方法
若是在正常的流程中弹出了模态窗口,就会使正常的PreTranslateMessage机制失效。di
由于模态窗口中已经包含了一个消息循环,接管了线程中缺省的消息循环。而这个消息循环是在DialogBox这个API函数中执行的,显然不可能再有PreTranalateMessage机制了。
为了解决这一问题,只有让模态窗口也使用和UI线程相同的消息循环,MFC正是这么作的。
在MFC中,对话框类的DoModal函数,并非调用DialogBox函数,而是直接使用CreateWindows建立一个非模态窗口,在窗口建立成功以后再调用MFC本身的消息循环,这样就可让PreTranslateMessage继续生效。同时在窗口建立出来以后,必须再作一些别的操做,使这个模态窗口的父窗口失效(通常直接把窗口Disable掉)。同时消息循环里有合适的退出条件,并有恢复现场的一些操做,具体能够查看MFC的DoModal函数。
方式三:你就不用模态对话框,用非模态对话框。