Perbarui Pengelola Animasi dan Gambar Bingkai

Setiap kali aplikasi menjadwalkan papan cerita, aplikasi harus menyediakan waktu saat ini ke manajer animasi. Waktu saat ini juga diperlukan saat mengarahkan manajer animasi untuk memperbarui statusnya dan mengatur semua variabel animasi ke nilai terinterpolasi yang sesuai.

Gambaran Umum

Ada dua konfigurasi yang didukung oleh Animasi Windows: animasi berbasis aplikasi dan animasi berbasis timer.

Untuk menggunakan animasi berbasis aplikasi di aplikasi, Anda harus memperbarui pengelola animasi sebelum menggambar setiap bingkai dan menggunakan mekanisme yang sesuai untuk menggambar bingkai yang cukup sering untuk animasi. Aplikasi yang menggunakan animasi berbasis aplikasi dapat menggunakan mekanisme apa pun untuk menentukan waktu saat ini, tetapi objek timer Animasi Windows mengembalikan waktu yang tepat di unit yang diterima oleh manajer animasi. Untuk menghindari gambar yang tidak perlu ketika tidak ada animasi yang diputar, Anda juga harus menyediakan pengelola event handler untuk mulai menggambar ulang ketika animasi dijadwalkan dan memeriksa setelah setiap bingkai apakah redrawing dapat ditangguhkan. Untuk informasi selengkapnya, lihat Animasi Berbasis Aplikasi.

Dalam konfigurasi berbasis aplikasi, aplikasi dapat memanggil metode IUIAnimationManager::GetStatus untuk memverifikasi bahwa animasi saat ini dijadwalkan dan terus menggambar bingkai jika ada. Karena menggambar ulang berhenti ketika tidak ada animasi yang dijadwalkan, perlu untuk memulai ulang saat animasi dijadwalkan berikutnya. Aplikasi dapat mendaftarkan pengelola penanganan aktivitas untuk diberi tahu ketika status manajer animasi berubah dari singgah (tidak ada animasi yang saat ini dijadwalkan) menjadi sibuk.

Untuk menggunakan animasi berbasis timer di aplikasi, Anda harus menyambungkan pengelola animasi ke timer animasi dan menyediakan penanganan aktivitas pengatur waktu. Ketika manajer animasi tersambung ke timer, timer dapat memberi tahu manajer kapan status animasi harus diperbarui saat waktu berlangsung. Aplikasi harus menggambar bingkai untuk setiap centang timer. Manajer animasi pada gilirannya dapat memberi tahu timer ketika ada animasi yang diputar, sehingga timer dapat mematikan dirinya sendiri selama periode diam saat menggambar ulang tidak perlu. Untuk menghindari gambar yang tidak perlu ketika tidak ada animasi yang diputar, Anda harus mengonfigurasi timer untuk menonaktifkan dirinya sendiri secara otomatis. Untuk informasi selengkapnya, lihat Animasi Berbasis Timer.

Contoh Kode

Animasi Application-Driven

Contoh kode berikut diambil dari ManagerEventHandler.h dari Sampel Animasi Windows Animasi Animasi Berbasis Aplikasi dan Tata Letak Kisi. Ini mendefinisikan pengelola penanganan aktivitas.

#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;
    }

    ...

};

Contoh kode berikut diambil dari MainWindow.cpp dari contoh Animasi Windows Animasi Animasi Berbasis Aplikasi; lihat CMainWindow::InitializeAnimation. Contoh ini membuat instans pengelola penanganan aktivitas menggunakan metode CreateInstance dan meneruskannya ke manajer animasi menggunakan metode 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();
}

Karena pengelola penanganan aktivitas mempertahankan referensi ke objek jendela utama, penanganan aktivitas manajer harus dibersihkan (dengan meneruskan NULL ke SetManagerEventHandler) atau manajer animasi harus benar-benar dirilis sebelum jendela utama dihancurkan.

Contoh kode berikut diambil dari MainWindow.cpp di Animasi Windows sampel Animasi Animasi Berbasis Aplikasi; lihat metode CMainWindow::OnPaint. Ini memanggil metode IUIAnimationManager::GetTime untuk mengambil waktu dalam unit yang diperlukan oleh metode 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
        );

    ...

}

Contoh kode berikut diambil dari MainWindow.cpp dari sampel Animasi Windows Animasi Animasi Berbasis Aplikasi dan Tata Letak Kisi; lihat metode CMainWindow::OnPaint. Ini mengasumsikan bahwa aplikasi menggunakan API grafis yang secara otomatis disinkronkan ke kecepatan refresh monitor (seperti Direct2D dengan pengaturan defaultnya), dalam hal ini panggilan ke fungsi InvalidateRect sudah cukup untuk memastikan bahwa kode lukisan akan dipanggil lagi ketika sudah waktunya untuk menggambar bingkai berikutnya. Daripada memanggil InvalidateRect tanpa syarat, lebih baik memeriksa apakah masih ada animasi yang dijadwalkan menggunakan 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
                );
        }
    }
}

Animasi Timer-Driven

Contoh kode berikut diambil dari TimerEventHandler.h dari Animasi Windows sampel Animasi Timer-Driven Animation. Kode contoh mendefinisikan penanganan aktivitas pengatur waktu, yang membatalkan area klien jendela untuk menyebabkan repaint setelah setiap pembaruan status animasi.

#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;
    }

    ...

};

Contoh kode berikut diambil dari MainWindow.cpp dari contoh Animasi Windows Animasi Timer-Driven Animation; lihat CMainWindow::InitializeAnimation. Contoh ini membuat instans penanganan aktivitas timer menggunakan metode CreateInstance dan meneruskannya ke timer menggunakan metode IUIAnimationTimer::SetTimerEventHandler . Karena penanganan aktivitas timer mempertahankan referensi ke objek jendela utama, penangan aktivitas timer harus dibersihkan (dengan meneruskan NULL ke SetTimerEventHandler) atau timer benar-benar dirilis sebelum jendela utama dihancurkan.

// Create and set the timer event handler

IUIAnimationTimerEventHandler *pTimerEventHandler;
hr = CTimerEventHandler::CreateInstance(
    this,
    &pTimerEventHandler
    );
if (SUCCEEDED(hr))
{
    hr = m_pAnimationTimer->SetTimerEventHandler(
        pTimerEventHandler
        );
    pTimerEventHandler->Release();
}

Contoh kode berikut diambil dari MainWindow.cpp dalam contoh Animasi Windows Animasi Timer-Driven Animation; lihat metode CMainWindow::InitializeAnimation. Ini memanggil metode QueryInterface pada objek manajer animasi untuk mendapatkan penunjuk ke IUIAnimationTimerUpdateHandler, lalu menyambungkan objek UIAnimationManager dan UIAnimationTimer dengan mengatur manajer animasi sebagai penangan pembaruan timer menggunakan metode IUIAnimationTimer::SetTimerUpdateHandler . Perhatikan bahwa tidak perlu secara eksplisit menghapus koneksi ini; koneksi dibersihkan dengan aman setelah aplikasi merilis manajer animasi dan timer animasi.

// 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

        ...

    }
}

Jika UI_ANIMATION_IDLE_BEHAVIOR_DISABLE tidak digunakan, perlu juga untuk mengaktifkan timer untuk memulainya berdetak.

Langkah Sebelumnya

Sebelum memulai langkah ini, Anda seharusnya telah menyelesaikan langkah ini: Buat Variabel Animasi.

Langkah Selanjutnya

Setelah menyelesaikan langkah ini, langkah selanjutnya adalah: Baca Nilai Variabel Animasi.

IUIAnimationManager::GetStatus

IUIAnimationManager::SetManagerEventHandler

IUIAnimationManager::Update

IUIAnimationTimer::GetTime

IUIAnimationTimer::SetTimerUpdateHandler

UIAnimationManager

UIAnimationTimer

Gambaran Umum Animasi Windows