• 解决MFC中因控件类多次Attch造成的销毁窗口过程中CWnd* pWnd = CWnd::FromHandlePermanent(hWnd); ASSERT(pWnd != NULL); 断言失败的问题


    问题描述:

    最近正在做一个MFC框架窗口(CFramwWnd)程序,该窗体程序是以对话框项目为框架,在此基础上创建框架窗口(CFramwWnd),框架窗口(CFramwWnd)中没有CDocument及CView,其中增加了分隔条CSplitterWnd类成员,在框架窗口销毁函数中,做了分离m_wndSpltter.Detach();然后在C:Program Files (x86)Microsoft Visual Studio2017EnterpriseVCToolsMSVC14.16.27023atlmfcsrcmfcwincore.cpp文件中的:

    1 CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
    2 ASSERT(pWnd != NULL);

    断言失败的问题。

    寻找原因:

    因为一开始并不知道是因m_wndSpltter.Detach();报错,

    参考了:

    深入解析Windows窗口创建和消息分发

    https://www.cnblogs.com/findumars/p/6329614.html

    之后,有了更清晰的认识。因为之前调试时会经常进入MFC源代码,基本的消息泵框架这块还有一定概念的。

    先得找到报错的窗口句柄到底是属于哪个控件的。

    (注:窗口中的控件都继承于CWnd类)

    解决方法:

    1..F5调试,弹出报错后,点击重试,得到了报错的句柄,在spy++中查询该句柄。

    2.打开spy++,查找本程序窗品,可定位到该窗口句柄。

    3.可是CSplitterWnd窗口类成员的显示的是:AfxMDIFramw140sud。

    4.此时怀疑是CSplitterWnd,再次重复步聚1、2在报错代码处插入断点,在CMyFrame::OnClose()处添加处成员的HWND值。这果也可以编辑断点条件:

    (0x00580D40 == hWnd || hWnd == 0x002F1140 || hWnd == 0x00B81060) && nMsg == 0x2

    依次是主窗口句柄、CSplitterWnd、句柄、以CSplitterWnd的子窗口句柄,0x2为WM_DESTROY消息。

    5.报错后的句柄,对比CSplitterWnd句柄,就是它了。

    6.找到始作俑者后,再次调试时,跟进去CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);代码,在LookupPermanent()中返回NULL。很明显m_permanentMap中没了这个句柄。

    7.再看Detach()做了什么,RemoveHandle,一切原因找到了,我在OnClose()处,多于的做了一次Detach(),导到在销毁窗口时,寻找该窗口句柄时返回NULL。

    8.全部移除其它的Detach,程序正常运行。

  • 相关阅读:
    vue 路由跳转传参
    vue better-scroll 下拉上拉,加载刷新
    H5点击拨打电话,发短信
    vue搭建项目
    How to determine the socket connection up time on Linux
    @ContextConfiguration注解
    MySQL修改主键属性
    软件测试工程师面试(一)
    Python实现不同格式打印九九乘法表
    MySQL 5.1安装和配置过程中遇到的问题
  • 原文地址:https://www.cnblogs.com/freemindblog/p/15414838.html
Copyright © 2020-2023  润新知