CMFCToolbar ReplaceButton() causes button to disappear

1.6k views Asked by At

Using Visual Studio 2010 and working with an MFC SDI Application. I have a CMFCToolbar object owned by the Main Frame.

When the document in this application is created, the MainFrame calls a function to replace one of the buttons in the CMFCToolbar object with a CMFCToolbarMenuButton. The contents of the menu button are populated with information from the document. The menu creation always works. The call to ReplaceButton always succeeds. But there's a visual symptom of the call that I haven't yet figured out.

Any time ReplaceButton is called, the button disappears. Not only is it not drawn, it's not clickable. It's temporarily gone. I assume this is because there's a dangling reference to the old button, which I have just destroyed with the call to ReplaceButton.

I've tried calling Invalidate(), RecalcLayout() to trigger a re-draw, but neither has worked yet. The only reliable method I have for getting the button to show up is re-sizing the application window manually or by un-docking/re-docking the toolbar. I assume there's some kind of lower-level refresh that occurs in these situations, but I don't know how to trigger it manually.

Is there a way to make sure my button is drawn immediately?

Edit: code sample

Count = m_Doc->...->GetCount();
for (Index = 0; Index < Count; ++Index)
{
    Caption.Format(L"%s", m_Doc->...->GetName());
        m_pLayerMenu->AppendMenu(MF_ENABLED | MF_STRING, LAYER_DROP_SEED+Index, Caption.GetData());
}
m_wndBrushBar.ReplaceButton(ID_BRUSH_TERRAIN,
    CMFCToolBarMenuButton(ID_BRUSH_TERRAIN, *m_pLayerMenu, GetCmdMgr()->GetCmdImage(ID_BRUSH_TERRAIN)));

Update:

Calling m_wndBrushBar.AdjustLayout() seems to stabilize the visual behavior of these CMFCToolbar buttons. So that's a partial solution. Partial because of the following:

It's hard to tell what the real visual behavior is. It turns out that all visual settings/states are stored in the Registry with these MFC objects, and it can hold onto states of dynamically created objects that really alter the startup behavior of the app.

I've gone in to delete the registry values under

Current User -> "Local App-Wizard Generated Applications" -> [My App Name]. Done this a number of times, just to find out what the real behavior of my app is. Feel like I'm missing some fundamental knowledge with the current version of MFC. Lots of bugs arising from the registry deal.

Is there a way to prevent registry settings for certain objects, or to shut off this behavior altogether? Otherwise, I guess my shutdown process will have to be a LOT more thorough with resetting all the visual elements. Registry values seem to ignore, override, or bypass my startup code. I can code how I want an object to look at startup, but if there are values in the registry, it does no good.

1

There are 1 answers

0
rrirower On

You've discovered a sometimes annoying aspect for the CMFC code. That is, the concept of a Workspace. The Workspace manages the concept of the application state. I, too, have had problems like the one you describe. But, you have the flexibility to manage how those objects are recreated by overriding the LoadState () and SaveState () methods.