次の方法で共有


2D 変換を適用する方法

注意

Windows 10上のアプリの場合は、DirectComposition ではなく Windows.UI.Composition API を使用することをお勧めします。 詳細については、「 Visual レイヤーを使用してデスクトップ アプリをモダン化する」を参照してください。

このトピックでは、Microsoft DirectComposition を使用して 2D 変換をビジュアルに適用する方法について説明します。 このトピックの例では、次の変換のグループを適用します。

  1. ビジュアルを 180 度回転させます。
  2. ビジュアルを元のサイズの 3 倍にスケールアップします。
  3. ビジュアルを元の位置の右側に 150 ピクセル移動 (移動) します。

次のスクリーン ショットは、2D 変換の適用前と適用後のビジュアルを示しています。

2d 変換のグループをビジュアルに適用した結果

知っておくべきこと

テクノロジ

前提条件

  • C/C++
  • Microsoft Win32
  • コンポーネント オブジェクト モデル (COM)

Instructions

手順 1: DirectComposition オブジェクトを初期化する

  1. デバイス オブジェクトとコンポジション ターゲット オブジェクトを作成します。
  2. ビジュアルを作成し、その内容を設定して、ビジュアル ツリーに追加します。

詳細については、「 DirectComposition を初期化する方法」を参照してください。

手順 2: 変換グループ配列を作成する

IDCompositionTransform *pTransforms[3];

手順 3: 変換オブジェクトを作成し、そのプロパティを設定し、それらを変換グループ配列に追加する

  1. IDCompositionDevice::CreateRotateTransform::CreateScaleTransform、および ::CreateTranslateTransform メソッドを使用して、変換オブジェクトを作成します。
  2. IDCompositionRotateTransformIDCompositionScaleTransform、および IDCompositionTranslateTransform インターフェイスのメンバー関数を使用して、変換のプロパティを設定します。
  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;
}

手順 4: 変換グループ オブジェクトを作成する

IDCompositionDevice::CreateTransformGroup メソッドを呼び出して、変換グループ オブジェクトを作成します。

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

手順 5: 変換グループ オブジェクトをビジュアルに適用する

IDCompositionVisual::SetTransform メソッドを使用して、ビジュアルの Transform プロパティを変換グループ オブジェクトに関連付けます。

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

手順 6: コンポジションをコミットする

IDCompositionDevice::Commit メソッドを呼び出して、ビジュアルの更新を DirectComposition にコミットして処理します。 2D 変換のグループを適用した結果がターゲット ウィンドウに表示されます。

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

手順 7: DirectComposition オブジェクトを解放する

必要なくなった 2D 変換オブジェクトのグループは、必ず解放してください。 次の例では、変換オブジェクトを解放するために、アプリケーション定義 の SafeRelease マクロを呼び出します。

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

また、アプリケーションが終了する前に、デバイス オブジェクト、コンポジション ターゲット オブジェクト、ビジュアルも解放してください。

コード例全体

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

変換