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 » CExtDynTabControlBar and close button Collapse All
Subject Author Date
Chris Fudge May 6, 2005 - 6:50 AM

With my dynamic ControlBars some, have the close button enabled and some do not. This is working fine - I understand that I now need to also implement this in a CExtDynTabControlBar derived class.

How do I display a close button depending on the currently selected tab in a CExtDynTabControlBar ?

I think all I need is to retrieve the currently selected Tab then do something like the following :

void CXPTabPanel::OnNcAreaButtonsReinitialize()
{
    INT nItemCount = CExtDynTabControlBar::GetSwitcherItemCount();
    if(nItemCount)
    {
        CXPPanel * pPanel = (CXPPanel*)GetBarAt(CURRENTLY_SELECTED_TAB,true);
        if(pPanel)
        {
            if(pPanel->HasCloseButton()) NcButtons_Add( m_pCloseButton );
        }
    }


    NcButtons_Add( new CExtBarNcAreaButtonMenu(this) );
}

This would work if I could somehow find the index for CURRENTLY_SELECTED_TAB.

Technical Support May 7, 2005 - 10:32 AM

The CExtDynTabControlBar::GetSwitcherItemCount() method returns the number of tab items in the dynamic tabbed bar container, CExtDynTabControlBar::GetSwitcherSelection() returns a zero-based index of the selected tab item, and CExtDynTabControlBar::GetBarAt() returns a pointer to the CExtControlBar window for the specified tab index.

Chris Fudge May 8, 2005 - 4:47 PM

Thanks - ive got the close buttons appearing as desired using:

void CXPTabPanel::OnNcAreaButtonsReinitialize()//OnNcAreaButtonsReinitialize()
{
    INT nCountOfNcButtons = NcButtons_GetCount();

    INT nItemCount = CExtDynTabControlBar::GetSwitcherItemCount();
    LONG nSelection = CExtDynTabControlBar::GetSwitcherSelection();
    if(nItemCount && (nSelection != -1))
    {
        CXPPanel * pPanel = (CXPPanel*)GetBarAt(nSelection,true);
        if(pPanel)
        {
            if(pPanel->HasCloseButton())
            {
                if( nCountOfNcButtons == 0 )
                {
                    m_pCloseButton = new CXPPanelCloseButton(this,m_pFrame,pPanel->GetID());
                    m_pCloseButton->SetCore(m_pCore);
                    NcButtons_Add( m_pCloseButton );
                }
            }
            else
            {
                if( nCountOfNcButtons > 0 )
                {
                    NcButtons_RemoveAll();
                }
            }
        }
    }
}

The problem I have now is removing the panel when the close button is clicked - I want to remove the panel not just hide it.

I have accomplished this using the following overload in my closebutton class

    virtual bool OnNcAreaClicked( CPoint point )
    {
        ASSERT_VALID( this );
        // They clicked the button i think
        if(!m_rc.PtInRect(point))return false;

        RemovePanel();
        return true; // continue asking nc-buttins
    }

My RemovePanel function uses the RemoveControlBar method. This works fine unless the control bar is tabbed - the control bar gets removed as desired when the close button is clicked however if I then drag the remaining control bar and try to tab it with another I get an application crash with the following debug info:

mfc71ud.dll!CObject::IsKindOf(const CRuntimeClass * pClass=0x007776d8) Line 44 + 0x8    C++
ProfUIS230ud.dll!0050de2a()     
ProfUIS230ud.dll!004d4800()     
ProfUIS230ud.dll!0050ce18()     
ProfUIS230ud.dll!0050fc12()     
ProfUIS230ud.dll!0050f9c3()     
ProfUIS230ud.dll!004feec5()     
ProfUIS230ud.dll!004fba61()     

Technical Support May 10, 2005 - 12:52 PM

There is not enough to call the CFrameWnd::RemoveControlBar() method because MFC’s frame window knows nothing about internal implementation of tabbed bar groups in Prof-UIS. Here is the source code which removes the resizable control bar specified by pBar regardless of its state:

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;
 m_mapBars.RemoveKey( pBar );
 if( pMiniFrame != NULL )
  pMiniFrame->DestroyWindow();
 else
  pBar->DestroyWindow();
 if( ! bForceNoOptimizeMode )
  CExtDockBar::_OptimizeCircles( pDockSite );

Chris Fudge May 10, 2005 - 1:35 PM

Thats Great thanks - It fixes most of my problem however I have had to comment out two parts to get it going :

pDockSite variable is undefined.

I also get an unknown variable error for bForceNoOptimizeMode.

Thanks again

Chris Fudge May 11, 2005 - 6:55 AM

Ive also noticed that a Control Bar doesnt get removed under the following conditions when there are 2 control bars (A and B) which are initially separate from each other (not tabbed ):

1) Drag A onto B - B becomes the selected tab.
2) Select A’s tab and drag so that it is docked below B.
3) Close B using the Removal code above.

When I do this B doesnt get removed.

Also please could you clarify what m_mapBars is?

Technical Support May 12, 2005 - 3:45 AM

We will certainly check this issue. We took the source code for removing control bars in any state from the new CExtDynamicBarSite class and can say that we did not encounter any problems with allocating/deallocating resizable bars dynamically. m_mapBars is used for keeping pointers to bar objects as key values in the map. Please let us know what happens with the control bar that fails to be removed? Is it accessible UI part like any other bars? Do you have any assertions?

Chris Fudge May 12, 2005 - 3:56 AM

The control bar doesnt remain as a fully functional control bar.

Upon closing it - the title string disappears but the bar remains.

It can be floated, however when it is dragged to be docked /tabbed with any other bars it disappears.

There are no asserts at any stage.

Technical Support May 13, 2005 - 8:56 AM

Could you send us your project or the entire code snippet/method that removes the control bar?

Chris Fudge May 16, 2005 - 9:25 AM

void CMainFrame::RemovePanel(CXPPanel *pBar)
{


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 * pDynTabbedBar = STATIC_DOWNCAST( CExtDynTabControlBar, pBar->m_pDockBar->GetParent() );
                CXPTabPanel * pTabbedBar = (CXPTabPanel *) pDynTabbedBar;

                LONG nIdx = pTabbedBar->FindControlBar( pBar );
                if( nIdx >= 0 )
                {
                    LONG nSel = pTabbedBar->GetSwitcherSelection();
                    if( nIdx != nSel )
                    {
                        pTabbedBar->SetSwitcherSelection( nIdx );
                    }
                    pTabbedBar->RemoveSelFromSwitcher();

                    if(pTabbedBar->GetSwitcherItemCount() > 0)
                    {
                        pTabbedBar->SetSwitcherSelection(0);
                    }

                    pTabbedBar->OnNcAreaButtonsReinitialize();

                } // 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() )


RemoveControlBar( pBar );
pBar->m_pDockSite    = NULL;
pBar->m_pDockBar    = NULL;


if( pMiniFrame != NULL )
    pMiniFrame->DestroyWindow();
else
    pBar->DestroyWindow();

CExtDockBar::_OptimizeCircles( this);


RecalcLayout();

}

Technical Support May 17, 2005 - 9:04 AM

We have tested your control code for removing control bars in our SDI sample. We used the standard CExtControlBar type instead of CXPPanel and found no problems. Does your CXPPanel class override any internal method of CExtControlBar? Do you use Prof-UIS of version 2.32 or 2.30? Could you send us your real or any test project? Finally, here it is the universal code for removing control bars:

#include "AfxPriv.h"
#include "../Src/ExtDockBar.h"
#include "../Src/ExtControlBarTabbedFeatures.h"
 
. . .
 
void CMainFrame::_RemovePanel(
    CExtControlBar * pBar
    )
{
CMiniDockFrameWnd * pMiniFrame = NULL;
    if( pBar->IsFloating() )
    {
        pMiniFrame =
            DYNAMIC_DOWNCAST(
                CMiniDockFrameWnd,
                pBar->GetDockingFrame()
                );
        ASSERT_VALID( pMiniFrame );
    }
    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 );
        }
#endif
        if(    pBar->m_pDockBar->
                IsKindOf(
                    RUNTIME_CLASS( CExtDockBar )
                    )
                )
        {
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
            if(    pBar->m_pDockBar->
                    IsKindOf(
                        RUNTIME_CLASS(
                            CExtDockDynTabBar
                            )
                        )
                    )
            {
                CExtDynTabControlBar * pDynTabbedBar =
                    STATIC_DOWNCAST(
                        CExtDynTabControlBar,
                        pBar->m_pDockBar->GetParent()
                        );
                LONG nIdx =
                    pDynTabbedBar->FindControlBar( pBar );
                if( nIdx >= 0 )
                {
                    LONG nSel =
                        pDynTabbedBar->
                            GetSwitcherSelection();
                    if( nIdx != nSel )
                        pDynTabbedBar->
                            SetSwitcherSelection( nIdx );
                    pDynTabbedBar->RemoveSelFromSwitcher();
                    if( pDynTabbedBar->
                            GetSwitcherItemCount() > 0
                        )
                        pDynTabbedBar->
                            SetSwitcherSelection(0);
                    pDynTabbedBar->
                        OnNcAreaButtonsReinitialize();
                }
            }
#endif
            VERIFY(
                ((CExtDockBar *)pBar->m_pDockBar)->
                    RemoveControlBar( pBar, -1, 0, false )
                );
        }
        else
        {
            VERIFY(
                pBar->m_pDockBar->RemoveControlBar(pBar)
                );
        }
    } // else from if( pBar->IsFloating() )
    RemoveControlBar( pBar );
    pBar->m_pDockSite = NULL;
    pBar->m_pDockBar = NULL;
    if( pMiniFrame != NULL )
        pMiniFrame->DestroyWindow();
    else
        pBar->DestroyWindow();
    CExtDockBar::_OptimizeCircles( this);
    RecalcLayout();
}