用 VC6 和 VC71 裝載的 ATL 開發軟件的人都知道, 當我們定義了一個自銷毀窗口時, 一般在 ATL 窗口類的
virtual void OnFinalMessage(HWND ){...}
函數內加一句
delete this;
然后就返回了. 但是氣人的是, 每次當我們返回后, 總有一個地方斷言失敗,
ATLASSERT(pThis->m_pCurrentMsg == &msg);
Google 了許久, 沒有滿意的解決方案, 包括微軟的方案
http://support.microsoft.com/kb/202110 也不好, 自己想盡辦法還是 "山重水復疑無路", 后來突然靈光突現, 徹底解決, 就一個函數調用而已: IsWindow(...). 現在, 終極解決方案是這樣的:
搜索 atlwin.h 文件內的 "ATLASSERT(pThis->m_pCurrentMsg == &msg);" 字符串 (在文件內有 3 處), 將其原始內容
LRESULT lRes;
BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
// restore saved value for the current message
ATLASSERT(pThis->m_pCurrentMsg == &msg);
pThis->m_pCurrentMsg = pOldMsg;
改成
LRESULT lRes;
BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
if(FALSE == ::IsWindow(pThis->m_hWnd)) {
return lRes; // 在 CDialogImplBaseT 類里是 return FALSE; 特此說明
}
// restore saved value for the current message
ATLASSERT(pThis->m_pCurrentMsg == &msg);
pThis->m_pCurrentMsg = pOldMsg;
其中紅色的代碼為我們的修正代碼. 萬事大吉. 再也不會出現斷言失敗了.
道理是這樣的: 如果 pThis 對象被刪除了的話, 那么 pThis 本身和其成員變量 m_hWnd 都將是一個無效值, 那么后續的操作將毫無意義. 因此直接返回, 不用廢話.
真是簡單的思路直指問題的核心啊.
posted on 2008-07-02 15:44
free2000fly 閱讀(2299)
評論(4) 編輯 收藏 引用