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 » RibbonBar: explicit stop of background animation possible? Collapse All
Subject Author Date
Oliver Rau Jan 29, 2010 - 3:38 AM

Dear ProfUIS-Team,

in our application we are switching between two ribbon bars using the following approach:

CExtRibbonBar m_wndRibbonBar;
CExtRibbonNode * m_pRibbonNode_1;
CExtRibbonNode * m_pRibbonNode_2;
[...]
m_wndRibbonBar.SetButtons(  m_pRibbonNode_1_OR_2 );
[...]
m_wndRibbonBar._RecalcPositionsImpl();
m_wndRibbonBar.Invalidate();
m_wndRibbonBar.UpdateWindow();

Although I know that you do not recommend to switch between two ribbons in one frame window (see General Forum 2007/09/03 "Switching between two ribbonbars?") this approach worked for us pretty well for v2.82. But after updating to v2.87 we got problems with background animation processes (e.g. hover animation) that still reference objects owned by the previously loaded ribbon node.

Therefore my question: is there a way to explicitly stop all kind of background ribbon animation in order not to run into trouble after a ribbon node switch.

Kind regards,

Martin

Technical Support Feb 27, 2010 - 8:47 AM

The CExtAnimationSite::AnimationSite_ClientProgressStop() and CExtAnimationClient::AnimationClient_OnProgressStop() virtual methods are invoked when a UI item animation is finished. But there are no retranslated version of these virtual methods you can subscribe. The CExtAnimationSite::AnimationSite_ClientProgressStop() virtual method can be overridden in your ribbon bar class to catch end of animation event for ribbon buttons. But there is no virtual method notifying about all the animations finished.
We think the real problem is that two subsystems are using timer based code enough aggressively. One is Prof-UIS animations, second is some part of your application. The good way to resolve such issues is to move one of them into another thread.

Technical Support Jan 29, 2010 - 9:31 AM

There are several ways to suspend the alpha blending based animations in Prof-UIS. Please let us to explain details. A set of Prof-UIS controls provide support for these animations. They have the CExtAnimationClient class as non-first parent class. The CExtAnimationClient::AnimationClient_OnQueryAnimationParameters() virtual method returns the CExtAnimationParameters data object describing how to animate the animation client. The animation client can be either solid control based on standalone HWND handle like CExtButton control. It can be non-HWND<code>-based a part of another window like toolbar or ribbon bar button. The non-<code>HWND-based animation client can be either part of window client area and its non-client area. You can override the CExtAnimationClient::AnimationClient_OnQueryAnimationParameters() virtual method of any animated control or C++ class and return pointer to the CExtPaintManager::g_DefAnimationParametersEmpty static object describing zero animation rules based on zero count of alpha blending steps. This was the first and the most advanced way. Fortunately, all the overridden versions of the CExtAnimationClient::AnimationClient_OnQueryAnimationParameters() virtual method in all the Prof-UIS animated components are invoking the CExtPaintManager::Animation_GetParameters() virtual method. This means the currently installed paint manager controls animations of all the animation enabled Prof-UIS components. You can code your paint manager class, override this method and return pointer to the CExtPaintManager::g_DefAnimationParametersEmpty static object. This will also stop any animations everywhere. This was the second way and it’s better than previous because the CExtPaintManager::Animation_GetParameters() virtual method has the CObject * pHelperSrc parameter specifying pointer to the animation enabled Prof-UIS component. You can check it’s type and disable animations for particular components only. The ribbon bar and toolbar controls use the CExtBarButton objects implementing ribbon bar and toolbar buttons. But there is the third way and it’s even easier and does not require virtual method overriding but, unfortunately, it can suspend only all the animations in all the components. The CExtPaintManager::Animation_GetParameters() virtual method and all its overridden versions are always return pointers to the following static objects:

CExtAnimationParameters CExtPaintManager::g_DefAnimationParametersEmpty( 0, 0 );
CExtAnimationParameters CExtPaintManager::g_DefAnimationParametersNormal( __EXT_MFC_DEF_ANIMATION_STEP_COUNT, __EXT_MFC_DEF_ANIMATION_TIMER_ELAPSE );
CExtAnimationParameters CExtPaintManager::g_DefAnimationParametersSlow( __EXT_MFC_DEF_ANIMATION_STEP_COUNT+1, __EXT_MFC_DEF_ANIMATION_TIMER_ELAPSE );
CExtAnimationParameters CExtPaintManager::g_DefAnimationParametersVerySlow( __EXT_MFC_DEF_ANIMATION_STEP_COUNT+2, __EXT_MFC_DEF_ANIMATION_TIMER_ELAPSE );
CExtAnimationParameters CExtPaintManager::g_DefAnimationParametersVerySlowAndSmooth( 4, 80 );

You can simply make all these animation parameters descriptions empty:
CExtPaintManager::g_DefAnimationParametersNormal.AnimationClient_StepCountSet( 0 );
CExtPaintManager::g_DefAnimationParametersSlow.AnimationClient_StepCountSet( 0 );
CExtPaintManager::g_DefAnimationParametersVerySlow.AnimationClient_StepCountSet( 0 );
CExtPaintManager::g_DefAnimationParametersVerySlowAndSmooth.AnimationClient_StepCountSet( 0 );

Oliver Rau Feb 5, 2010 - 11:30 AM

If I got you right, then your approach is useful to globally switch off any kind of animation.

But is there a way to stop only currently running animations at a certain moment, or at least to get a notification when all current animations are finished?

To be more precise: if I click-select an item in the recent documents’ list under the application button of the ribbonbar, our application opens the document through the OnRibbonGalleryItemSelEndOK() overridable (see below). Then, under some specific circumstances, we have to switch to the other ribbon node, but at this moment there is still a timer running animations in the background that reference objects that are not owned by the current ribbon node.

Here is our implementation of the OnRibbonGalleryItemSelEndOK() overridable (simplified):


void CMyRibbonBar::OnRibbonGalleryItemSelEndOK(
    CExtRibbonGalleryWnd & wndRG,
    CExtRibbonGalleryPopupMenuWnd * pGalleryPopup,
    CExtRibbonButtonGallery * pRibbonGalleryTBB,
    CExtToolBoxWnd::TOOLBOX_ITEM_DATA * pTBCI
    )
{
    DocID currDocID = GetDocID(pTBCI->TextGet());

    if (INVAL_DOCID != currDocID)
    {
	    LoadDoc(currDocID);
    }
}

Here is the deepest part of the stack trace:

	 099c52ab()   
>    mfc80ud.dll!AfxAssertValidObject(const CObject * pOb=0x099c53b8, const char * lpszFileName=0x04491f2c, int nLine=10632)  Line 99 + 0xe bytes    C++
	 ProfUIS287ud.dll!CExtRibbonGalleryWnd::OnToolBoxWndItemHoverChange(CExtToolBoxWnd::TOOLBOX_ITEM_DATA * pTBCI_Old=0x00000000, CExtToolBoxWnd::TOOLBOX_ITEM_DATA * pTBCI_New=0x140278f0)  Line 10633    C++
	 ProfUIS287ud.dll!CExtToolBoxWnd::TOOLBOX_ITEM_DATA::ModifyItemStyle(unsigned long dwStylesAdd=4, unsigned long dwStylesRemove=0)  Line 1008 + 0x22 bytes    C++
	 ProfUIS287ud.dll!CExtToolBoxWnd::OnMouseMove(unsigned int nFlags=0, CPoint point={...})  Line 5104 + 0x16 bytes    C++
	 mfc80ud.dll!CWnd::OnWndMsg(unsigned int message=512, unsigned int wParam=0, long lParam=3538976, long * pResult=0x012afba4)  Line 2169    C++
	 mfc80ud.dll!CWnd::WindowProc(unsigned int message=512, unsigned int wParam=0, long lParam=3538976)  Line 1741 + 0x20 bytes    C++
	 ProfUIS287ud.dll!CExtScrollWnd::WindowProc(unsigned int message=512, unsigned int wParam=0, long lParam=3538976)  Line 4396    C++
	 ProfUIS287ud.dll!CExtToolBoxWnd::WindowProc(unsigned int message=512, unsigned int wParam=0, long lParam=3538976)  Line 3955    C++
	 ProfUIS287ud.dll!CExtRibbonGalleryWnd::WindowProc(unsigned int message=512, unsigned int wParam=0, long lParam=3538976)  Line 10873 + 0x14 bytes    C++
	 mfc80ud.dll!AfxCallWndProc(CWnd * pWnd=0x14022cf4, HWND__ * hWnd=0x0016229c, unsigned int nMsg=512, unsigned int wParam=0, long lParam=3538976)  Line 240 + 0x1c bytes    C++
	 mfc80ud.dll!AfxWndProc(HWND__ * hWnd=0x0016229c, unsigned int nMsg=512, unsigned int wParam=0, long lParam=3538976)  Line 389    C++
	 mfc80ud.dll!AfxWndProcBase(HWND__ * hWnd=0x0016229c, unsigned int nMsg=512, unsigned int wParam=0, long lParam=3538976)  Line 411 + 0x15 bytes    C++
	 user32.dll!7e368734()    
	 [Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]   
	 user32.dll!7e368816()    
	 user32.dll!7e3689cd()    
	 user32.dll!7e368a10()    
[...]

Kind regards,

Martin

Oliver Rau Feb 26, 2010 - 7:51 AM

Due to the fact that my last post has obviously vanished into thin air, I dare to ask again : is there a way to get a notification when all current animations have been finished?


Martin

Oliver Rau Feb 1, 2010 - 2:40 AM

Thank you very much for this detailed description! And again: very good support ...


Kind regards,


Martin