这是挑战.我来自Framework的WebBrowserSite类.我的派生类的实例ImprovedWebBrowserSite是通过WebBrowser.CreateWebBrowserSiteBase,我在我的WebBrowser类的派生版本中重写- 特别是提供自定义站点对象.Framework的WebBrowser实现进一步将其传递给底层的非托管WebBrowser ActiveX控件.
到目前为止,我已经设法IDocHostUIHandler在我的ImprovedWebBrowserSite实现中覆盖(像这样).我现在正在寻找更多核心COM接口,比如IOleClientSite,我想要传递给它WebBrowserSite.所有这些都暴露在与COM ComImport,但声明private或internal由框架实施的WebBrowserSite/ UnsafeNativeMethods.因此,我无法在派生类中明确地重新实现它们.我必须像我一样定义自己的版本IDocHostUIHandler.
所以,问题是,如何WebBrowserSite从我的派生类中调用定义的私有或内部COM接口的方法?例如,我想打电话IOleClientSite.GetContainer.我可以使用反射(像这样),但这将是最后的手段,其次是WebBrowser从头开始重新实现.
我的想法是,因为Framework的私有UnsafeNativeMethods.IOleClientSite和我自己ImprovedWebBrowserSite.IOleClientSite都是COM接口,用ComImport属性声明,相同的GUID和相同的方法签名..NET 4.0+中有COM类型等价,因此必须有一种方法可以在没有反射的情况下完成.
[更新]现在我已经有了一个解决方案,我相信它为自定义WinForms版本的WebBrowser控件开启了一些新的和有趣的可能性.
这个版本的问题是在我最初尝试以更抽象的形式表达问题之后创建的,被评论员称为误导.评论已被删除,但我决定保留这两个版本.
为什么我不想用反射来解决这个问题?原因如下:
依赖于实现者给出的内部或私有方法的实际符号名称WebBrowserSite,与COM接口不同,它与二进制v表合同有关.
庞大的反射代码.例如,考虑调用base的私有TranslateAcceleratorvia Type.InvokeMember …
.NET interop将COM对象包装到.NET对象(运行时可调用包装器,RCW)中,这些对象隐藏了通常的接口查询.为了使用运行对象表注册表示过滤器图的COM对象,我需要其IUnknown接口的(本机)地址(请参阅如何对DirectShow图进行反向工程?).
所以问题是:如何在C#中获取COM对象的IUnknown指针?