Reputation: 823
I have created derived control from WebBrowser
control that has own IDocHostUIHandler
implementation following idea from CreateWebBrowserSiteBase
method:
The WebBrowser.WebBrowserSite class provides default implementations of the OLE IDocHostUIHandler interface. You can provide your own implementation of this interface or implement any other WebBrowser ActiveX control interface in order to customize the behavior of the control.
The problem that is not working. My code looks next way:
[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
}
My questions are:
WebBrowser
I know that is possible to go ICustomDoc.SetUIHandler
way, but it is not what I am looking for.
I was having idea at some point to give up with c# and do that with unmanaged code. Is that the way?
Upvotes: 3
Views: 1905
Reputation: 61726
I've just dealt with exactly the same problem: how to provide a custom implementation of IDocHostUIHandler
to WinForms WebBrowser
control. The problem is that the base class WebBrowserSite
has already implemented its own version of IDocHostUIHandler
(which is an internal
interface, so it's not possible to explicitly re-implement it in the derived class NewWebBrowserSite
). However, in theory it should not be a problem to implement another C# interface with the same GIID and methods layout (because that's all the COM client - the underlying WebBrowser ActiveX Control - cares about in this particular case).
Unfortunately, it was not possible until .NET 4.0. Luckily, now it is, by means of the new ICustomQueryInterface feature:
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;
}
}
Upvotes: 4
Reputation: 3785
You can't simply override the interfaces implemented by a class. If the methods for IDocHostUIHandler are not marked as virtual, you can't replace them.
The fact that the interface is defined in UnsafeNativeMethods
is also a clue that you probably shouldn't be messing with it unless you have a very good idea of what you're doing.
Upvotes: 1