MFC用CFileDialog的派生类,打开文件时,提示ASSERT(m_dwRef <= 1)出错。使用VS2013,VS2015,VS2017都有这个问题:
用CFileDialog的派生类CDlgCustom打开文件时,会触发异常。具体在C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.16.27023\atlmfc\src\mfc\cmdtarg.cpp文件,
#include "stdafx.h"
#include "occimpl.h"
#define new DEBUG_NEW
/
// CCmdTarget construction/destruction
CCmdTarget::CCmdTarget()
{
// capture module state where object was constructed
m_pModuleState = AfxGetModuleState();
ASSERT(m_pModuleState != NULL);
// initialize state
m_dwRef = 1;
m_pOuterUnknown = NULL;
m_xInnerUnknown = 0;
m_xDispatch.m_vtbl = 0;
m_bResultExpected = TRUE;
m_xConnPtContainer.m_vtbl = 0;
}
CCmdTarget::~CCmdTarget()
{
if (m_xDispatch.m_vtbl != 0)
((COleDispatchImpl*)&m_xDispatch)->Disconnect();
ASSERT(m_dwRef <= 1);
m_pModuleState = NULL;
}
CCmdTarget::~CCmdTarget()的"ASSERT(m_dwRef <= 1);"
解决方法1:(不彻底,会有内存泄露)
对于这问题,我查了半天,从网上借鉴了一些经验,发现这是MFC的一个bug。
规避这个问题,应改为:CDlgCustom *dlg = new CDlgCustom...在堆中申请一个Dlg 对象。
把原语句:
CDlgCustom dlg(TRUE, _T(""), NULL, NULL, _T("文件(*.*)|*.*|"));
改为在堆中申请一个Dlg对象:
CDlgCustom *dlg = new CDlgCustom(TRUE, _T(""), NULL, NULL, _T("文件(*.*)|*.*|"));
问题在于如何delete dlg?否则会内存泄露
解决方法2:(推荐,亲测可行)
新增一个OnDestroy函数,把变量m_dwRef赋值为0
void CDlgCustom::OnDestroy()
{
CFileDialog::OnDestroy();
// TODO: 在此处添加消息处理程序代码
COleControlSite* pSite = GetOleControlSite(IDD_DIALOG_CUSTOM);
if (NULL != pSite)
{
pSite->ExternalDisconnect();
}
m_dwRef = 0;//这个才是重点
}
---
参考资料
AFX_MANAGE_STATE(AfxGetStaticModuleState())
https://www.cnblogs.com/lin1270/p/3498728.html