Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS General Discussion » Destroy CExtControlBar window in runtime. Collapse All
Subject Author Date
Viktor Korol Jun 8, 2006 - 4:17 AM

How to destroy docked CExtControlBar window in runtime correctly.

Viktor Korol Jun 8, 2006 - 4:29 AM

I am using this class:

CNoCloseExtControlBar : public CExtControlBar
{
public:
virtual void OnNcAreaButtonsReinitialize()
{
        ASSERT_VALID( this );
        INT nCountOfNcButtons = NcButtons_GetCount();
        if( nCountOfNcButtons > 0 )
        {
            return;
        }
    #if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
        NcButtons_Add( new CExtBarNcAreaButtonAutoHide(this) );
    #endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
        //NcButtons_Add( new CExtBarNcAreaButtonExpand(this) );
        //NcButtons_Add( new CExtBarNcAreaButtonMenu(this) );
}

    void RemoveFromAutoHideArea()
    {
        ASSERT_VALID(m_pDockBar);
        ASSERT_KINDOF(CExtDockBar, m_pDockBar);

        CExtDynAutoHideArea *pWndAutoHideArea =
            ((CExtDockBar*)m_pDockBar)->_GetAutoHideArea();

        ASSERT_VALID(pWndAutoHideArea);

        if (pWndAutoHideArea && AutoHideModeGet())
        {
            pWndAutoHideArea->RemoveControlBar( this, true );
        }
    }
};

If I call function CMainFrame::DeleteCustomControlBar() - program crashes:

void CMainFrame::DeleteCustomControlBar(CNoCloseExtControlBar *pControlBar)
{
    size_t nCustomBarsCount = m_vCustomControlBars.size();
    for (size_t i = 0; i < nCustomBarsCount; ++i)
    {
        if (m_vCustomControlBars[i] == pControlBar)
        {
            ShowControlBar(pControlBar, FALSE, FALSE);
            pControlBar->RemoveFromAutoHideArea();
            pControlBar->DestroyWindow();
            m_vCustomControlBars.erase(m_vCustomControlBars.begin() + i);
            delete pControlBar;
            return;
        }
    }    
}

Technical Support Jun 8, 2006 - 8:36 AM

First of all, we should draw your attention to the fact that removing a control bar at run time may cause problems with loading the UI state. If you change the number of bars at run-time, we recommend you use dynamic control bars. Of course, you can use the following function to kill a simple control bar:

#include "../Src/ExtDockBar.h"
#include "../Src/ExtControlBarTabbedFeatures.h"

void KillBar(
    CExtControlBar * pBar,
    bool bForceNoOptimizeMode = false
    )
{
    ASSERT_VALID( pBar );
    ASSERT_VALID( pBar->m_pDockBar );
    ASSERT_VALID( pBar->m_pDockSite );
CFrameWnd * pDockSite = pBar->m_pDockSite;
    ASSERT( pDockSite->GetSafeHwnd() != NULL );
CMiniDockFrameWnd * pMiniFrame = NULL;
    if( pBar->IsFloating() )
    {
        pMiniFrame = 
            DYNAMIC_DOWNCAST(
                CMiniDockFrameWnd,
                pBar->GetDockingFrame()
                );
        ASSERT_VALID( pMiniFrame );
    } // if( pBar->IsFloating() )
    else
    {
        ASSERT( ! pBar->m_pDockBar->m_bFloating );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
        if( pBar->AutoHideModeGet() )
        {
            ASSERT_KINDOF( CExtDockBar, pBar->m_pDockBar );
            CExtDynAutoHideArea * pWndAutoHideArea =
                ((CExtDockBar*)pBar->m_pDockBar)->_GetAutoHideArea();
            ASSERT_VALID( pWndAutoHideArea );
            CExtDynAutoHideSlider * pWndSlider =
                pWndAutoHideArea->GetAutoHideSlider();
            ASSERT_VALID( pWndSlider );
            if( (pWndSlider->GetStyle()&WS_VISIBLE) != 0 )
                pWndSlider->SendMessage( WM_CANCELMODE );
            pWndAutoHideArea->RemoveControlBar( pBar, true );
        } // if( pBar->AutoHideModeGet() )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
        if( pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockBar)) )
        {
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
            if( pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockDynTabBar)) )
            {
                CExtDynTabControlBar * pTabbedBar =
                    STATIC_DOWNCAST(
                        CExtDynTabControlBar,
                        pBar->m_pDockBar->GetParent()
                        );
                LONG nIdx = pTabbedBar->FindControlBar( pBar );
                if( nIdx >= 0 )
                {
                    LONG nSel = pTabbedBar->GetSwitcherSelection();
                    if( nIdx != nSel )
                        pTabbedBar->SetSwitcherSelection( nIdx );
                    pTabbedBar->RemoveSelFromSwitcher();
                } // if( nIdx >= 0 )
            } // if( pBar->m_pDockBar->IsKindOf(RUNTIME_CLASS(CExtDockDynTabBar)) )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
            VERIFY(
                ((CExtDockBar *)pBar->m_pDockBar)->
                    RemoveControlBar( pBar, -1, 0, false )
                );
        }
        else
        {
            VERIFY( pBar->m_pDockBar->RemoveControlBar(pBar) );
        }
    } // else from if( pBar->IsFloating() )
    pDockSite->RemoveControlBar( pBar );
    pBar->m_pDockSite = NULL;
    pBar->m_pDockBar = NULL;
    if( pMiniFrame != NULL )
        pMiniFrame->DestroyWindow();
    else
        pBar->DestroyWindow();
    if( ! bForceNoOptimizeMode )
        CExtDockBar::_OptimizeCircles( pDockSite );
}




Viktor Korol Jun 8, 2006 - 10:25 AM

If a control bar is docked and visible, then after calling KillBar() you should call AfxGetMainWnd()->SendMessage(WM_SIZE); for recalc layout, else this control bar window remains in the main frame window.

Technical Support Jun 9, 2006 - 7:36 AM

We recommend you invoke the CFrameWnd::RecalcLayout() method instead of sending the WM_SIZE messages.