0

Hi I am developing a project using C#/WPF and Windows.UI.Composition for creating acrylic effect in WPF.

Here is how my project looks like currently

Sample image

Current Status

Usually rendering any Windows.UI.Composition visual in WPF causes airspace issue, to overcome this I created separate window to render acrylic and another window to render WPF content and overlapped one over the other. Since using SetWindowPos() is slow and causes flicker, I created a Layered Transparent Window of full width and height, and clips the Windows.UI.Composition.Visual to the size of the window which have the WPF Content.

Current Issue

But when I maximize, restore or minimize a window, the animation is lost and so I tried creating custom maximize, minimize and restore animations using Windows.UI.Composition but the Custom animation is never same as the original one.(I mean it is not syncing with each other). The GetWindowRect() function only gives the maximized window RECT not the RECT values during the animation.

So Is there any way to get the RECT value during window maximize, minimize and Restore animations so I can apply it to the Clipping Function?

Code

This is the Code I used to animate the visual containing acrylic:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Composition;
using Windows.UI.Composition.Core;

namespace FluentCompositor.Core
{
    public class VisualAnimator
    {
        #region AnimationTypes
        public const int ANIMATION_MAXIMIZE = 0;
        public const int ANIMATION_RESTORE = 1;
        public const int ANIMATION_MINIMIZE = 2;
        #endregion

        #region MaximizeAnimation
        Vector3KeyFrameAnimation maximizeAnimation;
        #endregion

        Visual animationVisual;
        CompositorController compositionController;
        Compositor compositor;

        public VisualAnimator(Visual visual,CompositorController controller,IntPtr hwnd)
        {
            animationVisual = visual;
            compositionController = controller;
            compositor = controller.Compositor;
            maximizeAnimation = compositor.CreateVector3KeyFrameAnimation();
        }

        public void Animate(int animatonType)
        {
            switch(animatonType)
            {
                case ANIMATION_MAXIMIZE:
                    AnimateMaximize();
                    break;
            }
            compositionController.Commit();
        }

        private void AnimateMaximize()
        {
            var easeOut = compositor.CreateCubicBezierEasingFunction(new Vector2(.215f, 0.610f), new Vector2(0.355f, 1.000f));
            animationVisual.Scale = new Vector3(.945f, .945f, .945f);
            Vector3 v3 = new Vector3(animationVisual.Size / 2, 0);
            
            animationVisual.CenterPoint = v3 + new Vector3(280, 0, 0);
            maximizeAnimation.InsertKeyFrame(0f, new Vector3(.945f, .945f, .945f), easeOut);
            maximizeAnimation.InsertKeyFrame(1f, new Vector3(1.0f, 1.0f, 1.0f), easeOut);
            maximizeAnimation.Duration = TimeSpan.FromMilliseconds(5000);
            maximizeAnimation.Direction = AnimationDirection.Normal;
            animationVisual.StartAnimation("Scale", maximizeAnimation);
        }
    }
}

In the code I mentioned above, I used scale animation to animate visual like Window Maximize animation. This method use scaling instead of clipping.

The clipping function code:

private void ClipCompositionRoot(int x,int y,int cx,int cy,bool commit)
{
    if (clipRect != null)
    {
        clipRect.Offset = new Vector2(x, y);
        clipRect.Size = new Vector2(cx, cy);
        if(commit)
        {
            compositionController.Commit();
        }
    }
}

So if I could get the Animation RECT values I could pass it to this function to clip my acrylic visual along with the window Animation.

Will it be possible using any DWM Private Functions or something similar?

jason.kaisersmith
  • 8,712
  • 3
  • 29
  • 51
trickymind
  • 557
  • 5
  • 21

0 Answers0