görsel katmanını Windows Forms ile kullanma

Windows Forms uygulamalarınızda Windows Çalışma Zamanı Oluşturma API'lerini (Visual katman olarak da adlandırılır) kullanarak Windows kullanıcılar için modern deneyimler oluşturabilirsiniz.

Bu öğreticinin tam kodu GitHub'da mevcuttur: Windows Forms HelloComposition örneği.

Prerequisites

UWP barındırma API'sinin bu önkoşulları vardır.

Windows Forms'da Oluşturma API'lerini kullanma

Bu öğreticide basit bir Windows Forms kullanıcı arabirimi oluşturur ve ona animasyonlu Bileşim öğeleri eklersiniz. Hem Windows Forms hem de Oluşturma bileşenleri basit tutulur, ancak bileşenlerin karmaşıklığından bağımsız olarak gösterilen birlikte çalışma kodu aynıdır. Tamamlanmış uygulama şöyle görünür.

Çalışan uygulama kullanıcı arabirimi

Windows Forms projesi oluşturma

İlk adım, bir uygulama tanımı ve kullanıcı arabirimi için ana formu içeren Windows Forms uygulama projesini oluşturmaktır.

Visual C# uygulamasında HelloComposition0 adlı yeni bir Windows Forms Uygulaması projesi oluşturmak için:

  1. Visual Studio'yu açın ve Dosya>Yeni>Projeöğesini seçin.
    Yeni Proje iletişim kutusu açılır.
  2. Yüklü kategorisinin altında Visual C# düğümünü genişletin ve Windows Masaüstü öğesini seçin.
  3. Windows Forms App (.NET Framework) şablonunu seçin.
  4. HelloComposition, Framework .NET Framework 4.7.2 adını girin ve OK öğesine tıklayın.

Visual Studio projeyi oluşturur ve Form1.cs adlı varsayılan uygulama penceresi için tasarımcıyı açar.

Projeyi Windows Çalışma Zamanı API'lerini kullanacak şekilde yapılandırma

Windows Forms uygulamanızda Windows Çalışma Zamanı (WinRT) API'lerini kullanmak için Visual Studio projenizi Windows Çalışma Zamanı erişecek şekilde yapılandırmanız gerekir. Buna ek olarak, vektörler Oluşturma API'leri tarafından yaygın olarak kullanılır, bu nedenle vektörleri kullanmak için gereken başvuruları eklemeniz gerekir.

NuGet paketleri, bu gereksinimlerin her ikisini de karşılamak için kullanılabilir. Projenize gerekli başvuruları eklemek için bu paketlerin en son sürümlerini yükleyin.

Note

Projenizi yapılandırmak için NuGet paketlerini kullanmanızı öneririz ancak gerekli başvuruları el ile ekleyebilirsiniz. Daha fazla bilgi için bkz. Windows için masaüstü uygulamanızı kullanma. Aşağıdaki tabloda referans eklemeniz gereken dosyalar gösterilmektedir.

File Konum
System.Runtime.WindowsRuntime C:\Windows\Microsoft.NET\Framework\v4.0.30319
Windows.Foundation.UniversalApiContract.winmd C:\Program Files (x86)\Windows Kits\10\References<sdk version>\Windows.Foundation.UniversalApiContract<version>
Windows.Foundation.FoundationContract.winmd C:\Program Files (x86)\Windows Kits\10\References<sdk version>\Windows. Foundation.FoundationContract<version>
System.Numerics.Vectors.dll C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Numerics.Vectors\v4.0_4.0.0.0__b03f5f7f11d50a3a
System.Numerics.dll C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.7.2

Birlikte çalışabilirliği yönetmek için özel bir denetim oluşturun

Görsel katmanıyla oluşturduğunuz içeriği barındırmak için Denetim'den türetilen özel bir denetim oluşturursunuz. Bu denetim, görsel katmanı içeriğinizin kapsayıcısını oluşturmak için ihtiyacınız olan pencere Tutamacına erişmenizi sağlar.

Burası, Oluşturma API'lerini barındırmak için yapılandırmanın çoğunu yaptığınız yerdir. Bu denetimde, oluşturma API'lerini Windows Forms uygulamanıza getirmek için Platform Çağırma Hizmetleri (PInvoke) ve COM Birlikte Çalışma kullanırsınız. PInvoke ve COM Birlikte Çalışma hakkında daha fazla bilgi için bkz. Yönetilmeyen kodla birlikte çalışma.

Tavsiye

Gerekirse, öğreticiyi takip ederken tüm kodun doğru yerlerde olduğundan emin olmak için, öğreticinin sonundaki tüm kodu kontrol edin.

  1. Projenize Control'ten türetilen yeni bir özel denetim dosyası ekleyin.

    • Çözüm Gezginipenceresinde, HelloComposition projesine sağ tıklayın.
    • Bağlam menüsündeYeni Öğe Ekle...'> seçin.
    • Yeni Öğe Ekle iletişim kutusunda Özel Denetim'i seçin.
    • Denetim CompositionHost.cs adlandırın ve Ekle'ye tıklayın. CompositionHost.cs Tasarım görünümünde açılır.
  2. CompositionHost.cs için kod görünümüne geçin ve sınıfına aşağıdaki kodu ekleyin.

    // Add
    // using Windows.UI.Composition;
    
    IntPtr hwndHost;
    object dispatcherQueue;
    protected ContainerVisual containerVisual;
    protected Compositor compositor;
    
    private ICompositionTarget compositionTarget;
    
    public Visual Child
    {
        set
        {
            if (compositor == null)
            {
                InitComposition(hwndHost);
            }
            compositionTarget.Root = value;
        }
    }
    
  3. Oluşturucuya kod ekleyin.

    Oluşturucuda InitializeCoreDispatcher ve InitComposition yöntemlerini çağırırsınız. Bu yöntemleri sonraki adımlarda oluşturacaksınız.

    public CompositionHost()
    {
        InitializeComponent();
    
        // Get the window handle.
        hwndHost = Handle;
    
        // Create dispatcher queue.
        dispatcherQueue = InitializeCoreDispatcher();
    
        // Build Composition tree of content.
        InitComposition(hwndHost);
    }
    
  4. CoreDispatcher ile bir iş parçacığını başlatın. Çekirdek dağıtıcı, WinRT API'leri için pencere iletilerini işlemek ve olayları göndermekle sorumludur. Yeni Compositor örnekleri CoreDispatcher içeren bir iş parçacığında oluşturulmalıdır.

    • InitializeCoreDispatcher adlı bir yöntem oluşturun ve dağıtıcı kuyruğunun ayarlanması için kod ekleyin.
    // Add
    // using System.Runtime.InteropServices;
    
    private object InitializeCoreDispatcher()
    {
        DispatcherQueueOptions options = new DispatcherQueueOptions();
        options.apartmentType = DISPATCHERQUEUE_THREAD_APARTMENTTYPE.DQTAT_COM_STA;
        options.threadType = DISPATCHERQUEUE_THREAD_TYPE.DQTYPE_THREAD_CURRENT;
        options.dwSize = Marshal.SizeOf(typeof(DispatcherQueueOptions));
    
        object queue = null;
        CreateDispatcherQueueController(options, out queue);
        return queue;
    }
    
    • Dağıtıcı kuyruğu bir PInvoke bildirimi gerektirir. Bu bildirimi sınıfı için kodun sonuna yerleştirin. (Sınıf kodunu düzenli tutmak için bu kodu bir bölgeye yerleştiririz.)
    #region PInvoke declarations
    
    //typedef enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE
    //{
    //    DQTAT_COM_NONE,
    //    DQTAT_COM_ASTA,
    //    DQTAT_COM_STA
    //};
    internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE
    {
        DQTAT_COM_NONE = 0,
        DQTAT_COM_ASTA = 1,
        DQTAT_COM_STA = 2
    };
    
    //typedef enum DISPATCHERQUEUE_THREAD_TYPE
    //{
    //    DQTYPE_THREAD_DEDICATED,
    //    DQTYPE_THREAD_CURRENT
    //};
    internal enum DISPATCHERQUEUE_THREAD_TYPE
    {
        DQTYPE_THREAD_DEDICATED = 1,
        DQTYPE_THREAD_CURRENT = 2,
    };
    
    //struct DispatcherQueueOptions
    //{
    //    DWORD dwSize;
    //    DISPATCHERQUEUE_THREAD_TYPE threadType;
    //    DISPATCHERQUEUE_THREAD_APARTMENTTYPE apartmentType;
    //};
    [StructLayout(LayoutKind.Sequential)]
    internal struct DispatcherQueueOptions
    {
        public int dwSize;
    
        [MarshalAs(UnmanagedType.I4)]
        public DISPATCHERQUEUE_THREAD_TYPE threadType;
    
        [MarshalAs(UnmanagedType.I4)]
        public DISPATCHERQUEUE_THREAD_APARTMENTTYPE apartmentType;
    };
    
    //HRESULT CreateDispatcherQueueController(
    //  DispatcherQueueOptions options,
    //  ABI::Windows::System::IDispatcherQueueController** dispatcherQueueController
    //);
    [DllImport("coremessaging.dll", EntryPoint = "CreateDispatcherQueueController", CharSet = CharSet.Unicode)]
    internal static extern IntPtr CreateDispatcherQueueController(DispatcherQueueOptions options,
                                            [MarshalAs(UnmanagedType.IUnknown)]
                                            out object dispatcherQueueController);
    
    #endregion PInvoke declarations
    

    Artık dağıtıcı kuyruğunuz hazır ve Oluşturma içeriğini oluşturmaya başlayabilirsiniz.

  5. Compositor'ı başlatın. Compositor, Windows.UI.Composition ad alanında, görsel katman, efekt sistemi ve animasyon sistemini kapsayan çeşitli türler oluşturan bir fabrikadır. Compositor sınıfı, fabrikadan oluşturulan nesnelerin yaşam ömrünü de yönetir.

    private void InitComposition(IntPtr hwndHost)
    {
        ICompositorDesktopInterop interop;
    
        compositor = new Compositor();
        object iunknown = compositor as object;
        interop = (ICompositorDesktopInterop)iunknown;
        IntPtr raw;
        interop.CreateDesktopWindowTarget(hwndHost, true, out raw);
    
        object rawObject = Marshal.GetObjectForIUnknown(raw);
        compositionTarget = (ICompositionTarget)rawObject;
    
        if (raw == null) { throw new Exception("QI Failed"); }
    
        containerVisual = compositor.CreateContainerVisual();
        Child = containerVisual;
    }
    
    • ICompositorDesktopInterop ve ICompositionTarget , COM içeri aktarmaları gerektirir. Bu kodu CompositionHost sınıfından sonra ancak ad alanı bildiriminin içine yerleştirin.
    #region COM Interop
    
    /*
    #undef INTERFACE
    #define INTERFACE ICompositorDesktopInterop
        DECLARE_INTERFACE_IID_(ICompositorDesktopInterop, IUnknown, "29E691FA-4567-4DCA-B319-D0F207EB6807")
        {
            IFACEMETHOD(CreateDesktopWindowTarget)(
                _In_ HWND hwndTarget,
                _In_ BOOL isTopmost,
                _COM_Outptr_ IDesktopWindowTarget * *result
                ) PURE;
        };
    */
    [ComImport]
    [Guid("29E691FA-4567-4DCA-B319-D0F207EB6807")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface ICompositorDesktopInterop
    {
        void CreateDesktopWindowTarget(IntPtr hwndTarget, bool isTopmost, out IntPtr test);
    }
    
    //[contract(Windows.Foundation.UniversalApiContract, 2.0)]
    //[exclusiveto(Windows.UI.Composition.CompositionTarget)]
    //[uuid(A1BEA8BA - D726 - 4663 - 8129 - 6B5E7927FFA6)]
    //interface ICompositionTarget : IInspectable
    //{
    //    [propget] HRESULT Root([out] [retval] Windows.UI.Composition.Visual** value);
    //    [propput] HRESULT Root([in] Windows.UI.Composition.Visual* value);
    //}
    
    [ComImport]
    [Guid("A1BEA8BA-D726-4663-8129-6B5E7927FFA6")]
    [InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
    public interface ICompositionTarget
    {
        Windows.UI.Composition.Visual Root
        {
            get;
            set;
        }
    }
    
    #endregion COM Interop
    

Oluşturma öğelerini barındırmak için özel denetim oluşturma

Oluşturma öğelerinizi oluşturan ve yöneten kodu CompositionHost'tan türetilen ayrı bir denetime yerleştirmek iyi bir fikirdir. Bu, CompositionHost sınıfında oluşturduğunuz birlikte çalışma kodunu yeniden kullanılabilir durumda tutar.

Burada, CompositionHost'tan türetilen özel bir denetim oluşturursunuz. Bu denetim, formunuza ekleyebilmeniz için Visual Studio araç kutusuna eklenir.

  1. Projenize CompositionHost'tan türetilen yeni bir özel denetim dosyası ekleyin.

    • Çözüm Gezginipenceresinde, HelloComposition projesine sağ tıklayın.
    • Bağlam menüsündeYeni Öğe Ekle...'> seçin.
    • Yeni Öğe Ekle iletişim kutusunda Özel Denetim'i seçin.
    • Denetim CompositionHostControl.cs adlandırın ve Ekle'ye tıklayın. CompositionHostControl.cs Tasarım görünümünde açılır.
  2. CompositionHostControl.cs tasarım görünümünün Özellikler bölmesinde BackColor özelliğini ControlLight olarak ayarlayın.

    Arka plan rengini ayarlamak isteğe bağlıdır. Form arka planında özel denetiminizi görebilmeniz için bunu burada yaparız.

  3. CompositionHostControl.cs için kod görünümüne geçin ve sınıf bildirimini CompositionHost'tan türetecek şekilde güncelleştirin.

    class CompositionHostControl : CompositionHost
    
  4. Temel oluşturucuyu çağırmak için oluşturucuyu güncelleştirin.

    public CompositionHostControl() : base()
    {
    
    }
    

Oluşturma öğeleri ekleme

Altyapı yerinde olduğunda, artık uygulama kullanıcı arabirimine Composition içeriği ekleyebilirsiniz.

Bu örnekte, basit bir SpriteVisual oluşturan ve bunlara animasyon uygulayan CompositionHostControl sınıfına kod eklersiniz.

  1. Bir bileşim öğesi ekleyin.

    CompositionHostControl.cs'de, aşağıdaki yöntemleri CompositionHostControl sınıfına ekleyin.

    // Add
    // using Windows.UI.Composition;
    
    public void AddElement(float size, float offsetX, float offsetY)
    {
        var visual = compositor.CreateSpriteVisual();
        visual.Size = new Vector2(size, size); // Requires references
        visual.Brush = compositor.CreateColorBrush(GetRandomColor());
        visual.Offset = new Vector3(offsetX, offsetY, 0);
        containerVisual.Children.InsertAtTop(visual);
    
        AnimateSquare(visual, 3);
    }
    
    private void AnimateSquare(SpriteVisual visual, int delay)
    {
        float offsetX = (float)(visual.Offset.X);
        Vector3KeyFrameAnimation animation = compositor.CreateVector3KeyFrameAnimation();
        float bottom = Height - visual.Size.Y;
        animation.InsertKeyFrame(1f, new Vector3(offsetX, bottom, 0f));
        animation.Duration = TimeSpan.FromSeconds(2);
        animation.DelayTime = TimeSpan.FromSeconds(delay);
        visual.StartAnimation("Offset", animation);
    }
    
    private Windows.UI.Color GetRandomColor()
    {
        Random random = new Random();
        byte r = (byte)random.Next(0, 255);
        byte g = (byte)random.Next(0, 255);
        byte b = (byte)random.Next(0, 255);
        return Windows.UI.Color.FromArgb(255, r, g, b);
    }
    

Denetimi formunuza ekleme

Artık Oluşturma içeriğini barındırmak için özel bir denetiminiz olduğuna göre, bunu uygulama kullanıcı arabirimine ekleyebilirsiniz. Burada, önceki adımda oluşturduğunuz CompositionHostControl örneğini eklersiniz. CompositionHostControl otomatik olarak Visual Studio araç kutusuna project name Components altında eklenir.

  1. Form1.CS tasarım görünümünde kullanıcı arabirimine bir Düğme ekleyin.

    • Araç kutusundan Form1'e Bir Düğme sürükleyin. Formun sol üst köşesine yerleştirin. (Denetimlerin yerleşimini denetlemek için öğreticinin başındaki resme bakın.)
    • Özellikler bölmesinde Text özelliğinidüğme1 yerine Oluşturma öğesi ekle olarak değiştirin.
    • Düğmeyi tüm metnin gösterebilmesi için yeniden boyutlandırın.

    (Daha fazla bilgi için bkz. Nasıl Yapılır: Windows Forms'a Denetim Ekleme.)

  2. Kullanıcı arabirimine bir CompositionHostControl ekleyin.

    • Bir CompositionHostControl'i araç kutusundan Form1'e sürükleyin. Düğmenin sağındaki yere yerleştirin.
    • CompositionHost'u formun geri kalanını dolduracak şekilde yeniden boyutlandırın.
  3. Düğme tıklama olayını işle.

    • Özellikler bölmesinde yıldırıma tıklayarak Olaylar görünümüne geçin.
    • Olaylar listesinde Click olayını seçin, Button_Click yazın ve Enter tuşuna basın.
    • Bu kod Form1.cs'ye eklenmiştir:
    private void Button_Click(object sender, EventArgs e)
    {
    
    }
    
  4. Yeni öğeler oluşturmak için düğme tıklama işleyicisine kod ekleyin.

    • Form1.cs'da, daha önce oluşturduğunuz Button_Click olay işleyicisine kod ekleyin. Bu kod, rastgele oluşturulan boyut ve uzaklık ile yeni bir öğe oluşturmak için CompositionHostControl1.AddElement öğesini çağırır. (CompositionHostControl örneği, forma sürüklediğinizde otomatik olarak compositionHostControl1 olarak adlandırılmıştır.)
    // Add
    // using System;
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Random random = new Random();
        float size = random.Next(50, 150);
        float offsetX = random.Next(0, (int)(compositionHostControl1.Width - size));
        float offsetY = random.Next(0, (int)(compositionHostControl1.Height/2 - size));
        compositionHostControl1.AddElement(size, offsetX, offsetY);
    }
    

Artık Windows Forms uygulamanızı derleyebilir ve çalıştırabilirsiniz. Düğmeye tıkladığınızda, kullanıcı arabirimine eklenmiş animasyonlu kareler görmeniz gerekir.

Sonraki Adımlar

Aynı altyapıyı oluşturan daha eksiksiz bir örnek için GitHub Windows Forms Görsel katmanı tümleştirme örneği bakın.

Ek kaynaklar

Kodu tamamlama

İşte bu eğitimin tam kodu.

Form1.cs

using System;
using System.Windows.Forms;

namespace HelloComposition
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, EventArgs e)
        {
            Random random = new Random();
            float size = random.Next(50, 150);
            float offsetX = random.Next(0, (int)(compositionHostControl1.Width - size));
            float offsetY = random.Next(0, (int)(compositionHostControl1.Height/2 - size));
            compositionHostControl1.AddElement(size, offsetX, offsetY);
        }
    }
}

CompositionHostControl.cs

using System;
using System.Numerics;
using Windows.UI.Composition;

namespace HelloComposition
{
    class CompositionHostControl : CompositionHost
    {
        public CompositionHostControl() : base()
        {

        }

        public void AddElement(float size, float offsetX, float offsetY)
        {
            var visual = compositor.CreateSpriteVisual();
            visual.Size = new Vector2(size, size); // Requires references
            visual.Brush = compositor.CreateColorBrush(GetRandomColor());
            visual.Offset = new Vector3(offsetX, offsetY, 0);
            containerVisual.Children.InsertAtTop(visual);

            AnimateSquare(visual, 3);
        }

        private void AnimateSquare(SpriteVisual visual, int delay)
        {
            float offsetX = (float)(visual.Offset.X);
            Vector3KeyFrameAnimation animation = compositor.CreateVector3KeyFrameAnimation();
            float bottom = Height - visual.Size.Y;
            animation.InsertKeyFrame(1f, new Vector3(offsetX, bottom, 0f));
            animation.Duration = TimeSpan.FromSeconds(2);
            animation.DelayTime = TimeSpan.FromSeconds(delay);
            visual.StartAnimation("Offset", animation);
        }

        private Windows.UI.Color GetRandomColor()
        {
            Random random = new Random();
            byte r = (byte)random.Next(0, 255);
            byte g = (byte)random.Next(0, 255);
            byte b = (byte)random.Next(0, 255);
            return Windows.UI.Color.FromArgb(255, r, g, b);
        }
    }
}

CompositionHost.cs

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Windows.UI.Composition;

namespace HelloComposition
{
    public partial class CompositionHost : Control
    {
        IntPtr hwndHost;
        object dispatcherQueue;
        protected ContainerVisual containerVisual;
        protected Compositor compositor;
        private ICompositionTarget compositionTarget;

        public Visual Child
        {
            set
            {
                if (compositor == null)
                {
                    InitComposition(hwndHost);
                }
                compositionTarget.Root = value;
            }
        }

        public CompositionHost()
        {
            // Get the window handle.
            hwndHost = Handle;

            // Create dispatcher queue.
            dispatcherQueue = InitializeCoreDispatcher();

            // Build Composition tree of content.
            InitComposition(hwndHost);
        }

        private object InitializeCoreDispatcher()
        {
            DispatcherQueueOptions options = new DispatcherQueueOptions();
            options.apartmentType = DISPATCHERQUEUE_THREAD_APARTMENTTYPE.DQTAT_COM_STA;
            options.threadType = DISPATCHERQUEUE_THREAD_TYPE.DQTYPE_THREAD_CURRENT;
            options.dwSize = Marshal.SizeOf(typeof(DispatcherQueueOptions));

            object queue = null;
            CreateDispatcherQueueController(options, out queue);
            return queue;
        }

        private void InitComposition(IntPtr hwndHost)
        {
            ICompositorDesktopInterop interop;

            compositor = new Compositor();
            object iunknown = compositor as object;
            interop = (ICompositorDesktopInterop)iunknown;
            IntPtr raw;
            interop.CreateDesktopWindowTarget(hwndHost, true, out raw);

            object rawObject = Marshal.GetObjectForIUnknown(raw);
            compositionTarget = (ICompositionTarget)rawObject;

            if (raw == null) { throw new Exception("QI Failed"); }

            containerVisual = compositor.CreateContainerVisual();
            Child = containerVisual;
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);
        }

        #region PInvoke declarations

        //typedef enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE
        //{
        //    DQTAT_COM_NONE,
        //    DQTAT_COM_ASTA,
        //    DQTAT_COM_STA
        //};
        internal enum DISPATCHERQUEUE_THREAD_APARTMENTTYPE
        {
            DQTAT_COM_NONE = 0,
            DQTAT_COM_ASTA = 1,
            DQTAT_COM_STA = 2
        };

        //typedef enum DISPATCHERQUEUE_THREAD_TYPE
        //{
        //    DQTYPE_THREAD_DEDICATED,
        //    DQTYPE_THREAD_CURRENT
        //};
        internal enum DISPATCHERQUEUE_THREAD_TYPE
        {
            DQTYPE_THREAD_DEDICATED = 1,
            DQTYPE_THREAD_CURRENT = 2,
        };

        //struct DispatcherQueueOptions
        //{
        //    DWORD dwSize;
        //    DISPATCHERQUEUE_THREAD_TYPE threadType;
        //    DISPATCHERQUEUE_THREAD_APARTMENTTYPE apartmentType;
        //};
        [StructLayout(LayoutKind.Sequential)]
        internal struct DispatcherQueueOptions
        {
            public int dwSize;

            [MarshalAs(UnmanagedType.I4)]
            public DISPATCHERQUEUE_THREAD_TYPE threadType;

            [MarshalAs(UnmanagedType.I4)]
            public DISPATCHERQUEUE_THREAD_APARTMENTTYPE apartmentType;
        };

        //HRESULT CreateDispatcherQueueController(
        //  DispatcherQueueOptions options,
        //  ABI::Windows::System::IDispatcherQueueController** dispatcherQueueController
        //);
        [DllImport("coremessaging.dll", EntryPoint = "CreateDispatcherQueueController", CharSet = CharSet.Unicode)]
        internal static extern IntPtr CreateDispatcherQueueController(DispatcherQueueOptions options,
                                                 [MarshalAs(UnmanagedType.IUnknown)]
                                        out object dispatcherQueueController);

        #endregion PInvoke declarations
    }

    #region COM Interop

    /*
    #undef INTERFACE
    #define INTERFACE ICompositorDesktopInterop
        DECLARE_INTERFACE_IID_(ICompositorDesktopInterop, IUnknown, "29E691FA-4567-4DCA-B319-D0F207EB6807")
        {
            IFACEMETHOD(CreateDesktopWindowTarget)(
                _In_ HWND hwndTarget,
                _In_ BOOL isTopmost,
                _COM_Outptr_ IDesktopWindowTarget * *result
                ) PURE;
        };
    */
    [ComImport]
    [Guid("29E691FA-4567-4DCA-B319-D0F207EB6807")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface ICompositorDesktopInterop
    {
        void CreateDesktopWindowTarget(IntPtr hwndTarget, bool isTopmost, out IntPtr test);
    }

    //[contract(Windows.Foundation.UniversalApiContract, 2.0)]
    //[exclusiveto(Windows.UI.Composition.CompositionTarget)]
    //[uuid(A1BEA8BA - D726 - 4663 - 8129 - 6B5E7927FFA6)]
    //interface ICompositionTarget : IInspectable
    //{
    //    [propget] HRESULT Root([out] [retval] Windows.UI.Composition.Visual** value);
    //    [propput] HRESULT Root([in] Windows.UI.Composition.Visual* value);
    //}

    [ComImport]
    [Guid("A1BEA8BA-D726-4663-8129-6B5E7927FFA6")]
    [InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
    public interface ICompositionTarget
    {
        Windows.UI.Composition.Visual Root
        {
            get;
            set;
        }
    }
    #endregion COM Interop
}