【发布时间】:2021-12-17 13:03:09
【问题描述】:
我正在更新一个旧的 MFC 应用程序,我刚刚添加了一个功能区(使用 CMFCRibbonBar 类)。
但是,当从快速访问工具栏而不是普通功能区使用命令时,功能区上快速访问工具栏中的任何导致状态更改(例如关闭文件并退出到主菜单)的命令都会导致崩溃按钮。
崩溃发生在OnMouseMove()中的MFC文件afxribbonbar.cpp中
if (pHit != m_pHighlighted)
{
PopTooltip();
if (m_pHighlighted != NULL)
{
ASSERT_VALID(m_pHighlighted);
m_pHighlighted->m_bIsHighlighted = FALSE;
m_pHighlighted->OnHighlight(FALSE);
InvalidateRect(m_pHighlighted->GetRect());
m_pHighlighted = NULL;
}
它在InvalidateRect 行崩溃,因为m_pHighlighted 似乎存在但没有数据,因此堆栈已损坏或m_pHighlighted 不再存在。
我有一些行要重新加载,其中所有帧都是用户上次处于新状态时的位置,我发现如果我在更改状态时注释掉这些行,则不会发生崩溃:
theApp.SaveState(this, ToolbarKey(i_oldAppState));
和
theApp.LoadState( this, ToolbarKey(i_newAppState) );
但理想情况下,我希望这些行,否则所有窗口和框架都会恢复到默认状态,用户必须再次调整所有内容的大小。
当我更改状态时,感觉就像快速访问工具栏中的条目正在被销毁并重新创建,但我找不到 MFC 在哪里执行此操作,或者找不到将突出显示的条目设置为 null 的方法。
编辑:由于 mfc140u.dll 中的访问读取冲突,崩溃是未处理的异常。崩溃发生在 MFC 代码的深处,与我编写的任何内容相去甚远。
这个未处理的异常发生时的调用栈是:
mfc140u.dll!CBasePane::get_accValue(tagVARIANT varChild, wchar_t * * pszValue) Line 1494 C++
mfc140u.dll!CMFCRibbonBar::OnMouseMove(unsigned int nFlags, CPoint point) Line 2348 C++
mfc140u.dll!CMFCRibbonBar::OnLButtonUp(unsigned int nFlags, CPoint point) Line 2276 C++
mfc140u.dll!CWnd::OnWndMsg(unsigned int message, unsigned __int64 wParam, __int64 lParam, __int64 * pResult) Line 2698 C++
mfc140u.dll!CWnd::WindowProc(unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 2099 C++
mfc140u.dll!CBasePane::WindowProc(unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 1020 C++
mfc140u.dll!CMFCRibbonBar::WindowProc(unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 4884 C++
mfc140u.dll!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 265 C++
mfc140u.dll!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 417 C++
mfc140u.dll!AfxWndProcBase(HWND__ * hWnd, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 299 C++
user32.dll!UserCallWinProcCheckWow() Unknown
user32.dll!DispatchMessageWorker() Unknown
user32.dll!IsDialogMessageW() Unknown
mfc140u.dll!CWnd::IsDialogMessageW(tagMSG * lpMsg) Line 194 C++
[Inline Frame] mfc140u.dll!CWnd::PreTranslateInput(tagMSG *) Line 4606 C++
mfc140u.dll!CBasePane::PreTranslateMessage(tagMSG * pMsg) Line 1057 C++
mfc140u.dll!CMFCRibbonBar::PreTranslateMessage(tagMSG * pMsg) Line 3734 C++
mfc140u.dll!CWnd::WalkPreTranslateTree(HWND__ * hWndStop, tagMSG * pMsg) Line 3379 C++
mfc140u.dll!AfxInternalPreTranslateMessage(tagMSG * pMsg) Line 233 C++
mfc140u.dll!AfxInternalPumpMessage() Line 178 C++
mfc140u.dll!CWinThread::Run() Line 629 C++
【问题讨论】:
-
你从哪里得到 m_pHighlighted?您可以在执行 LoadState 之前将其设置为 null 吗?
-
“It crashs” - 这是一个非常通用的短语,许多人将许多不同的语义归结为 “crash” 是什么。程序是否因未捕获的异常而终止?它是否响应 SEH 异常而终止。或者您看到的是 failed debug assertion dialog,它实际上并没有崩溃。
-
m_pHighlighted 指向的那个内存内容?所有字节 0xdd?旧的存储空间被删除了。