Применение двухd-преобразований
Примечание
Для приложений на Windows 10 рекомендуется использовать API Windows.UI.Composition вместо DirectComposition. Дополнительные сведения см. в статье Модернизация классического приложения с помощью визуального слоя.
В этом разделе показано, как применить двухD-преобразования к визуальному элементу с помощью Microsoft DirectComposition. В примере в этом разделе применяется группа преобразований, которые:
- Повернуть визуальный элемент на 180 градусов.
- Масштаб визуального элемента в три раза больше, чем его первоначальный размер.
- Переведите (переместите) визуальный элемент на 150 пикселей справа от его исходного положения.
На следующих снимках экрана показан визуальный элемент до и после применения двухмерных преобразований.
Это важно знать
Технологии
Предварительные требования
- C/C++
- Microsoft Win32
- Модель COM
Инструкции
Шаг 1. Инициализация объектов DirectComposition
- Создайте объект устройства и целевой объект композиции.
- Создайте визуальный элемент, задайте его содержимое и добавьте его в визуальное дерево.
Дополнительные сведения см. в разделе Как инициализировать DirectComposition.
Шаг 2. Создание массива группы преобразования
IDCompositionTransform *pTransforms[3];
Шаг 3. Создание объектов преобразования, установка их свойств и добавление их в массив группы преобразования
- Используйте методы IDCompositionDevice::CreateRotateTransform, ::CreateScaleTransform и ::CreateTranslateTransform для создания объектов преобразования.
- Используйте функции-члены интерфейсов IDCompositionRotateTransform, IDCompositionScaleTransform и IDCompositionTranslateTransform , чтобы задать свойства преобразований.
- Скопируйте указатели интерфейса преобразования на массив группы преобразования.
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;
}
Связанные темы