dynamically switch mfc ribbon resource

Steve H 21 Reputation points
2021-04-21T21:45:27.6+00:00

The user of my MFC app needs to be able to click on a ribbon button to switch to a different ribbon UI (for example, in a different language). I have IDR_RIBBON and IDR_RIBBON1 in my project. The "switch" button has the following event handler:

void CMainFrame::OnSwitchRibbon()
{
// TODO: Add your command handler code here
m_wndRibbonBar.RemoveAllCategories();
m_wndRibbonBar.RemoveAllFromTabs();
m_wndRibbonBar.ShowPane(0, 0, 0);
VERIFY(m_wndRibbonBar.LoadFromResource(IDR_RIBBON1));
m_wndRibbonBar.ShowPane(1, 0, 0);
m_wndRibbonBar.RecalcLayout();

   RecalcLayout();
   RedrawWindow();

}

As written, it causes an Access Violation in the following MFC ribbon panel code at the RedrawElement function below:

void CMFCRibbonPanel::MouseButtonUp(CPoint point)
{
ASSERT_VALID(this);
m_bMouseIsDown = FALSE;
if (m_pHighlighted != NULL)
{
ASSERT_VALID(m_pHighlighted);
HWND hwndParent = GetParentWnd()->GetSafeHwnd();
CMFCRibbonBaseElement* pHighlighted = m_pHighlighted;
m_pHighlighted->OnLButtonUp(point);
if (::IsWindow(hwndParent) && pHighlighted->m_bIsPressed)
{
pHighlighted->m_bIsPressed = FALSE;
RedrawElement(pHighlighted); ACCESS VIOLATION

If the following 2 lines are added before the call to LoadResource(IDR_RIBBON1) in my code:

   RemovePaneFromDockManager(&m_wndRibbonBar, TRUE, TRUE, FALSE, NULL);
   VERIFY(m_wndRibbonBar.Create(this));

Then it runs without the access violation. But then I have to move all other bars in the app (like a caption bar) to get the original docking pane layout. Is there any way around this?
Finally, there is another bug in the CMFC ribbon code that causes Print Preview in the new ribbon (IDR_RIBBON1) to fail. How can that be avoided?

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,537 questions
{count} votes