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 Tech Support » CExtControlBar Close Collapse All
Subject Author Date
Andrew Banks Dec 25, 2006 - 9:20 PM

The x button at the top of a CExtControlBar is used to Hide the control bar. How can I use this to close the control bar and remove if from the Frame.

Offer Har Dec 28, 2006 - 5:13 AM

Dear Support,

I have asked a while ago to make this function part of the library, as it have demand.
Also, i think that you should do a sample, and test this feature, as this function and it’s usage cause bugs elsewhere.

Regards,
Ron.

Technical Support Dec 26, 2006 - 1:29 PM

If you are using CExtControlBar control bars, you should override the OnNcAreaButtonsReinitialize() virtual method. You can make it the same as the original method except for instantiating your own CExtBarNcAreaButtonClose-derived object which implements the "X"-button in the bar’s caption. In this Close button class, implement the CExtBarNcAreaButton::OnNcAreaClicked() virtual method which is invoked when the caption button is clicked. Your version of this method should invoke the following function to remove the 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 );
}
Please note that if you remove simple control bars (the CExtControlBar objects), there may be problems with saving/restoring the state of control bars to/from the registry. So for simple control bars, just to hide them would be a better solution.

The dynamic control bars (the CExtDynamicControlBar objects) controlled by the dynamic bar site (the CExtDynamicBarSite object) can be safely removed and allocated any time and the CExtDynamicBarSite object restores the recent number of dynamic control bars using runtime type information of each dynamic bar for restoring exactly the same object. You can use the above described approach for dynamic control bar, but you should code your own CExtDynamicControlBar-derived and CExtDynamicBarNcAreaClose-derived classes. The close button class in this case should invoke the CExtDynamicBarSite::BarFree() method to de-allocate the control bar. Dynamic control bars are demonstrated in the SDI_DynamicBars and MDI_DynamicBars samples. These bars have additional features like switching into document mode and more. These bars can be mixed with the simple control bars in scope of one frame window.

Andrew Banks Dec 28, 2006 - 12:04 AM

The above code works thanks. However,

    int sz = pMiniFrame->m_wndDockBar.m_arrBars.GetSize() ;
    for (int i = 0; i < sz; i++)
            pMiniFrame->m_wndDockBar.m_arrBars[i] = NULL;

Needs to be added before Destroy Window. The destruction code eventually reaches CDockBar::~CDockBar() in MFC on the variable CMiniDockFrameWnd::m_wndDockBar. The array m_wndDockBar.m_arrBars becomes invalid prior to CDockBar destruction and so occasional asserts occur in the destruction code of CDockBar. The alternative is to use CMiniDockFrameWnd::m_wndDockBar.RemoveControlBar and not directly call DestroyWindow on the CMiniDockFrameWnd as CDockBar::RemoveControlBar() does that for you once all control bars are removed.

Technical Support Dec 28, 2006 - 1:43 PM

We cannot confirm that this improvement is required. Please do a search for the KillBar() function in Prof-UIS forums. It is based on the code used for removing dynamic control bars. Nobody reported any problems about this. We guess there must be some conditions in your application when some modification should be made to the dock bar’s array of control bars.