原文: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函數。
方式三:你就不用模態對話框,用非模態對話框。