Share via


Anwenden von 2D-Transformationen

Hinweis

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

In diesem Thema wird veranschaulicht, wie Sie 2D-Transformationen mithilfe von Microsoft DirectComposition auf ein Visual anwenden. Das Beispiel in diesem Thema wendet eine Gruppe von Transformationen an, die:

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

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

Ergebnis des Anwendens einer Gruppe von 2D-Transformationen auf ein Visual

Wichtige Informationen

Technologien

Voraussetzungen

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

Anweisungen

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 Transformationsgruppenarrays

IDCompositionTransform *pTransforms[3];

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

  1. Verwenden Sie die Methoden IDCompositionDevice::CreateRotateTransform, ::CreateScaleTransform und ::CreateTranslateTransform , um die Transformationsobjekte zu erstellen.
  2. Verwenden Sie die Memberfunktionen der Schnittstellen IDCompositionRotateTransform, IDCompositionScaleTransform und IDCompositionTranslateTransform , um die Eigenschaften der Transformationen festzulegen.
  3. Kopieren Sie die Transformationsschnittstellenzeiger auf das Transformationsgruppenarray.
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 Transformationsgruppenobjekts

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

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

Schritt 5: Anwenden des Transformationsgruppenobjekts auf das Visual

Verwenden Sie die IDCompositionVisual::SetTransform-Methode , um die Transform-Eigenschaft des Visuals dem Transformationsgruppenobjekt zuzuordnen.

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

Schritt 6: Commit für die Komposition

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

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

Schritt 7: Freigeben der DirectComposition-Objekte

Achten Sie darauf, die Gruppe der 2D-Transformationsobjekte freizugeben, wenn Sie sie nicht mehr benötigen. Im folgenden Beispiel wird das anwendungsdefinierte SafeRelease-Makro aufgerufen, 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 Visuals 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