Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Interfejsów API kompozycji Windows Runtime (nazywanych również warstwą wizualną ) można używać w aplikacjach Windows Forms, aby tworzyć nowoczesne doświadczenia, które oferują doskonałe wrażenia użytkownikom systemu Windows.
Kompletny kod do tego poradnika jest dostępny na GitHub: przykład HelloComposition Windows Forms.
Wymagania wstępne
Interfejs API hostingu platformy UWP ma te wymagania wstępne.
- Zakładamy, że masz pewną znajomość tworzenia aplikacji przy użyciu formularzy systemu Windows i platformy UWP. Aby uzyskać więcej informacji, zobacz:
- .NET Framework 4.7.2 lub nowszy
- Windows 10 w wersji 1803 lub nowszej
- Windows 10 SDK 17134 lub nowszy
Jak używać API kompozycji w formularzach Windows Forms
W tym samouczku utworzysz prosty interfejs użytkownika formularzy systemu Windows i dodasz do niego animowane elementy kompozycji. Zarówno składniki Windows Forms, jak i Composition są proste, ale pokazany kod międzyoperajności jest taki sam, niezależnie od złożoności składników. Gotowa aplikacja wygląda następująco.
Tworzenie projektu formularzy systemu Windows
Pierwszym krokiem jest utworzenie projektu aplikacji Windows Forms, który zawiera definicję aplikacji i formularz główny interfejsu użytkownika.
Aby utworzyć nowy projekt aplikacji Windows Forms w języku Visual C# o nazwie HelloComposition:
- Otwórz program Visual Studio i wybierz pozycję Plik >Nowy>Projekt.
Otwiera się okno dialogowe Nowy projekt. - W kategorii Zainstalowane rozwiń wątek Visual C#, a następnie wybierz pozycję Windows Desktop.
- Wybierz szablon Windows Forms App (.NET Framework).
- Wprowadź nazwę HelloComposition, wybierz pozycję Framework .NET Framework 4.7.2, a następnie kliknij przycisk OK.
Visual Studio tworzy projekt i otwiera edytor dla domyślnego okna aplikacji o nazwie Form1.cs.
Konfigurowanie projektu do używania interfejsów API środowiska uruchomieniowego systemu Windows
Aby używać interfejsów API środowiska Uruchomieniowego systemu Windows (WinRT) w aplikacji Windows Forms, należy skonfigurować projekt programu Visual Studio w celu uzyskania dostępu do środowiska uruchomieniowego systemu Windows. Ponadto wektory są szeroko używane przez API kompozycji, dlatego należy dodać odwołania wymagane do użycia wektorów.
Pakiety NuGet są dostępne dla obu tych potrzeb. Zainstaluj najnowsze wersje tych pakietów, aby dodać niezbędne odwołania do projektu.
- Microsoft.Windows.SDK.Contracts (Wymaga domyślnego formatu zarządzania pakietami ustawionego na PackageReference).
- System.Numerics.Vectors
Uwaga / Notatka
Zalecamy skonfigurowanie projektu przy użyciu pakietów NuGet, ale można ręcznie dodać wymagane odwołania. Więcej informacji znajdziesz w Ulepszanie aplikacji desktopowej dla systemu Windows. W poniższej tabeli przedstawiono pliki, do których należy dodać odwołania.
| Plik | Lokalizacja |
|---|---|
| System.Runtime.WindowsRuntime | C:\Windows\Microsoft.NET\Framework\v4.0.30319 |
| Windows.Foundation.UniversalApiContract.winmd | C:\Program Files (x86)\Windows Kits\10\References<wersja sdk>\Windows.Foundation.UniversalApiContract<wersja> |
| Windows.FoundationContract.winmd | C:\Program Files (x86)\Windows Kits\10\References<wersja SDK>\Windows.Foundation.FoundationContract<wersja> |
| 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 |
Utwórz niestandardową kontrolkę do zarządzania interoperacyjnością
Aby hostować zawartość utworzoną za pomocą warstwy wizualnej, należy utworzyć niestandardową kontrolkę pochodzącą od kontrolki. Ta kontrolka zapewnia dostęp do uchwytu okna, który jest potrzebny do utworzenia kontenera dla zawartości warstwy wizualizacji.
W tym miejscu przeprowadzasz większość konfiguracji potrzebnej do hostowania interfejsów API kompozycji. W tej kontrolce użyjesz Platform Invocation Services (PInvoke) i międzyoperacyjności modelu COM, aby wprowadzić interfejsy API kompozycji do aplikacji Windows Forms. Aby uzyskać więcej informacji na temat PInvoke i współpracy z COM z kodem niezarządzanym, zobacz Interoperating with unmanaged code.
Wskazówka
Jeśli chcesz, sprawdź kompletny kod na końcu samouczka, aby upewnić się, że cały kod znajduje się w odpowiednich miejscach podczas pracy z samouczkiem.
Dodaj nowy niestandardowy plik kontrolki do projektu, który pochodzi z Control.
- W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy projekt HelloComposition .
- W menu kontekstowym wybierz pozycję Dodaj>nowy element....
- W oknie dialogowym Dodawanie nowego elementu
wybierz pozycję Kontrolka niestandardowa . - Nadaj kontrolce nazwę CompositionHost.cs, a następnie kliknij Dodaj. CompositionHost.cs zostanie otwarty w widoku Projekt.
Przejdź do widoku kodu dla CompositionHost.cs i dodaj następujący kod do klasy.
// 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; } }Dodaj kod do konstruktora.
W konstruktorze wywołasz metody InitializeCoreDispatcher i InitComposition . Te metody są tworzone w następnych krokach.
public CompositionHost() { InitializeComponent(); // Get the window handle. hwndHost = Handle; // Create dispatcher queue. dispatcherQueue = InitializeCoreDispatcher(); // Build Composition tree of content. InitComposition(hwndHost); }Inicjuj wątek używając CoreDispatcher. Główny dyspozytor jest odpowiedzialny za przetwarzanie komunikatów okien i wysyłanie zdarzeń dla interfejsów API WinRT. Nowe wystąpienia kompositora muszą być tworzone w wątku z CoreDispatcher.
- Utwórz metodę o nazwie InitializeCoreDispatcher i dodaj kod w celu skonfigurowania kolejki dyspozytora.
// 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; }- Kolejka dyspozytora wymaga deklaracji PInvoke. Umieść tę deklarację na końcu kodu dla klasy. (Umieszczamy ten kod w regionie, aby zachować porządek kodu klasy).
#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 declarationsMasz teraz gotową kolejkę dyspozytora i możesz rozpocząć inicjowanie i tworzenie treści Composition.
Zainicjować Compositor. Kompozytor to fabryka, która tworzy w przestrzeni nazw Windows.UI.Composition różne typy obejmujące warstwę wizualną, system efektów i system animacji. Klasa Compositor zarządza również okresem istnienia obiektów utworzonych z fabryki.
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 i ICompositionTarget wymagają importu modelu COM. Umieść ten kod za klasą CompositionHost, ale wewnątrz deklaracji przestrzeni nazw.
#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
Utwórz kontrolkę niestandardową do hostowania elementów kompozycji
Dobrym pomysłem jest umieszczenie kodu, który generuje elementy kompozycji i zarządza nimi w oddzielnej kontrolce pochodzącej z elementu CompositionHost. Dzięki temu kod międzyoperacowy utworzony w klasie CompositionHost pozostanie wielokrotnego użytku.
W tym miejscu utworzysz niestandardową kontrolkę pochodzącą z elementu CompositionHost. Ta kontrolka jest dodawana do przybornika programu Visual Studio, aby można było dodać ją do formularza.
Dodaj nowy niestandardowy plik kontrolki do projektu, który pochodzi z elementu CompositionHost.
- W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy projekt HelloComposition .
- W menu kontekstowym wybierz pozycję Dodaj>nowy element....
- W oknie dialogowym Dodawanie nowego elementu
wybierz pozycję Kontrolka niestandardowa . - Nadaj kontrolce nazwę CompositionHostControl.cs, a następnie kliknij przycisk Dodaj. CompositionHostControl.cs otwiera się w widoku projektu.
W okienku Właściwości dla widoku projektu CompositionHostControl.cs ustaw właściwość BackColor na ControlLight.
Ustawienie koloru tła jest opcjonalne. Robimy to tutaj, żebyś mógł zobaczyć swoją niestandardową kontrolkę na tle formularza.
Przejdź do widoku kodu dla CompositionHostControl.cs i zaktualizuj deklarację klasy, aby pochodzić z obiektu CompositionHost.
class CompositionHostControl : CompositionHostZaktualizuj konstruktor w celu wywołania konstruktora podstawowego.
public CompositionHostControl() : base() { }
Dodawanie elementów kompozycji
Po zainstalowaniu infrastruktury możesz teraz dodać zawartość kompozycji do interfejsu użytkownika aplikacji.
W tym przykładzie dodasz kod do klasy CompositionHostControl, który tworzy i animuje prostą SpriteVisual.
Dodaj element kompozycji.
W CompositionHostControl.cs dodaj te metody do klasy CompositionHostControl.
// 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); }
Dodawanie kontrolki do formularza
Teraz, gdy masz niestandardową kontrolkę do hostowania zawartości Composition, możesz dodać ją do interfejsu aplikacji. W tym miejscu dodasz wystąpienie kontrolki CompositionHostControl utworzonej w poprzednim kroku. Element CompositionHostControl jest automatycznie dodawany do przybornika programu Visual Studio w obszarze Nazwa projektu Składniki.
W widoku projektu Form1.CS dodaj przycisk do interfejsu użytkownika.
- Przeciągnij przycisk z przybornika do formularza Form1. Umieść go w lewym górnym rogu formularza. (Zobacz obraz na początku samouczka, aby sprawdzić położenie kontrolek).
- W okienku Właściwości zmień właściwość Text z przycisku button1 na Dodaj element kompozycji.
- Zmień rozmiar przycisku, tak aby cały tekst był wyświetlany.
(Aby uzyskać więcej informacji, zobacz Jak dodać kontrole do Windows Forms.)
Dodaj kontrolkę CompositionHostControl do interfejsu użytkownika.
- Przeciągnij kontrolkę CompositionHostControl z przybornika na Form1. Umieść go po prawej stronie przycisku.
- Zmień rozmiar elementu CompositionHost, tak aby wypełniał pozostałą część formularza.
Obsłuż zdarzenie kliknięcia przycisku.
- W okienku Właściwości kliknij błyskawicę, aby przełączyć się do widoku Zdarzenia.
- Na liście zdarzeń wybierz zdarzenie Click, wpisz Button_Clicki naciśnij Enter.
- Ten kod jest dodawany w Form1.cs:
private void Button_Click(object sender, EventArgs e) { }Dodaj kod do procedury obsługi kliknięć przycisku, aby utworzyć nowe elementy.
- W Form1.cs dodaj kod do procedury obsługi zdarzenia Button_Click, którą utworzyłeś wcześniej. Ten kod wywołuje CompositionHostControl1.AddElement, aby utworzyć nowy element z losowo wygenerowanym rozmiarem i przesunięciem. (Wystąpienie elementu CompositionHostControl zostało automatycznie nazwane compositionHostControl1 po przeciągnięciu go do formularza).
// 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); }
Teraz możesz skompilować i uruchomić aplikację Windows Forms. Po kliknięciu przycisku powinny zostać wyświetlone animowane kwadraty dodane do interfejsu użytkownika.
Dalsze kroki
Aby uzyskać bardziej kompletny przykład oparty na tej samej infrastrukturze, zobacz przykład integracji warstwy wizualnej windows Forms w witrynie GitHub.
Dodatkowe zasoby
- Wprowadzenie do formularzy systemu Windows (.NET)
- Interoperacyjność z niezarządzanym kodem (.NET)
- Wprowadzenie do aplikacji systemu Windows (UWP)
- Ulepsz swoją aplikację desktopową dla systemu Windows (UWP)
- przestrzeń nazw Windows.UI.Composition (UWP)
Kompletny kod
Oto kompletny kod tego samouczka.
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
}
Windows developer