代码改变世界

如何消除Microsoft Office Spreadsheet 11.0控件引起的断言失败对话框

  愤怒的青蛙  阅读(1005)  评论(0编辑  收藏  举报

转载自:程序人生

在一个对话框上,插入一个Microsoft Office Spreadsheet 11.0控件(Office 2003带的),再插入一个别的具有焦点的控件,比如Edit控件,运行之后,用鼠标在Microsoft Office Spreadsheet 11.0控件和Edit控件之间切换一下焦点(如果用Tab切换没问题),再关闭对话框,就出现断言失败(这时所有代码都是开发环境产生的), 调试器定位在cmdtarg.cpp中:

1
2
3
4
5
6
7
8
9
10
11
CCmdTarget::~CCmdTarget()
{
#ifndef _AFX_NO_OLE_SUPPORT
         if (m_xDispatch.m_vtbl != 0)
                ((COleDispatchImpl*)&m_xDispatch)->Disconnect();
         ASSERT(m_dwRef <= 1); //<-中断在这句
#endif
#ifdef _AFXDLL
        m_pModuleState = NULL;
#endif
}

此时m_dwRef的值,等于Microsoft Office Spreadsheet 11.0控件获得焦点(鼠标设置)的次数+1。 
使用Microsoft Office Spreadsheet 10.0控件(Office 2002带的)则没有这个问题。
应该是11.0版本的控件代码存在bug。
说明该控件作者在控件取得焦点时,++m_dwRef,而在控件失去焦点时,却没有相应的--m_dwRef。导致出现了上面所述的规律。 
release版本不会出现断言失败框,如果想在debug下关闭的烦人的断言失败框,最佳解决办法如下:
添加对话框WM_DESTROY消息处理,添加如下代码。
1
2
3
4
5
6
7
8
9
10
void CxxxDlg::-OnDestroy()
{
#ifdef _DEBUG
    int old = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
#endif
    CDialog::OnDestroy();
#ifdef _DEBUG
    _CrtSetReportMode(_CRT_ASSERT, old);
#endif
}

编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示