2011年5月13日 星期五

CDialog m_pCtrlCont 與 Focus

這陣子都在 Windows 7 x64 的環境下開發專案…
因為發生一些狀況所以將專案 pull 一份至 Windows XP 上編譯…

環境設置好且整個方案皆編譯完成後果然解決了一些問題…
但在開啟某些 Dialog 時會發生 Crash 的狀況…
Trace 後發現是在 mfc dlgcore 中的 HandleInitDialog 使用了 NULL Point
以下即是自 dlgcore 取出的片段程式…
執行起來 m_pCtrlCont 竟然會是 NULL


LRESULT CDialog::HandleInitDialog(WPARAM, LPARAM)
{
    // Default will call the dialog proc, and thus OnInitDialog
    LRESULT bResult = Default();
#ifndef _AFX_NO_OCC_SUPPORT
    if (bResult && (m_nFlags & WF_OLECTLCONTAINER))
    {
       m_pCtrlCont->m_pSiteFocus = NULL;
       CWnd* pWndNext = GetNextDlgTabItem(NULL);
       if (pWndNext != NULL)
       {
           pWndNext->SetFocus();   // UI Activate OLE control
           bResult = FALSE;
       }
    }
#endif
}


再仔細看了一下中間的程式碼…感覺這段不做對我的流程也不會有影響…
於是想辦法不進到這個判斷式來…方法就是對上面的 bResult 做手腳…
而 bResult 會被賦予 CDialog::OnInitDialog() 的回傳值…
那在 OnInitDialog 中不 return TRUE; 沒關係嗎?

仔細看了一下 OnInitDialog 才發現有一行我一直沒注意到的註解…
// return TRUE unless you set the focus to a control
原來回傳 TRUE 是讓此 dialog 在 initDialog 後能被設置焦點…
我從前一直以為是對話框初始化成功的意思 :P


BOOL CDialog::OnInitDialog()
{
    //return TRUE;  // return TRUE unless you set the focus to a control
    return FALSE;
}


如上程式碼片段…將專案中會產生 Crash 的 CDialog::OnInitDialog return FALSE; 即可解決…
之後繼續查了一下發現微軟有證實這是個 Visual Studio 2008 的 issue
此狀況已在 Visual Studio 2010 修正嘍。

沒有留言:

張貼留言