用 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 阅读(2271)
评论(4) 编辑 收藏 引用