3

WebBrowser我已经从具有自己实现的控件创建了派生控件,该控件IDocHostUIHandler遵循方法的想法CreateWebBrowserSiteBase

WebBrowser.WebBrowserSite 类提供 OLE IDocHostUIHandler 接口的默认实现。您可以提供自己的此接口实现或实现任何其他 WebBrowser ActiveX 控件接口,以自定义控件的行为。

不工作的问题。我的代码如下所示:

[PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
public MyBrowser(){}

protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
{
    var manager = new NewWebBrowserSite(this);
    return manager;
}

protected class NewWebBrowserSite : WebBrowserSite, 
    UnsafeNativeMethods.IDocHostUIHandler
{
    private MyBrowser host;
    public NewWebBrowserSite(MyBrowser h)
        : base(h)
    {
        this.host = h; 
    }

    int UnsafeNativeMethods.IDocHostUIHandler.ShowContextMenu(int dwID, NativeMethods.POINT pt, object pcmdtReserved, object pdispReserved)
    {
        MyBrowser wb = (MyBrowser)this.host;
        // other code
    }

    // rest of IDocHostUIHandler methods
}

我的问题是:

  1. 我是否必须实现其他接口才能使其正常工作?
  2. 是设计使然吗,我读过一些帖子,它与 .net 框架实现中的错误有关WebBrowser

我知道这是可能的ICustomDoc.SetUIHandler,但这不是我想要的。

我曾经有过放弃 c# 并使用非托管代码的想法。是这样吗?

4

2 回答 2

4

我刚刚处理了完全相同的问题:如何为IDocHostUIHandlerWinFormsWebBrowser控件提供自定义实现。问题是基类WebBrowserSite已经实现了自己的版本IDocHostUIHandler(这是一个internal接口,所以不可能在派生类中显式地重新实现NewWebBrowserSite它)。但是,理论上,用相同的 GIID 和方法布局实现另一个 C# 接口应该不是问题(因为在这种特殊情况下,这就是所有 COM 客户端 - 底层 WebBrowser ActiveX 控件 - 所关心的)。

不幸的是,在 .NET 4.0 之前这是不可能的。幸运的是,现在它是通过新的ICustomQueryInterface功能实现的:

protected class NewWebBrowserSite : WebBrowserSite, 
    UnsafeNativeMethods.IDocHostUIHandler
    ICustomQueryInterface
{
    private MyBrowser host;
    public NewWebBrowserSite(MyBrowser h): base(h)
    {
        this.host = h; 
    }

    int UnsafeNativeMethods.IDocHostUIHandler.ShowContextMenu(int dwID, NativeMethods.POINT pt, object pcmdtReserved, object pdispReserved)
    {
        MyBrowser wb = (MyBrowser)this.host;
        // other code
    }

    // rest of IDocHostUIHandler methods

    // ICustomQueryInterface

    public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr ppv)
    {
        if (iid == typeof(UnsafeNativeMethods.IDocHostUIHandler).GUID)
        {
            ppv = Marshal.GetComInterfaceForObject(this, typeof(UnsafeNativeMethods.IDocHostUIHandler), CustomQueryInterfaceMode.Ignore);
        }
        else
        {
            ppv = IntPtr.Zero;
            return CustomQueryInterfaceResult.NotHandled;
        }
        return CustomQueryInterfaceResult.Handled;
    }   
}
于 2013-10-30T13:48:12.513 回答
1

您不能简单地覆盖类实现的接口。如果 IDocHostUIHandler 的方法未标记为虚拟,则无法替换它们。

定义接口的事实UnsafeNativeMethods也是一个线索,除非您非常清楚自己在做什么,否则您可能不应该弄乱它。

于 2013-03-20T04:57:43.187 回答