实现IDocHostUIHandler.c#中的FilterDataObject
本文关键字:FilterDataObject 中的 IDocHostUIHandler 实现 | 更新日期: 2023-09-27 18:17:07
我试图添加一个HTML功能的编辑器到WPF应用程序。显而易见的选择是使用默认的WebBrowser控件,并将其文档置于"设计模式"。到目前为止,一切顺利。
现在,它变得棘手了,因为我需要能够拦截从剪贴板粘贴到编辑器中的内容,以确保它是可用的格式。例如,当从包含图像的Word文档中粘贴一个片段时,该图像由一段Office XML表示,而浏览器控件无法理解该图像,因此我需要在将其插入文档之前将其替换为一个简单的标记。
在意识到没有办法在纯WPF级别上实现这一点之后,我不得不深入到WebBrowser控件只是一个包装器的ActiveX组件。似乎我的问题(以及我也面临的其他一些问题,但与这个问题无关)可以通过提供IDocHostUIHandler
接口的自定义实现来解决。
这个接口包含一个叫做FilterDataObject
的方法,当粘贴操作发生时,它显然会被调用,给实现一个检查的机会,并在必要时更改浏览器从剪贴板接收到的数据。
作为参考,以下是IDocHostUIHandler接口中方法的定义:
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("bd3f23c0-d43e-11cf-893b-00aa00bdce1a")]
public interface IDocHostUIHandler {
// ...
[PreserveSig]
int FilterDataObject(
[In, MarshalAs(UnmanagedType.Interface)] object pDO,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppDORet
);
}
传入的COM对象可以强制转换为System.Runtime.InteropServices.ComTypes.IDataObject
,并且可以很好地访问剪贴板内容。但是当我实际尝试通过out参数返回一个替换IDataObject时,我得到了一个访问冲突异常。
例如,简单地返回现有类System.Windows.DataObject
的一个新实例(它也实现了...ComTypes.IDataObject
,所以我希望CLR能够正确地封送它开箱即用),就像这样…
public class MyDocHostUIHandler : IDocHostUIHandler {
// ...
public int FilterDataObject(object pDO, out object ppDORet) {
ppDORet = new System.Windows.DataObject("Text", "New Clipboard Content!");
return S_OK; // S_OK means that the data object has been replaced
}
}
…不工作(AccessViolationException,只要我试图粘贴任何东西到编辑器)。
有人做过这样的事吗?我可能做错了什么?我的comimport接口的定义是否有问题(在网上很难找到一个真正有效的版本——至少在某些时候——开始)?我想做的是什么,甚至可能从托管代码?
Try [return: MarshalAs(UnmanagedType.I4)] int FilterDataObject(System.Runtime.InteropServices.ComTypes. com)。IDataObject pDO, out System.Runtime.InteropServices.ComTypes.IDataObject ppDORet);}
如果在为COM接口生成签名时遇到问题,通常可以使用midl和tlbimp从Windows SDK工具生成。