迅雷APlayer官方论坛有大佬使用 APlayerCaller.dll 做了个C# Winform 开发的例子,同样的可以轻松移植到 WPF 上,但是这方法也会出现一个严重的问题:在使用 APlayerCaller.dll 创建新的 AP 对象的时候需要设置父控件/窗体,他是通过传入指定的句柄来明确其归属关系的。
原文:http://aplayer.open.xunlei.com/bbs/read.php?tid=468875
但是!!!WPF的控件是没有句柄的,不是指没有.Handle这个属性(当然也没有)。而是!WPF 的控件都是画出来的,不具有独立的句柄,是画!出!来!的,都是像素点而已。画布一层一层而已!
所以用关键字“WPF 控件 句柄”搜到的类似这样的方案,行不通
1、在WPF中,获取当前窗体的句柄与WINFORM中不一样: WINFORM直接获取:this.Handle----------this是窗体的类名,handle就是句柄。 2、WPF中先引用命名空间:System.Windows.Interop; IntPtr hwnd = new WindowInteropHelper(this).Handle;----this就是要获取句柄的窗体的类名; 3、控件句柄,同样引用 :System.Windows.Interop: IntPtr hwnd = ((HwndSource)PresentationSource.FromVisual(uielement)).Handle;----uielement就是要获取句柄的控件,该控件必须继承自UIElement。
事实上,获取 WPF 控件的句柄是根本不可能的。大家应该都知道,要获取WinForm控件的句柄相当简单,是因为WinForm是通过GDI+来渲染界面,每个控件都拥有自己的句柄,但是 WPF 的界面是由 DirectX 渲染,除了 Window(窗体) 本身,其他部分都没有句柄。
你用控件也只能获取到窗体的句柄,wpf 上所有的控件用这个方法获取的句柄都跟窗口是同一个,因为它们是画出来的!
所以就只能用最原始的方案了,在 WPF 里调用 Winform 的控件了(尽管想极力避免这样子,空域问题):
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration" <wfi:WindowsFormsHost> <wf:Panel x:Name="m_LeftPanel" Margin="5, 5, 5, 5" BackColor="#22ffffff" /> </wfi:WindowsFormsHost>
空域解决备选方案
步骤一:到下面的连接中下载源码:
https://archive.codeplex.com/?p=microsoftdwayneneed
根据自己项目所用的 .net framework 版本编译对应版本的 dll,得到下面 2 个 dll
Microsoft.DwayneNeed.dll Microsoft.DwayneNeed.Win32.dll
在项目中添加引用,引入命名空间:
xmlns:airspace="clr-namespace:Microsoft.DwayneNeed.Interop;assembly=Microsoft.DwayneNeed"
xmal中写法:
<Grid> <airspace:AirspaceDecorator AirspaceMode="Redirect" IsInputRedirectionEnabled="True" IsOutputRedirectionEnabled="True"> <WindowsFormsHost Name="FormsHost"> <wf:Panel x:Name="PART_PanelContainer"/> </WindowsFormsHost> </airspace:AirspaceDecorator> </Grid>
这个在编辑 XAML 文件的时候会报错,直接忽略后可以编译成功,并且AP播放器上成功叠加其他 WPF 控件,不够完美。
目前最优的方法应该还是AP控件跟窗体绑定,所有其他WPF控件都悬浮在 AP 控件之上,虽然会遮挡视频,做半透明应该会缓解很多。
记录一下 WPF 调用 Winform 控件缺陷太大 ,死了这条心。