MFC功能区:CView :: OnUpdate中的RemoveAllSubItems()导致访问冲突(VS2008)

时间:2014-05-29 15:03:19

标签: mfc ribbon mfc-feature-pack

要重现该行为,请使用功能区(CMyView作为视图类名称)启动新的MFC Outlook样式项目。

我想说我要修改CMFCRibbonButton的菜单,例如Print命令的子项,为此,我想首先RemoveAllSubItems()

在MainFrm.h中将其添加为公共成员:

CMFCRibbonButton *m_pBtnPrint;

在MainFrm.cpp中的InitializeRibbon()成员函数中添加:

CMFCRibbonButton* pBtnPrint = new CMFCRibbonButton(ID_FILE_PRINT, strTemp, 6, 6);
// store the pointer to the button to be used in CMyView class
m_pBtnPrint = pBtnPrint;   

CMyView::OnUpdate()中添加以下代码:

CMFCRibbonButton *pBtnPrint = ((CMainFrame*)AfxGetMainWnd())->m_pBtnPrint;
if (pBtnPrint) pBtnPrint->RemoveAllSubItems();  

我最好的猜测是,Print命令的框架内部复制出了问题,例如:用于快速访问工具栏。我想知道我是否在这里遗漏了一些东西。在CMainFrame中创建功能区后,是否禁止修改菜单?

编辑:这显然与m_pBtnPrint无效无关,例如在LoadFrame()之后。如果您使用CMFCRibbonBar::FindByID()动态检索pBtnPrint,它也会崩溃:

CMFCRibbonBar *pRibbon = ((CMDIFrameWndEx*) AfxGetMainWnd())->GetRibbonBar();
CMFCRibbonButton *pBtnPrint = DYNAMIC_DOWNCAST(CMFCRibbonButton, pRibbon->FindByID(ID_FILE_PRINT)); 
if (pBtnPrint) pBtnPrint->RemoveAllSubItems();  

编辑:我在Microsoft Connect网站上启动了support query,但之后没有任何有意义的回复。

1 个答案:

答案 0 :(得分:0)

CmainFrame :: LoadFrame()会覆盖您的指针。如果您上次运行并关闭此程序时保存了注册表值,则LoadFrame将序列化MFC按钮的旧状态。在此期间内存位置会发生变化,并且在Initialize期间保存的指针将无效。你必须找到一种在LoadFrame运行后抓取指针的方法。

我在所有MFCToolbars上创建了一个设置函数,只是为了在从注册表创建新按钮后获取这些自定义按钮指针。在调用CMainFrame :: LoadFrame()之后,我在CWinAppEx :: InitInstance中调用了这个Setup函数

如果您删除此程序保存的注册表值,您应该能够正常运行,但在第二次运行时它将崩溃。