天天看點

WPF 擷取 MediaContext 的方法

本文告訴大家如何通過反射擷取 MediaContext 對象。在 WPF 裡面,通過 MediaContext 對象可以用來控制渲染

在調試下,通過 Dispatcher 對象,可以看到有 Reserved0 不公開的屬性,此屬性就是 MediaContext 對象,如下面方法,通過反射擷取此屬性

var propertyInfo = typeof(Dispatcher).GetProperty("Reserved0", BindingFlags.NonPublic | BindingFlags.Instance);
            var mediaContext = propertyInfo.GetMethod.Invoke(Dispatcher, null);           

複制

如此即可擷取到 MediaContext 對象

接下來可以通過程式集擷取 MediaContext 類型,進而實作反射調用方法

var mediaContextType = typeof(Visual).Assembly.GetType("System.Windows.Media.MediaContext");           

複制

如嘗試自己調用 DUCE 觸發渲染

var methodInfoGetChannels = mediaContextType.GetMethod("GetChannels", BindingFlags.NonPublic | BindingFlags.Instance);
            var channelSet = methodInfoGetChannels.Invoke(mediaContext, null);

            var typeChannelSet = typeof(Visual).Assembly.GetType("System.Windows.Media.Composition.DUCE+ChannelSet");
            var fieldInfoChannel = typeChannelSet.GetField("Channel", BindingFlags.NonPublic | BindingFlags.Instance);
            var channel = fieldInfoChannel.GetValue(channelSet);

            var typeChannel = typeof(Visual).Assembly.GetType("System.Windows.Media.Composition.DUCE+Channel");
            var hChannelFieldInfo = typeChannel.GetField("_hChannel", BindingFlags.NonPublic | BindingFlags.Instance);
            var hChannel = (IntPtr)hChannelFieldInfo.GetValue(channel);

            ResourceHandle handle = default;
            var result = MilResource_CreateOrAddRefOnChannel(hChannel, ResourceType.TYPE_BRUSH, ref handle);

        [DllImport(MilCore)]
        internal static extern /*HRESULT*/ int MilResource_CreateOrAddRefOnChannel(
            IntPtr pChannel,
            ResourceType resourceType,
            ref ResourceHandle hResource
        );

        internal const string WCP_VERSION_SUFFIX = "_cor3";
        internal const string MilCore = "wpfgfx" + WCP_VERSION_SUFFIX + ".dll";           

複制

本文所有代碼放在 github 和 gitee 歡迎通路

可以通過如下方式擷取本文代碼

先建立一個空檔案夾,接着使用指令行 cd 指令進入此空檔案夾,在指令行裡面輸入以下代碼,即可擷取到本文的代碼

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 23c0515af613acc5025f95c17ea254fc573375ce           

複制

以上使用的是 gitee 的源,如果 gitee 不能通路,請替換為 github 的源

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git           

複制

擷取代碼之後,進入 LereleweawaLinojairgeefonechal 檔案夾