Search code examples
mfctoolbar

How to show/hide a Toolbar (the ENTIRE bar, not an individual button) dynamically in MFC?


I created an SDI app with a single menu and a single toolbar in MFC:

enter image description here

I am supposed to show/hide the toolbar dynamically via this code:

...
m_wndToolBar.ShowWindow(SW_HIDE);
...

It did visually hide the toolbar but left a blank, seemingly still working space in the dock region that blocks the main view repositioning. And, when I try to drag the menu, it can dock to the top and bottom line just like the toolbar is there.

enter image description here

I must have missed some necessary steps. So how can I "really" remove the toolbar and raise the main view close to the menu?


Solution

  • Assuming you are using a (relatively) recent version of MFC, and that your m_wndToolBar member is a CMFCToolBar (or derived therefrom), then you should use the ShowPane() member function, rather than the more general ShowWindow() member. Using the former allows the Framework to make the required adjustments to the docking system.

    From the linked document:

    Call this method instead of the CWnd::ShowWindow when showing or hiding dockable panes.

    (Note that a CMFCToolBar is derived from CPane via the CMFCBaseToolBar class.)

    In your call to ShowPane(), the first argument will be TRUE to show the toolbar or FALSE to hide it; the other two arguments will most likely be FALSE, as you want to readjust the docking layout immediately and you generally don't want to activate a toolbar.

    So:

    //...
    m_wndToolBar.ShowPane(FALSE, FALSE, FALSE); // Hide toolbar
    //...
    

    Or:

    //...
    m_wndToolBar.ShowPane(TRUE, FALSE, FALSE); // Show toolbar
    //...
    

    Note also that ShowPane() (or, rather, a version of it) is called by the Framework's default handler for a show/hide menu item with the ID of any toolbar (which toggles its visibility); from "afxframewndex.cpp":

    BOOL CFrameWndEx::OnPaneCheck(UINT nID)
    {
        ASSERT_VALID(this);
        CBasePane* pBar = GetPane(nID);
        if (pBar != NULL)
        {
            ShowPane(pBar, (pBar->GetStyle() & WS_VISIBLE) == 0, FALSE, FALSE);
            return TRUE;
        }
        return FALSE;
    }