PreTranslateMessage中有調用模態對話框的解決方法

原文: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函數。

方式三:你就不用模態對話框,用非模態對話框。

相關文章
相關標籤/搜索