InteropCompositor (and CoreDispatcher)

InteropCompositor? What is this?
Remember Windows.UI.Composition.Compositor in UWP apps? That’s InteropCompositor.

Ok enough, so what is different from a normal “Compositor”? You can cast that into IDCompositionDesktopDevice. And create InteropVisuals (IDCompositionVisual that can be castable into Windows.UI.Composition.Visual).

How do I create an InteropCompositor?

Before we start, look at this (Win32) Composition sample: Windows.UI.Composition-Win32-Samples. You can see that you must create a DispatcherQueueController and then you can create a Compositor. Now try to cast that Compositor into IDCompositionDesktopDevice. It will fail because it is just a simple Compositor.

On the other hand, when you are creating an InteropCompositor, dcomp will make it IDComposition*Device castable.

The base

For this tutorial we will modify a pre-existing code created in the previous article (DWM Thumbnails. But with IDCompositionVisual.) to make it use Windows.UI.Composition.* instead.

Download the code here: DWM Thumbnail/VirtualDesktop IDCompositionVisual example (github.com)

Set up your project to use:

  • Language standard C++17 (or newer)
  • C++/WinRT (install it via nuget)

Now, compile it before continuing, it should build successfully, and C++/WinRT should have had generated winrt projection headers without issues.

Add these include directives:

And using namespaces

Nice. Now let’s add InteropCompositor interfaces.

HwndTarget is used to set a composition visual as compositor visual root, and this is for build 14393 and 15063. For 16299 and newer we will use CompositionTarget instead.

IInteropCompositorFactoryPartner is the interface of our interest as this will let us create InteropCompositor.
Let’s read the parameters: renderingDevice is basically ID2D1Device, callback is your made (with winrt::make) IInteropCompositorPartnerCallback implemented interface and it can be null, iid is either IInteropCompositorPartner, Windows.UI.Composition.Compositor or IDComposition*Device* guid and instance is your interface.

Now add a ComPtr to ID2D1Device

And replace this: (in CreateDevice function)

with this:

Because we need a D2DDevice to create an InteropCompositor.

Now, let’s add a parameter to DemoCreateWindowThumbnail and DemoCreateMultiWindowThumbnail.

void DemoCreateWindowThumbnail(HWND myWnd, IDCompositionVisual2** ppWindowVisual, SIZE* thumbSize)
void DemoCreateMultiWindowThumbnail(HWND myWnd, IDCompositionVisual2** ppVirtualDesktopVisual, SIZE* thumbSize)

and assign the content on both functions:

As for this demo we want to know the size of the DCompositionVisual to be able to make animation on its center point (size / 2)

And now let’s make the function to create our InteropCompositor!

This function will create a Windows.UI.Composition.Visual container to hold our IDCompositionVisual visual

And finally, the last function to create an animation using Composition.

Let’s glue it together in our main function.

Compile and run! You should have a zoom in-out animation!

Bonus – CoreDispatcher

You can create a CoreDispatcher if you need to create a DispatcherQueue (16299+) and to process events (instead of the classic message loop).

How? Add this interface:

And make this helper function:

In Main function, create a CoreDispatcher using GetOrCreateCoreDispatcher() and replace the message loop with:

You should end up something like this:

Notes:

You can’t cast Windows.UI.Composition.Visual created from compositor.Create*Visual to IDCompositionVisual.

You can cast IDCompositionVisual to Windows.UI.Composition.Visual that are created from IDCompositionDesktopDevice.CreateVisual

Why? IDCompositionDesktopDevice.CreateVisual is covered by InteropCompositor API and that produces an InteropVisual. On the other hand, compositor.Create*Visual is covered only by Compositor API and that produces a simple Visual.

Compatibility:

This code is tested and confirmed to work on build 14393 and later
Builds before 14393 won’t work at all.


Full demo code: DWM Thumbnail/VirtualDesktop USING Windows.UI.Composition (github.com)

1 thought on “InteropCompositor (and CoreDispatcher)”

  1. Hey man, really appreciate these kind of blog posts/tutorials. Seems you’re about the only one discussing these things in this detail.

    Many thanks and keep it up!

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Enable Notifications OK No thanks