Поделиться через


Применение двухd-преобразований

Примечание

Для приложений на Windows 10 рекомендуется использовать API Windows.UI.Composition вместо DirectComposition. Дополнительные сведения см. в статье Модернизация классического приложения с помощью визуального слоя.

В этом разделе показано, как применить двухD-преобразования к визуальному элементу с помощью Microsoft DirectComposition. В примере в этом разделе применяется группа преобразований, которые:

  1. Повернуть визуальный элемент на 180 градусов.
  2. Масштаб визуального элемента в три раза больше, чем его первоначальный размер.
  3. Переведите (переместите) визуальный элемент на 150 пикселей справа от его исходного положения.

На следующих снимках экрана показан визуальный элемент до и после применения двухмерных преобразований.

результат применения группы двухd-преобразований к визуальному элементу

Это важно знать

Технологии

Предварительные требования

  • C/C++
  • Microsoft Win32
  • Модель COM

Инструкции

Шаг 1. Инициализация объектов DirectComposition

  1. Создайте объект устройства и целевой объект композиции.
  2. Создайте визуальный элемент, задайте его содержимое и добавьте его в визуальное дерево.

Дополнительные сведения см. в разделе Как инициализировать DirectComposition.

Шаг 2. Создание массива группы преобразования

IDCompositionTransform *pTransforms[3];

Шаг 3. Создание объектов преобразования, установка их свойств и добавление их в массив группы преобразования

  1. Используйте методы IDCompositionDevice::CreateRotateTransform, ::CreateScaleTransform и ::CreateTranslateTransform для создания объектов преобразования.
  2. Используйте функции-члены интерфейсов IDCompositionRotateTransform, IDCompositionScaleTransform и 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 для обработки. Результат применения группы двухD-преобразований появится в целевом окне.

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

Шаг 7. Освобождение объектов DirectComposition

Не забудьте освободить группу двухd-объектов преобразования, если они больше не нужны. В следующем примере вызывается определенный приложением макрос 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;
}

Преобразования