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 » A crash when calling CExtRibbonBar::SetButtons(NULL) Collapse All
Subject Author Date
Jacek Piszczek Dec 3, 2007 - 12:55 AM

Hi!

There seems to be a problem when calling SetButtons(NULL) on a Ribbon. If there are animation clients active, ProfUIS will crash in
CExtToolControlBar::_GetButtonPtr(). This is because CExtToolControlBar::AnimationSite_OnProgressShutdownTimer() calls _UpdateHoverButton which in turn performs a check on all buttons inside _HitTestImpl(). Now let’s look at the code in _RemoveAllButtonsImpl:

    for( INT nBtnIdx = 0; nBtnIdx < m_buttons.GetSize(); nBtnIdx++ )
    {
        CExtBarButton * pTBB = m_buttons[nBtnIdx];
        ASSERT( pTBB != NULL );
        AnimationSite_ClientRemove( pTBB );
        delete pTBB;
    } // for( INT nBtnIdx = 0; nBtnIdx < m_buttons.GetSize(); nBtnIdx++ )

As you can see AnimationSite_ClientRemove may already crash for the 2nd iteration because the m_buttons[0] button was already deleted and the table still contains a bogus pointer. I guess doing the iteration twice (removing all animation clients in the 1st iteration) is the safest solution here.

Technical Support Dec 3, 2007 - 7:33 AM

We think your guess about the crash may be wrong because the CExtToolControlBar::_RemoveAllButtonsImpl() method invokes the AnimationSite_ClientProgressStop() method of each toolbar button object (the animation client) before removing all buttons:

void CExtToolControlBar::_RemoveAllButtonsImpl()
{
INT nAcIndex, nAcCount = AnimationSite_ClientGetCount();
      for( nAcIndex = 0; nAcIndex < nAcCount; nAcIndex ++ )
      {
            CExtAnimationClient * pAC = AnimationSite_ClientGetAt( nAcIndex );
            AnimationSite_ClientProgressStop( pAC );
      }
      if( GetMenuTrackingButton() != NULL )
      {
            _CloseTrackingMenus();
            CExtPopupMenuWnd::CancelMenuTracking();
      }
      if( m_pRightBtn != NULL )
            m_pRightBtn->GetButtons().RemoveAll();
      for( INT nBtnIdx = 0; nBtnIdx < m_buttons.GetSize(); nBtnIdx++ )
      {
            CExtBarButton * pTBB = m_buttons[nBtnIdx];
            ASSERT( pTBB != NULL );
            AnimationSite_ClientRemove( pTBB );
            delete pTBB;
      } // for( INT nBtnIdx = 0; nBtnIdx < m_buttons.GetSize(); nBtnIdx++ )
      m_buttons.RemoveAll();
      m_pRightBtn = NULL;
      m_nBtnIdxCapture = -1;      // nothing captured
      m_nBtnIdxHover = -1;
      m_nBtnIdxMenuTracking = -1;
}
Could you reproduce the crash in a modified version of the RibbonBar sample and send it to us?