Anwenden von 2D-Transformationen

Hinweis

Für Apps auf Windows 10 empfehlen wir die Verwendung von Windows.UI.Composition-APIs anstelle von DirectComposition. Weitere Informationen finden Sie unter Modernisieren Ihrer Desktop-App mithilfe der visuellen Ebene.

In diesem Thema wird veranschaulicht, wie 2D-Transformationen mithilfe von Microsoft DirectComposition auf ein Visual angewendet werden. Im Beispiel in diesem Thema wird eine Gruppe von Transformationen angewendet, die:

  1. Drehen Sie das Visual um 180 Grad.
  2. Skalieren Sie das Visual auf das Dreifache seiner ursprünglichen Größe hoch.
  3. Übersetzen (verschieben) Sie das Visual 150 Pixel rechts von seiner ursprünglichen Position.

Die folgenden Screenshots zeigen das Visual vor und nach dem Anwenden der 2D-Transformationen.

Ergebnis der Anwendung einer Gruppe von 2d-Transformationen auf ein Visual

Wichtige Informationen

Technologien

Voraussetzungen

  • C/C++
  • Microsoft Win32
  • Component Object Model (COM)

Instructions

Schritt 1: Initialisieren von DirectComposition-Objekten

  1. Erstellen Sie das Geräteobjekt und das Kompositionszielobjekt.
  2. Erstellen Sie ein Visual, legen Sie dessen Inhalt fest, und fügen Sie es der visuellen Struktur hinzu.

Weitere Informationen finden Sie unter Initialisieren von DirectComposition.

Schritt 2: Erstellen des Gruppentransformationsarrays

IDCompositionTransform *pTransforms[3];

Schritt 3: Erstellen der Transformationsobjekte, Festlegen ihrer Eigenschaften und Hinzufügen zum Array der Transformationsgruppe

  1. Verwenden Sie die Methoden IDCompositionDevice::CreateRotateTransform, ::CreateScaleTransformund ::CreateTranslateTransform, um die Transformationsobjekte zu erstellen.
  2. Verwenden Sie die Memberfunktionen der Schnittstellen IDCompositionRotateTransform, IDCompositionScaleTransformund IDCompositionTranslateTransform, um die Eigenschaften der Transformationen zu festlegen.
  3. Kopieren Sie die Zeiger der Transformationsschnittstelle auf das Array der Transformationsgruppe.
IDCompositionRotateTransform *pRotateTransform = nullptr;
IDCompositionScaleTransform *pScaleTransform = nullptr;
IDCompositionTranslateTransform *pTranslateTransform = nullptr;
IDCompositionTransform *pTransformGroup = nullptr;

// Create the rotate transform.
hr = pDevice->CreateRotateTransform(&pRotateTransform);

if (SUCCEEDED(hr))
{
    // Set the center of rotation to the center point of the visual.
    hr = pRotateTransform->SetCenterX(BITMAP_WIDTH/2.0f);
    
    if (SUCCEEDED(hr)) {
        hr = pRotateTransform->SetCenterY(BITMAP_HEIGHT/2.0f);
    }

    // Set the rotate angle to 180 degrees.
    if (SUCCEEDED(hr)) {
        hr = pRotateTransform->SetAngle(180.0f);
    }

    // Add the rotate transform to the transform group array.
    pTransforms[0] = pRotateTransform;

    // Create the scale transform.
    if (SUCCEEDED(hr)) {
        hr = pDevice->CreateScaleTransform(&pScaleTransform);
    }
}

if (SUCCEEDED(hr))
{
    // Set the scaling origin to the upper-right corner of the visual.
    hr = pScaleTransform->SetCenterX(0.0f);
    if (SUCCEEDED(hr)) {
        hr = pScaleTransform->SetCenterY(0.0f);
    }

    // Set the scaling factor to three for both the width and height. 
    if (SUCCEEDED(hr)) {
        hr = pScaleTransform->SetScaleX(3.0f);
    }
    if (SUCCEEDED(hr)) {
        hr = pScaleTransform->SetScaleY(3.0f);
    }

    // Add the scale transform to the transform group array.
    pTransforms[1] = pScaleTransform;

    // Create the translate transform.
    if (SUCCEEDED(hr)) {
        hr = pDevice->CreateTranslateTransform(&pTranslateTransform);
    }
}

if (SUCCEEDED(hr))
{
    // Move the visual 150 pixels to the right.
    hr = pTranslateTransform->SetOffsetX(150.0f);
    if (SUCCEEDED(hr)) {
        hr = pTranslateTransform->SetOffsetY(0.0f);
    }

    // Add the translate transform to the transform group array.
    pTransforms[2] = pTranslateTransform;
}

Schritt 4: Erstellen des Transformationsgruppe-Objekts

Rufen Sie die IDCompositionDevice::CreateTransformGroup-Methode auf, um das Transformationsgruppe-Objekt zu erstellen.

if (SUCCEEDED(hr))
{
    // Create the transform group.
    hr = pDevice->CreateTransformGroup(pTransforms, 3, &pTransformGroup);
}

Schritt 5: Anwenden des Transformationsgruppe-Objekts auf das Visual

Verwenden Sie die IDCompositionVisual::SetTransform-Methode, um die Transform-Eigenschaft des Visuals dem Transformationsgruppe-Objekt zu zuordnen.

if (SUCCEEDED(hr))
{
    // Apply the transform group to the visual.
    hr = pVisual->SetTransform(pTransformGroup);
}

Schritt 6: Commit der Komposition

Rufen Sie die IDCompositionDevice::Commit-Methode auf, um die Updates für das Visual zur Verarbeitung an DirectComposition zu commiten. Das Ergebnis der Anwendung der Gruppe von 2D-Transformationen wird im Zielfenster angezeigt.

if (SUCCEEDED(hr))
{
    // Commit the composition.
    hr = pDevice->Commit();
}

Schritt 7: Freisetzung der DirectComposition-Objekte

Achten Sie darauf, die Gruppe der 2D-Transformationsobjekte frei zu lassen, wenn Sie sie nicht mehr benötigen. Das folgende Beispiel ruft das anwendungsdefinierte SafeRelease-Makro auf, um die Transformationsobjekte frei zu geben.

// Release the transform objects.
for (int i = 0; i < 3; i++)
{
    SafeRelease(&pTransforms[i]);
}

Denken Sie auch daran, das Geräteobjekt, das Kompositionszielobjekt und die visuellen Elemente frei zu geben, bevor Ihre Anwendung beendet wird.

Vollständiges Beispiel

#define BITMAP_WIDTH  80.0
#define BITMAP_HEIGHT 80.0

HRESULT DemoApp::ApplyTransformGroup(IDCompositionDevice *pDevice, 
                                     IDCompositionVisual *pVisual)
{
    HRESULT hr = S_OK;

    if (pDevice == nullptr || pVisual == nullptr)
        return E_INVALIDARG; 
    
    IDCompositionTransform *pTransforms[3];

    IDCompositionRotateTransform *pRotateTransform = nullptr;
    IDCompositionScaleTransform *pScaleTransform = nullptr;
    IDCompositionTranslateTransform *pTranslateTransform = nullptr;
    IDCompositionTransform *pTransformGroup = nullptr;

    // Create the rotate transform.
    hr = pDevice->CreateRotateTransform(&pRotateTransform);

    if (SUCCEEDED(hr))
    {
        // Set the center of rotation to the center point of the visual.
        hr = pRotateTransform->SetCenterX(BITMAP_WIDTH/2.0f);
        
        if (SUCCEEDED(hr)) {
            hr = pRotateTransform->SetCenterY(BITMAP_HEIGHT/2.0f);
        }

        // Set the rotate angle to 180 degrees.
        if (SUCCEEDED(hr)) {
            hr = pRotateTransform->SetAngle(180.0f);
        }

        // Add the rotate transform to the transform group array.
        pTransforms[0] = pRotateTransform;

        // Create the scale transform.
        if (SUCCEEDED(hr)) {
            hr = pDevice->CreateScaleTransform(&pScaleTransform);
        }
    }

    if (SUCCEEDED(hr))
    {
        // Set the scaling origin to the upper-right corner of the visual.
        hr = pScaleTransform->SetCenterX(0.0f);
        if (SUCCEEDED(hr)) {
            hr = pScaleTransform->SetCenterY(0.0f);
        }

        // Set the scaling factor to three for both the width and height. 
        if (SUCCEEDED(hr)) {
            hr = pScaleTransform->SetScaleX(3.0f);
        }
        if (SUCCEEDED(hr)) {
            hr = pScaleTransform->SetScaleY(3.0f);
        }

        // Add the scale transform to the transform group array.
        pTransforms[1] = pScaleTransform;

        // Create the translate transform.
        if (SUCCEEDED(hr)) {
            hr = pDevice->CreateTranslateTransform(&pTranslateTransform);
        }
    }

    if (SUCCEEDED(hr))
    {
        // Move the visual 150 pixels to the right.
        hr = pTranslateTransform->SetOffsetX(150.0f);
        if (SUCCEEDED(hr)) {
            hr = pTranslateTransform->SetOffsetY(0.0f);
        }

        // Add the translate transform to the transform group array.
        pTransforms[2] = pTranslateTransform;
    }

    if (SUCCEEDED(hr))
    {
        // Create the transform group.
        hr = pDevice->CreateTransformGroup(pTransforms, 3, &pTransformGroup);
    }

    if (SUCCEEDED(hr))
    {
        // Apply the transform group to the visual.
        hr = pVisual->SetTransform(pTransformGroup);
    }

    if (SUCCEEDED(hr))
    {
        // Commit the composition.
        hr = pDevice->Commit();
    }

    // Release the transform objects.
    for (int i = 0; i < 3; i++)
    {
        SafeRelease(&pTransforms[i]);
    }

    // Release the transform group pointer.
    SafeRelease(&pTransformGroup);

    return hr;
}

Transformationen