Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Ogni volta che un'applicazione pianifica uno storyboard, deve fornire l'ora corrente al gestore delle animazioni. L'ora corrente è necessaria anche quando si indirizza la gestione animazioni per aggiornarne lo stato e impostare tutte le variabili di animazione sui valori interpolati appropriati.
Panoramica
Esistono due configurazioni supportate dall'animazione di Windows: animazione guidata dall'applicazione e animazione basata su timer.
Per usare l'animazione guidata dall'applicazione nell'applicazione, è necessario aggiornare la gestione animazioni prima di disegnare ogni fotogramma e usare un meccanismo appropriato per disegnare fotogrammi con frequenza sufficiente per l'animazione. Un'applicazione che utilizza animazione guidata dall'applicazione può impiegare qualsiasi meccanismo per determinare l'ora corrente, ma l'oggetto timer di Windows Animation restituisce un tempo preciso nelle unità accettate dal gestore delle animazioni. Per evitare disegni non necessari quando non viene riprodotta alcuna animazione, devi anche fornire un gestore di eventi per iniziare a ridisegnare quando le animazioni sono pianificate e controllare se è possibile sospendere il ridisegno dopo ogni fotogramma. Per altre informazioni, vedere Application-Driven Animation.
Nella configurazione guidata dall'applicazione, l'applicazione può chiamare il metodo IUIAnimationManager::GetStatus per verificare che le animazioni siano attualmente in programma e continuare a disegnare fotogrammi se sono. Poiché il ridisegno si interrompe quando non sono pianificate animazioni, è necessario riavviarlo alla successiva pianificazione di un'animazione. Un'applicazione può registrare un gestore degli eventi per ricevere una notifica quando lo stato del gestore delle animazioni cambia da inattivo (nessuna animazione è attualmente programmata) a occupato.
Per usare l'animazione basata su timer nell'applicazione, devi connettere la gestione animazioni a un timer di animazione e fornire un gestore eventi timer. Quando la gestione animazioni è connessa a un timer, il timer può indicare al gestore quando lo stato dell'animazione deve essere aggiornato man mano che il tempo avanza. L'applicazione deve disegnare un frame per ogni tick del timer. Il gestore di animazioni può a sua volta indicare al timer quando sono in riproduzione animazioni, in modo che il timer possa chiudersi durante i periodi di inattività quando il ridisegno non è necessario. Per evitare disegni non necessari quando non vengono riprodotte animazioni, è necessario configurare il timer per disabilitarsi automaticamente. Per altre informazioni, vedere Timer-Driven Animation.
Codice di esempio
Animazione Application-Driven
Il codice di esempio seguente è tratto da ManagerEventHandler.h dagli esempi di animazione di Windows Application-Driven Animation e Grid Layout. Definisce il gestore degli eventi del manager.
#include "UIAnimationHelper.h"
// Event handler object for manager status changes
class CManagerEventHandler :
public CUIAnimationManagerEventHandlerBase<CManagerEventHandler>
{
public:
static HRESULT
CreateInstance
(
CMainWindow *pMainWindow,
IUIAnimationManagerEventHandler **ppManagerEventHandler
) throw()
{
CManagerEventHandler *pManagerEventHandler;
HRESULT hr = CUIAnimationCallbackBase::CreateInstance(
ppManagerEventHandler,
&pManagerEventHandler
);
if (SUCCEEDED(hr))
{
pManagerEventHandler->m_pMainWindow = pMainWindow;
}
return hr;
}
// IUIAnimationManagerEventHandler
IFACEMETHODIMP
OnManagerStatusChanged
(
UI_ANIMATION_MANAGER_STATUS newStatus,
UI_ANIMATION_MANAGER_STATUS previousStatus
)
{
HRESULT hr = S_OK;
if (newStatus == UI_ANIMATION_MANAGER_BUSY)
{
hr = m_pMainWindow->Invalidate();
}
return hr;
}
...
};
Il codice di esempio seguente è tratto da MainWindow.cpp dall'esempio di animazione di Windows Application-Driven Animation; vedere CMainWindow::InitializeAnimation. Questo esempio crea un'istanza del gestore eventi manager usando il metodoCreateInstancee lo passa al gestore animazioni usando il metodo IUIAnimationManager::SetManagerEventHandler.
// Create and set the ManagerEventHandler to start updating when animations are scheduled
IUIAnimationManagerEventHandler *pManagerEventHandler;
HRESULT hr = CManagerEventHandler::CreateInstance(
this,
&pManagerEventHandler
);
if (SUCCEEDED(hr))
{
hr = m_pAnimationManager->SetManagerEventHandler(
pManagerEventHandler
);
pManagerEventHandler->Release();
}
Poiché il gestore eventi mantiene un riferimento all'oggetto finestra principale, il gestore eventi deve essere eliminato (passando NULL a SetManagerEventHandler) o il gestore di animazione deve essere completamente liberato prima che la finestra principale venga eliminata.
Il codice di esempio seguente è tratto da MainWindow.cpp nell'esempio di animazione di Windows Application-Driven Animation; vedere il metodo CMainWindow::OnPaint. Chiama il metodo IUIAnimationManager::GetTime per recuperare il tempo nelle unità richieste dal metodo IUIAnimationManager::Update.
// Update the animation manager with the current time
UI_ANIMATION_SECONDS secondsNow;
HRESULT hr = m_pAnimationTimer->GetTime(
&secondsNow
);
if (SUCCEEDED(hr))
{
hr = m_pAnimationManager->Update(
secondsNow
);
...
}
Il codice di esempio seguente è tratto da MainWindow.cpp dagli esempi di animazione di Windows Application-Driven Animation e Grid Layout; vedere il metodo CMainWindow::OnPaint. Si presuppone che l'applicazione usi un'API grafica che si sincronizza automaticamente con la frequenza di aggiornamento del monitoraggio (ad esempio Direct2D con le impostazioni predefinite), nel qual caso una chiamata alla funzione InvalidateRect è sufficiente per garantire che il codice di disegno venga chiamato di nuovo quando è il momento di disegnare il fotogramma successivo. Anziché chiamare InvalidateRect in modo incondizionato, è preferibile verificare se sono ancora presenti animazioni pianificate usando GetStatus.
// Read the values of the animation variables and draw the client area
hr = DrawClientArea();
if (SUCCEEDED(hr))
{
// Continue redrawing the client area as long as there are animations scheduled
UI_ANIMATION_MANAGER_STATUS status;
hr = m_pAnimationManager->GetStatus(
&status
);
if (SUCCEEDED(hr))
{
if (status == UI_ANIMATION_MANAGER_BUSY)
{
InvalidateRect(
m_hwnd,
NULL,
FALSE
);
}
}
}
Animazione Timer-Driven
Il codice di esempio seguente è tratto da TimerEventHandler.h dall'esempio di animazione di Windows Timer-Driven Animation. Il codice di esempio definisce il gestore eventi timer, che invalida l'area client della finestra per causare un ridisegno dopo ogni aggiornamento dello stato dell'animazione.
#include "UIAnimationHelper.h"
// Event handler object for timer events
class CTimerEventHandler :
public CUIAnimationTimerEventHandlerBase<CTimerEventHandler>
{
public:
static HRESULT
CreateInstance
(
CMainWindow *pMainWindow,
IUIAnimationTimerEventHandler **ppTimerEventHandler
) throw()
{
CTimerEventHandler *pTimerEventHandler;
HRESULT hr = CUIAnimationCallbackBase::CreateInstance(
ppTimerEventHandler,
&pTimerEventHandler
);
if (SUCCEEDED(hr))
{
pTimerEventHandler->m_pMainWindow = pMainWindow;
}
return hr;
}
// IUIAnimationTimerEventHandler
IFACEMETHODIMP
OnPreUpdate()
{
return S_OK;
}
IFACEMETHODIMP
OnPostUpdate()
{
HRESULT hr = m_pMainWindow->Invalidate();
return hr;
}
IFACEMETHODIMP
OnRenderingTooSlow
(
UINT32 /* fps */
)
{
return S_OK;
}
...
};
Il codice di esempio seguente è tratto da MainWindow.cpp dall'esempio di animazione di Windows Timer-Driven Animation; vedere CMainWindow::InitializeAnimation. Questo esempio crea un'istanza del gestore eventi timer usando il metodoCreateInstancee lo passa al timer usando il metodo IUIAnimationTimer::SetTimerEventHandler. Poiché il gestore eventi timer mantiene un riferimento all'oggetto finestra principale, il gestore eventi timer deve essere cancellato (passando NULL a SetTimerEventHandler) o il timer completamente rilasciato prima che la finestra principale venga eliminata definitivamente.
// Create and set the timer event handler
IUIAnimationTimerEventHandler *pTimerEventHandler;
hr = CTimerEventHandler::CreateInstance(
this,
&pTimerEventHandler
);
if (SUCCEEDED(hr))
{
hr = m_pAnimationTimer->SetTimerEventHandler(
pTimerEventHandler
);
pTimerEventHandler->Release();
}
Il codice di esempio seguente è tratto da MainWindow.cpp nell'esempio di animazione di Windows Timer-Driven Animation; vedere il metodo CMainWindow::InitializeAnimation. Chiama il metodo QueryInterface sull'oggetto di gestione delle animazioni per ottenere un puntatore a IUIAnimationTimerUpdateHandler, quindi connette gli oggetti UIAnimationManager e UIAnimationTimer impostando il gestore di animazioni come gestore di aggiornamento del timer usando il metodo IUIAnimationTimer::SetTimerUpdateHandler. Si noti che non è necessario cancellare esplicitamente questa connessione; la connessione viene cancellata in modo sicuro dopo che l'applicazione rilascia sia la gestione animazioni che il timer di animazione.
// Connect the animation manager to the timer
IUIAnimationTimerUpdateHandler *pTimerUpdateHandler;
hr = m_pAnimationManager->QueryInterface(
IID_PPV_ARGS(&pTimerUpdateHandler)
);
if (SUCCEEDED(hr))
{
hr = m_pAnimationTimer->SetTimerUpdateHandler(
pTimerUpdateHandler
UI_ANIMATION_IDLE_BEHAVIOR_DISABLE // timer will shut itself off when there are no animations playing
);
pTimerUpdateHandler->Release();
if (SUCCEEDED(hr))
{
// Create and set the timer event handler
...
}
}
Se UI_ANIMATION_IDLE_BEHAVIOR_DISABLE non viene usato, è anche necessario attivare il timer per farlo iniziare a ticchettare.
Passaggio precedente
Prima di iniziare questo passaggio, è necessario aver completato questo passaggio: Creare variabili di animazione.
Passaggio successivo
Dopo aver completato questo passaggio, il passaggio successivo è: Leggere i valori delle variabili di animazione.
Argomenti correlati
-
Panoramica animazione di Windows