You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI3+C#初始化MPV.Net时无法提供控件句柄的问题

在WinUI3中初始化MPV.Net的解决方案

由于WinUI3的XAML控件没有直接暴露HWND,你可以通过创建Win32宿主窗口承载MPV,再将该窗口嵌入WinUI3页面的方式解决问题,具体步骤如下:

1. 确认项目类型

使用桌面打包的WinUI3应用(而非UWP版),这类项目对Win32互操作支持更完善。

2. 添加Win32窗口相关P/Invoke声明

在项目中添加用于创建和管理宿主窗口的P/Invoke代码:

using System.Runtime.InteropServices;

public static class Win32Native
{
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern IntPtr CreateWindowEx(
        uint dwExStyle,
        string lpClassName,
        string lpWindowName,
        uint dwStyle,
        int x, int y, int nWidth, int nHeight,
        IntPtr hWndParent,
        IntPtr hMenu,
        IntPtr hInstance,
        IntPtr lpParam);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool DestroyWindow(IntPtr hWnd);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern uint RegisterClassW([In] ref WNDCLASS lpWndClass);

    public const uint WS_CHILD = 0x40000000;
    public const uint WS_VISIBLE = 0x10000000;
    public const int CW_USEDEFAULT = 0x80000000;

    public struct WNDCLASS
    {
        public uint style;
        public IntPtr lpfnWndProc;
        public int cbClsExtra;
        public int cbWndExtra;
        public IntPtr hInstance;
        public IntPtr hIcon;
        public IntPtr hCursor;
        public IntPtr hbrBackground;
        public string lpszMenuName;
        public string lpszClassName;
    }

    [DllImport("user32.dll")]
    public static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
}

3. 在HomePage中实现初始化逻辑

3.1 声明核心变量

在HomePage类中添加以下字段:

private IntPtr _mpvHostHwnd;
private MpvPlayer _mpvPlayer;
private Windows.UI.Xaml.Hosting.DesktopWindowXamlSource _desktopSource;

3.2 初始化宿主窗口与MPV

在HomePage的Loaded事件中编写初始化代码:

private void HomePage_Loaded(object sender, RoutedEventArgs e)
{
    // 注册Win32窗口类
    var wc = new Win32Native.WNDCLASS
    {
        lpszClassName = "MPVHostWindow",
        lpfnWndProc = Marshal.GetFunctionPointerForDelegate(new WndProcDelegate(DefWndProc)),
        hInstance = System.Diagnostics.Process.GetCurrentProcess().Handle,
        hbrBackground = IntPtr.Zero
    };
    Win32Native.RegisterClassW(ref wc);

    // 创建子窗口作为MPV的宿主
    _mpvHostHwnd = Win32Native.CreateWindowEx(
        0,
        "MPVHostWindow",
        "",
        Win32Native.WS_CHILD | Win32Native.WS_VISIBLE,
        Win32Native.CW_USEDEFAULT, Win32Native.CW_USEDEFAULT,
        (int)MPVHostGrid.ActualWidth, (int)MPVHostGrid.ActualHeight,
        IntPtr.Zero, IntPtr.Zero, wc.hInstance, IntPtr.Zero);

    // 初始化MPVPlayer
    _mpvPlayer = new MpvPlayer(_mpvHostHwnd, "path/to/libmpv-2.dll");

    // 将Win32窗口嵌入WinUI3页面
    _desktopSource = new Windows.UI.Xaml.Hosting.DesktopWindowXamlSource();
    _desktopSource.Navigate(_mpvHostHwnd);
    MPVHostGrid.Children.Add(_desktopSource);
}

// 窗口过程委托
private delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
private IntPtr DefWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
    return Win32Native.DefWindowProc(hWnd, msg, wParam, lParam);
}

3.3 清理资源避免泄漏

在HomePage的Unloaded事件中释放资源:

private void HomePage_Unloaded(object sender, RoutedEventArgs e)
{
    _mpvPlayer?.Dispose();
    if (_mpvHostHwnd != IntPtr.Zero)
    {
        Win32Native.DestroyWindow(_mpvHostHwnd);
    }
    _desktopSource?.Dispose();
}

4. 配置XAML布局

在HomePage的XAML中添加用于承载Win32窗口的Grid:

<Grid x:Name="MPVHostGrid" Loaded="HomePage_Loaded" Unloaded="HomePage_Unloaded"/>

替代方案:修复WindowsFormsHost使用问题

若你坚持使用WinFormsHost,需完成以下配置:

  • 安装Microsoft.WindowsAppSDK和System.Windows.Forms NuGet包
  • 在项目文件中启用Windows Forms兼容:
<PropertyGroup>
  <UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
  • 在XAML中添加WindowsFormsHost及承载控件:
<WindowsFormsHost x:Name="WinFormsHost">
    <wf:Panel x:Name="MPVPanel"/>
</WindowsFormsHost>
  • 初始化时传入Panel的句柄:
_mpvPlayer = new MpvPlayer(MPVPanel.Handle, "path/to/libmpv-2.dll");

内容的提问来源于stack exchange,提问作者PigeonMuyz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 09:47:36