<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【UWP】讓 UWP 自己托管自己 —— Windows SDK 篇

      眾所周知,UWP 使用的窗口模型是 CoreWindow,但是 UWP 本身只是一個應用模型,所以完全可以創建 win32 窗口,那么我們可以不可以創建一個 win32 窗口,然后像 XAML 島 (XAML Islands) 一樣把 XAML 托管上去呢?本篇將講述如何在 UWP 創建一個 XAML 島窗口。

      示例

      首先,XAML 島會判斷當前的應用模型是否為ClassicDesktop,所以我們需要利用Detours劫持AppPolicyGetWindowingModel方法。具體內容如下:

      #r "nuget:Detours.Win32Metadata"
      #r "nuget:Microsoft.Windows.CsWin32"
      
      using System;
      using System.Runtime.CompilerServices;
      using System.Runtime.InteropServices;
      using Windows.Win32;
      using Windows.Win32.Foundation;
      using Windows.Win32.Storage.Packaging.Appx;
      using Detours = Microsoft.Detours.PInvoke;
      
      /// <summary>
      /// Represents a hook for the <see cref="PInvoke.AppPolicyGetWindowingModel(HANDLE, AppPolicyWindowingModel*)"/> function.
      /// </summary>
      public sealed partial class HookWindowingModel : IDisposable
      {
          /// <summary>
          /// The value that indicates whether the class has been disposed.
          /// </summary>
          private bool disposed;
      
          /// <summary>
          /// The reference count for the hook.
          /// </summary>
          private static int refCount;
      
          /// <summary>
          /// The value that represents the current process token.
          /// </summary>
          private const int currentProcessToken = -6;
      
          /// <remarks>The original <see cref="PInvoke.AppPolicyGetWindowingModel(HANDLE, AppPolicyWindowingModel*)"/> function.</remarks>
          /// <inheritdoc cref="PInvoke.AppPolicyGetWindowingModel(HANDLE, AppPolicyWindowingModel*)"/>
          private static unsafe delegate* unmanaged[Stdcall]<HANDLE, AppPolicyWindowingModel*, WIN32_ERROR> AppPolicyGetWindowingModel;
      
          /// <summary>
          /// Initializes a new instance of the <see cref="HookWindowingModel"/> class.
          /// </summary>
          public HookWindowingModel()
          {
              refCount++;
              StartHook();
          }
      
          /// <summary>
          /// Finalizes this instance of the <see cref="HookWindowingModel"/> class.
          /// </summary>
          ~HookWindowingModel()
          {
              Dispose();
          }
      
          /// <summary>
          /// Gets the value that indicates whether the hook is active.
          /// </summary>
          public static bool IsHooked { get; private set; }
      
          /// <summary>
          /// Gets or sets the windowing model to use when the hooked <see cref="PInvoke.AppPolicyGetWindowingModel(HANDLE, AppPolicyWindowingModel*)"/> function is called.
          /// </summary>
          internal static AppPolicyWindowingModel WindowingModel { get; set; } = AppPolicyWindowingModel.AppPolicyWindowingModel_ClassicDesktop;
      
          /// <summary>
          /// Starts the hook for the <see cref="PInvoke.AppPolicyGetWindowingModel(HANDLE, AppPolicyWindowingModel*)"/> function.
          /// </summary>
          private static unsafe void StartHook()
          {
              if (!IsHooked)
              {
                  using FreeLibrarySafeHandle library = PInvoke.GetModuleHandle("KERNEL32.dll");
                  if (!library.IsInvalid && NativeLibrary.TryGetExport(library.DangerousGetHandle(), nameof(PInvoke.AppPolicyGetWindowingModel), out nint appPolicyGetWindowingModel))
                  {
                      void* appPolicyGetWindowingModelPtr = (void*)appPolicyGetWindowingModel;
                      delegate* unmanaged[Stdcall]<HANDLE, AppPolicyWindowingModel*, WIN32_ERROR> overrideAppPolicyGetWindowingModel = &OverrideAppPolicyGetWindowingModel;
      
                      _ = Detours.DetourRestoreAfterWith();
      
                      _ = Detours.DetourTransactionBegin();
                      _ = Detours.DetourUpdateThread(PInvoke.GetCurrentThread());
                      _ = Detours.DetourAttach(ref appPolicyGetWindowingModelPtr, overrideAppPolicyGetWindowingModel);
                      _ = Detours.DetourTransactionCommit();
      
                      AppPolicyGetWindowingModel = (delegate* unmanaged[Stdcall]<HANDLE, AppPolicyWindowingModel*, WIN32_ERROR>)appPolicyGetWindowingModelPtr;
                      IsHooked = true;
                  }
              }
          }
      
          /// <summary>
          /// Ends the hook for the <see cref="PInvoke.AppPolicyGetWindowingModel(HANDLE, AppPolicyWindowingModel*)"/> function.
          /// </summary>
          private static unsafe void EndHook()
          {
              if (--refCount == 0 && IsHooked)
              {
                  void* appPolicyGetWindowingModelPtr = AppPolicyGetWindowingModel;
                  delegate* unmanaged[Stdcall]<HANDLE, AppPolicyWindowingModel*, WIN32_ERROR> overrideAppPolicyGetWindowingModel = &OverrideAppPolicyGetWindowingModel;
      
                  _ = Detours.DetourTransactionBegin();
                  _ = Detours.DetourUpdateThread(PInvoke.GetCurrentThread());
                  _ = Detours.DetourDetach(&appPolicyGetWindowingModelPtr, overrideAppPolicyGetWindowingModel);
                  _ = Detours.DetourTransactionCommit();
      
                  AppPolicyGetWindowingModel = null;
                  IsHooked = false;
              }
          }
      
          /// <param name="policy">A pointer to a variable of the <a >AppPolicyWindowingModel</a> enumerated type.
          /// When the function returns successfully, the variable contains the <see cref="WindowingModel"/> when the identified process is current; otherwise, the windowing model of the identified process.</param>
          /// <remarks>The overridden <see cref="PInvoke.AppPolicyGetWindowingModel(HANDLE, AppPolicyWindowingModel*)"/> function.</remarks>
          /// <inheritdoc cref="PInvoke.AppPolicyGetWindowingModel(HANDLE, AppPolicyWindowingModel*)"/>
          [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])]
          private static unsafe WIN32_ERROR OverrideAppPolicyGetWindowingModel(HANDLE processToken, AppPolicyWindowingModel* policy)
          {
              if ((int)processToken.Value == currentProcessToken)
              {
                  *policy = WindowingModel;
                  return WIN32_ERROR.ERROR_SUCCESS;
              }
              return AppPolicyGetWindowingModel(processToken, policy);
          }
      
          /// <inheritdoc/>
          public void Dispose()
          {
              if (!disposed && IsHooked)
              {
                  EndHook();
              }
              GC.SuppressFinalize(this);
              disposed = true;
          }
      }

      準備工作完成,接下來我們就可以創建窗口了,首先我們需要新創建一個線程,CoreWindow 線程無法新建 XAML 島,新建線程只需要用Thread就行了。

      new Thread(() => { ... });

      首先我們需要創建 XAML 島,這時我們就需要利用上面劫持器來劫持獲取應用模型的方法了。

      DesktopWindowXamlSource source;
      using (HookWindowingModel hook = new())
      {
          source = new DesktopWindowXamlSource();
      }

      微軟并沒有單獨提供一個 Win32 窗口管理的輪子,如果引用 Windows Forms 就太臃腫了,于是我們需要手動制作一個 Window 類:

      由于 C#/Win32 不支持源生成 COM 以支持 AOT,所以我們需要手寫IDesktopWindowXamlSourceNative定義:

      namespace Windows.Win32.System.WinRT.Xaml
      {
          [GeneratedComInterface]
          [Guid("3CBCF1BF-2F76-4E9C-96AB-E84B37972554")]
          internal partial interface IDesktopWindowXamlSourceNative
          {
              /// <summary>
              /// Attaches the current **IDesktopWindowXamlSourceNative** instance to a parent UI element in your desktop app that is associated with a window handle.
              /// </summary>
              /// <param name="parentWnd">
              /// <para>Type: **HWND** The window handle of the parent UI element in which you want to host a WinRT XAML control.</para>
              /// <para><see >Read more on docs.microsoft.com</see>.</para>
              /// </param>
              /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an **HRESULT** error code.</returns>
              /// <remarks>
              /// <para>For a code example that demonstrates how to use this method, see [XamlBridge.cpp](https://github.com/microsoft/Xaml-Islands-Samples/blob/master/Samples/Win32/SampleCppApp/XamlBridge.cpp) in the SampleCppApp sample in the XAML Island samples repo. > [!IMPORTANT] > Make sure that your code calls the **AttachToWindow** method only once per [DesktopWindowXamlSource](/uwp/api/windows.ui.xaml.hosting.desktopwindowxamlsource) object. Calling this method more than once for a **DesktopWindowXamlSource** object could result in a memory leak.</para>
              /// <para><see >Read more on docs.microsoft.com</see>.</para>
              /// </remarks>
              [PreserveSig]
              [return: MarshalAs(UnmanagedType.Error)]
              int AttachToWindow(nint parentWnd);
      
              /// <summary>
              /// Gets the window handle of the parent UI element that is associated with the current IDesktopWindowXamlSourceNative instance.
              /// </summary>
              /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an **HRESULT** error code.</returns>
              [PreserveSig]
              [return: MarshalAs(UnmanagedType.Error)]
              int get_WindowHandle(out nint hWnd);
          }
      
          file static class Extensions
          {
              /// <summary>
              /// Gets the window handle of the parent UI element that is associated with the current IDesktopWindowXamlSourceNative instance.
              /// </summary>
              public static HWND WindowHandle(this IDesktopWindowXamlSourceNative source)
              {
                  _ = source.get_WindowHandle(out nint hWnd);
                  return new HWND(hWnd);
              }
          }
      }

      然后就可以制作 Window 類了:

      /// <summary>
      /// Represents a system-managed container for the content of an app.
      /// </summary>
      public partial class DesktopWindow
      {
          private bool m_bIsClosed = false;
          private DesktopWindowXamlSource m_source;
          private IDesktopWindowXamlSourceNative m_native;
      
          private readonly HWND m_hwnd;
          private readonly WNDCLASSEXW m_wndClassEx;
      
          /// <summary>
          /// Initializes a new instance of the <see cref="DesktopWindow"/> class.
          /// </summary>
          public DesktopWindow()
          {
              m_wndClassEx = RegisterDesktopWindowClass(WNDPROC);
              m_hwnd = CreateDesktopWindow();
          }
      
          /// <summary>
          /// Gets the event dispatcher for the window.
          /// </summary>
          public CoreDispatcher Dispatcher { get; private set; }
      
          /// <summary>
          /// Gets the <see cref="DesktopWindowXamlSource"/> to provide XAML for this window.
          /// </summary>
          public DesktopWindowXamlSource WindowXamlSource
          {
              get => m_source;
              private init
              {
                  if (m_source != value)
                  {
                      m_source = value;
                      if (value != null)
                      {
                          Dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
                          m_native = value.As<IDesktopWindowXamlSourceNative>();
                          m_native.AttachToWindow(m_hwnd);
                          ResizeWindowToDesktopWindowXamlSourceWindowDimensions();
                      }
                      else
                      {
                          m_native = null;
                      }
                  }
              }
          }
      
          /// <summary>
          /// Shows the window and activates it.
          /// </summary>
          public void Show() => _ = PInvoke.ShowWindow(m_hwnd, SHOW_WINDOW_CMD.SW_NORMAL);
      
          private LRESULT WNDPROC(HWND hWnd, uint message, WPARAM wParam, LPARAM lParam)
          {
              switch (message)
              {
                  case PInvoke.WM_PAINT:
                      HDC hdc = PInvoke.BeginPaint(hWnd, out PAINTSTRUCT ps);
                      _ = PInvoke.GetClientRect(hWnd, out RECT rect);
                      _ = PInvoke.FillRect(hdc, rect, new DefaultSafeHandle(PInvoke.GetStockObject(GET_STOCK_OBJECT_FLAGS.WHITE_BRUSH)));
                      _ = PInvoke.EndPaint(hWnd, ps);
                      return new LRESULT();
                  case PInvoke.WM_CLOSE when m_bIsClosed:
                      goto default;
                  case PInvoke.WM_CLOSE:
                      m_bIsClosed = true;
                      goto default;
                  case PInvoke.WM_SIZE:
                      ResizeWindowToDesktopWindowXamlSourceWindowDimensions();
                      return new LRESULT();
                  case PInvoke.WM_CREATE:
                      return new LRESULT();
                  case PInvoke.WM_DESTROY:
                      PInvoke.PostQuitMessage(0);
                      return new LRESULT();
                  default:
                      return PInvoke.DefWindowProc(hWnd, message, wParam, lParam);
              }
          }
      
          private void ResizeWindowToDesktopWindowXamlSourceWindowDimensions()
          {
              if (m_bIsClosed) return;
              _ = PInvoke.GetClientRect(m_hwnd, out RECT rect);
              _ = PInvoke.SetWindowPos(
                  m_native.WindowHandle(),
                  new HWND(),
                  0, 0,
                  rect.Width, rect.Height,
                  SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE | SET_WINDOW_POS_FLAGS.SWP_NOZORDER | SET_WINDOW_POS_FLAGS.SWP_SHOWWINDOW);
          }
      }
      
      public partial class DesktopWindow
      {
          private static readonly unsafe HINSTANCE g_hInstance = new((void*)Process.GetCurrentProcess().Handle);
      
          // win32 window class name for top-level WinUI desktop windows
          private const string s_windowClassName = "WinUIDesktopWin32WindowClass";
      
          // Default window title for top-level WinUI desktop windows
          private const string s_defaultWindowTitle = "WinUI Desktop";
      
          private static unsafe WNDCLASSEXW RegisterDesktopWindowClass(WNDPROC lpfnWndProc)
          {
              if (!PInvoke.GetClassInfoEx(new DefaultSafeHandle(g_hInstance), s_windowClassName, out WNDCLASSEXW wndClassEx))
              {
                  wndClassEx.cbSize = (uint)Marshal.SizeOf(wndClassEx);
                  wndClassEx.style = WNDCLASS_STYLES.CS_HREDRAW | WNDCLASS_STYLES.CS_VREDRAW;
                  wndClassEx.cbClsExtra = 0;
                  wndClassEx.cbWndExtra = 0;
                  wndClassEx.hCursor = PInvoke.LoadCursor(new HINSTANCE(), PInvoke.IDC_ARROW);
                  wndClassEx.hbrBackground = (HBRUSH)((nint)SYS_COLOR_INDEX.COLOR_WINDOW + 1);
                  wndClassEx.hInstance = g_hInstance;
      
                  fixed (char* lps_windowClassName = s_windowClassName)
                  {
                      wndClassEx.lpszClassName = lps_windowClassName;
                  }
      
                  wndClassEx.lpfnWndProc = lpfnWndProc;
                  _ = PInvoke.RegisterClassEx(wndClassEx);
      
                  return wndClassEx;
              }
              return default;
          }
      
          private static unsafe HWND CreateDesktopWindow() =>
              PInvoke.CreateWindowEx(
                  0,                                  // Extended Style
                  s_windowClassName,                  // name of window class
                  s_defaultWindowTitle,               // title-bar string
                  WINDOW_STYLE.WS_OVERLAPPEDWINDOW | WINDOW_STYLE.WS_VISIBLE,  // top-level window
                  int.MinValue,                       // default horizontal position
                  (int)SHOW_WINDOW_CMD.SW_HIDE,       // If the y parameter is some other value,
                                                      // then the window manager calls ShowWindow with that value as the nCmdShow parameter
                  int.MinValue,                       // default width
                  int.MinValue,                       // default height
                  new HWND(),                         // no owner window
                  null,                               // use class menu
                  new DefaultSafeHandle(g_hInstance),
                  null);
      
          private partial class DefaultSafeHandle(nint invalidHandleValue, bool ownsHandle) : SafeHandle(invalidHandleValue, ownsHandle)
          {
              public DefaultSafeHandle(nint handle) : this(handle, true) => SetHandle(handle);
      
              public override bool IsInvalid => handle != nint.Zero;
      
              protected override bool ReleaseHandle() => true;
          }
      }

      然后我們就可以初始化一個窗口了。

      DesktopWindow window = new() { WindowXamlSource = source };

      最后不要忘了用消息循環保持當前線程,不然這里跑完了窗口就退出了。

      MSG msg = new();
      while (msg.message != PInvoke.WM_QUIT)
      {
          if (PInvoke.PeekMessage(out msg, new HWND(), 0, 0, PEEK_MESSAGE_REMOVE_TYPE.PM_REMOVE))
          {
              _ = PInvoke.DispatchMessage(msg);
          }
      }

      最后把之前的東西組合起來,再加點東西:

      /// <summary>
      /// Represents a system-managed container for the content of an app.
      /// </summary>
      public partial class DesktopWindow
      {
          private bool m_bIsClosed = false;
          private DesktopWindowXamlSource m_source;
          private IDesktopWindowXamlSourceNative m_native;
      
          private readonly HWND m_hwnd;
          private readonly WNDCLASSEXW m_wndClassEx;
      
          /// <summary>
          /// Initializes a new instance of the <see cref="DesktopWindow"/> class.
          /// </summary>
          public DesktopWindow()
          {
              m_wndClassEx = RegisterDesktopWindowClass(WNDPROC);
              m_hwnd = CreateDesktopWindow();
          }
      
          /// <summary>
          /// Get the handle of the window.
          /// </summary>
          public nint Hwnd => m_hwnd;
      
          /// <summary>
          /// Gets the event dispatcher for the window.
          /// </summary>
          public CoreDispatcher Dispatcher { get; private set; }
      
          /// <summary>
          /// Gets or sets the visual root of an application window.
          /// </summary>
          public UIElement Content
          {
              get => WindowXamlSource.Content;
              set => WindowXamlSource.Content = value;
          }
      
          /// <summary>
          /// Gets or sets the XamlRoot in which this element is being viewed.
          /// </summary>
          [SupportedOSPlatform("Windows10.0.18362.0")]
          public XamlRoot XamlRoot
          {
              get => WindowXamlSource.Content.XamlRoot;
              set => WindowXamlSource.Content.XamlRoot = value;
          }
      
          /// <summary>
          /// Gets or sets a string used for the window title.
          /// </summary>
          public unsafe string Title
          {
              get
              {
                  int windowTextLength = PInvoke.GetWindowTextLength(m_hwnd);
                  char* windowText = stackalloc char[windowTextLength + 1];
                  _ = PInvoke.GetWindowText(m_hwnd, windowText, windowTextLength + 1);
                  return new string(windowText);
              }
              set => _ = PInvoke.SetWindowText(m_hwnd, value);
          }
      
          /// <summary>
          /// Gets the <see cref="DesktopWindowXamlSource"/> to provide XAML for this window.
          /// </summary>
          public DesktopWindowXamlSource WindowXamlSource
          {
              get => m_source;
              private init
              {
                  if (m_source != value)
                  {
                      m_source = value;
                      if (value != null)
                      {
                          Dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
                          m_native = value.As<IDesktopWindowXamlSourceNative>();
                          m_native.AttachToWindow(m_hwnd);
                          ResizeWindowToDesktopWindowXamlSourceWindowDimensions();
                      }
                      else
                      {
                          m_native = null;
                      }
                  }
              }
          }
      
          /// <summary>
          /// Occurs when the window has closed.
          /// </summary>
          public event TypedEventHandler<DesktopWindow, object> Closed;
      
          /// <summary>
          /// Shows the window and activates it.
          /// </summary>
          public void Show() => _ = PInvoke.ShowWindow(m_hwnd, SHOW_WINDOW_CMD.SW_NORMAL);
      
          /// <summary>
          /// Sets the icon for the window, using the specified icon path.
          /// </summary>
          /// <param name="iconPath">The path of the icon.</param>
          public unsafe void SetIcon(string iconPath)
          {
              fixed (char* ptr = iconPath)
              {
                  HANDLE icon = PInvoke.LoadImage(new HINSTANCE(), ptr, GDI_IMAGE_TYPE.IMAGE_ICON, 0, 0, IMAGE_FLAGS.LR_LOADFROMFILE);
                  _ = PInvoke.SendMessage(m_hwnd, PInvoke.WM_SETICON, PInvoke.ICON_BIG, new LPARAM((nint)icon.Value));
              }
          }
      
          private LRESULT WNDPROC(HWND hWnd, uint message, WPARAM wParam, LPARAM lParam)
          {
              switch (message)
              {
                  case PInvoke.WM_PAINT:
                      HDC hdc = PInvoke.BeginPaint(hWnd, out PAINTSTRUCT ps);
                      _ = PInvoke.GetClientRect(hWnd, out RECT rect);
                      _ = PInvoke.FillRect(hdc, rect, new DefaultSafeHandle(PInvoke.GetStockObject(GET_STOCK_OBJECT_FLAGS.WHITE_BRUSH)));
                      _ = PInvoke.EndPaint(hWnd, ps);
                      return new LRESULT();
                  case PInvoke.WM_CLOSE when m_bIsClosed:
                      goto default;
                  case PInvoke.WM_CLOSE:
                      m_bIsClosed = true;
                      Closed?.Invoke(this, null);
                      goto default;
                  case PInvoke.WM_SIZE:
                      ResizeWindowToDesktopWindowXamlSourceWindowDimensions();
                      return new LRESULT();
                  case PInvoke.WM_CREATE:
                      return new LRESULT();
                  case PInvoke.WM_DESTROY:
                      PInvoke.PostQuitMessage(0);
                      return new LRESULT();
                  default:
                      return PInvoke.DefWindowProc(hWnd, message, wParam, lParam);
              }
          }
      
          private void ResizeWindowToDesktopWindowXamlSourceWindowDimensions()
          {
              if (m_bIsClosed) return;
              _ = PInvoke.GetClientRect(m_hwnd, out RECT rect);
              _ = PInvoke.SetWindowPos(
                  m_native.WindowHandle(),
                  new HWND(),
                  0, 0,
                  rect.Width, rect.Height,
                  SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE | SET_WINDOW_POS_FLAGS.SWP_NOZORDER | SET_WINDOW_POS_FLAGS.SWP_SHOWWINDOW);
          }
      }
      
      public partial class DesktopWindow
      {
          private static readonly unsafe HINSTANCE g_hInstance = new((void*)Process.GetCurrentProcess().Handle);
      
          // win32 window class name for top-level WinUI desktop windows
          private const string s_windowClassName = "WinUIDesktopWin32WindowClass";
      
          // Default window title for top-level WinUI desktop windows
          private const string s_defaultWindowTitle = "WinUI Desktop";
      
          private static unsafe WNDCLASSEXW RegisterDesktopWindowClass(WNDPROC lpfnWndProc)
          {
              if (!PInvoke.GetClassInfoEx(new DefaultSafeHandle(g_hInstance), s_windowClassName, out WNDCLASSEXW wndClassEx))
              {
                  wndClassEx.cbSize = (uint)Marshal.SizeOf(wndClassEx);
                  wndClassEx.style = WNDCLASS_STYLES.CS_HREDRAW | WNDCLASS_STYLES.CS_VREDRAW;
                  wndClassEx.cbClsExtra = 0;
                  wndClassEx.cbWndExtra = 0;
                  wndClassEx.hCursor = PInvoke.LoadCursor(new HINSTANCE(), PInvoke.IDC_ARROW);
                  wndClassEx.hbrBackground = (HBRUSH)((nint)SYS_COLOR_INDEX.COLOR_WINDOW + 1);
                  wndClassEx.hInstance = g_hInstance;
      
                  fixed (char* lps_windowClassName = s_windowClassName)
                  {
                      wndClassEx.lpszClassName = lps_windowClassName;
                  }
      
                  wndClassEx.lpfnWndProc = lpfnWndProc;
                  _ = PInvoke.RegisterClassEx(wndClassEx);
      
                  return wndClassEx;
              }
              return default;
          }
      
          private static unsafe HWND CreateDesktopWindow() =>
              PInvoke.CreateWindowEx(
                  0,                                  // Extended Style
                  s_windowClassName,                  // name of window class
                  s_defaultWindowTitle,               // title-bar string
                  WINDOW_STYLE.WS_OVERLAPPEDWINDOW | WINDOW_STYLE.WS_VISIBLE,  // top-level window
                  int.MinValue,                       // default horizontal position
                  (int)SHOW_WINDOW_CMD.SW_HIDE,       // If the y parameter is some other value,
                                                      // then the window manager calls ShowWindow with that value as the nCmdShow parameter
                  int.MinValue,                       // default width
                  int.MinValue,                       // default height
                  new HWND(),                         // no owner window
                  null,                               // use class menu
                  new DefaultSafeHandle(g_hInstance),
                  null);
      
          private partial class DefaultSafeHandle(nint invalidHandleValue, bool ownsHandle) : SafeHandle(invalidHandleValue, ownsHandle)
          {
              public DefaultSafeHandle(nint handle) : this(handle, true) => SetHandle(handle);
      
              public override bool IsInvalid => handle != nint.Zero;
      
              protected override bool ReleaseHandle() => true;
          }
      }
      
      public partial class DesktopWindow
      {
          /// <summary>
          /// Create a new <see cref="DesktopWindow"/> instance.
          /// </summary>
          /// <param name="launched">Do something after <see cref="DesktopWindowXamlSource"/> created.</param>
          /// <returns>The new instance of <see cref="DesktopWindow"/>.</returns>
          public static Task<DesktopWindow> CreateAsync(Action<DesktopWindowXamlSource> launched)
          {
              TaskCompletionSource<DesktopWindow> taskCompletionSource = new();
      
              new Thread(() =>
              {
                  try
                  {
                      DesktopWindowXamlSource source;
                      using (HookWindowingModel hook = new())
                      {
                          source = new DesktopWindowXamlSource();
                      }
      
                      DesktopWindow window = new() { WindowXamlSource = source };
      
                      launched(source);
                      taskCompletionSource.SetResult(window);
      
                      MSG msg = new();
                      while (msg.message != PInvoke.WM_QUIT)
                      {
                          if (PInvoke.PeekMessage(out msg, new HWND(), 0, 0, PEEK_MESSAGE_REMOVE_TYPE.PM_REMOVE))
                          {
                              _ = PInvoke.DispatchMessage(msg);
                          }
                      }
                  }
                  catch (Exception e)
                  {
                      taskCompletionSource.SetException(e);
                  }
              })
              {
                  Name = nameof(DesktopWindowXamlSource)
              }.Start();
      
              return taskCompletionSource.Task;
          }
      }
      
      namespace Windows.Win32.System.WinRT.Xaml
      {
          [GeneratedComInterface]
          [Guid("3CBCF1BF-2F76-4E9C-96AB-E84B37972554")]
          internal partial interface IDesktopWindowXamlSourceNative
          {
              /// <summary>
              /// Attaches the current **IDesktopWindowXamlSourceNative** instance to a parent UI element in your desktop app that is associated with a window handle.
              /// </summary>
              /// <param name="parentWnd">
              /// <para>Type: **HWND** The window handle of the parent UI element in which you want to host a WinRT XAML control.</para>
              /// <para><see >Read more on docs.microsoft.com</see>.</para>
              /// </param>
              /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an **HRESULT** error code.</returns>
              /// <remarks>
              /// <para>For a code example that demonstrates how to use this method, see [XamlBridge.cpp](https://github.com/microsoft/Xaml-Islands-Samples/blob/master/Samples/Win32/SampleCppApp/XamlBridge.cpp) in the SampleCppApp sample in the XAML Island samples repo. > [!IMPORTANT] > Make sure that your code calls the **AttachToWindow** method only once per [DesktopWindowXamlSource](/uwp/api/windows.ui.xaml.hosting.desktopwindowxamlsource) object. Calling this method more than once for a **DesktopWindowXamlSource** object could result in a memory leak.</para>
              /// <para><see >Read more on docs.microsoft.com</see>.</para>
              /// </remarks>
              [PreserveSig]
              [return: MarshalAs(UnmanagedType.Error)]
              int AttachToWindow(nint parentWnd);
      
              /// <summary>
              /// Gets the window handle of the parent UI element that is associated with the current IDesktopWindowXamlSourceNative instance.
              /// </summary>
              /// <returns>If this method succeeds, it returns S_OK. Otherwise, it returns an **HRESULT** error code.</returns>
              [PreserveSig]
              [return: MarshalAs(UnmanagedType.Error)]
              int get_WindowHandle(out nint hWnd);
          }
      
          file static class Extensions
          {
              /// <summary>
              /// Gets the window handle of the parent UI element that is associated with the current IDesktopWindowXamlSourceNative instance.
              /// </summary>
              public static HWND WindowHandle(this IDesktopWindowXamlSourceNative source)
              {
                  _ = source.get_WindowHandle(out nint hWnd);
                  return new HWND(hWnd);
              }
          }
      }

      這樣創建的窗口還存在一些問題,但是我不知道該怎么解決,所以該方法還是僅供參考。

      最后附上示例應用:https://github.com/wherewhere/CoreAppUWP/tree/wuxc

      MUXC 篇:【UWP】讓 UWP 自己托管自己 —— Windows App SDK 篇

      posted @ 2025-01-17 16:06  where-where  閱讀(272)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 第一精品福利导福航| a男人的天堂久久a毛片| 中文字幕人妻av12| 国精品无码一区二区三区在线看 | 国产在线亚州精品内射| 久久精品激情亚洲一二区| 毛片无遮挡高清免费| 男人又大又硬又粗视频| 久久国产精品色av免费看| caoporn成人免费公开| 久久久亚洲欧洲日产国码αv| 人人妻人人狠人人爽| 亚洲欧洲日产国产 最新| XXXXXHD亚洲日本HD| 久久国产精品日本波多野结衣| 中文字幕久久人妻熟人妻| 欧美交a欧美精品喷水| 国产精品久久久久久久久久| 日韩精品亚洲精品第一页| 精品人妻av区乱码| 国产成人精品日本亚洲网站 | 国产一区二区三区禁18| 国产精品有码在线观看| 青草内射中出高潮| 少妇高潮流白浆在线观看| 69人妻精品中文字幕| 女人腿张开让男人桶爽| 成A人片亚洲日本久久| 国产一区二区三区黄网| 亚洲成人av综合一区| 国产精品视频全国免费观看| 亚洲色大成网站WWW尤物| 亚洲www永久成人网站| 最新av中文字幕无码专区| 国产精品国产三级国AV | 亚洲色一区二区三区四区| 一区二区三区四区在线不卡高清| 社会| 精品国精品国自产在国产| 中文字幕精品亚洲人成在线 | 伊人av超碰伊人久久久|