Here is the challenge. I'm deriving from the Framework's WebBrowserSite
class. An instance of my derived class, ImprovedWebBrowserSite
, is returned via WebBrowser.CreateWebBrowserSiteBase
, which I override in my derived version of the WebBrowser
class - specifically to provide a custom site object. The Framework's WebBrowser
implementation further passes it to down to the underlying unmanaged WebBrowser ActiveX control.
So far, I've managed to override IDocHostUIHandler
in my ImprovedWebBrowserSite
implementation (like this). I'm now looking for more core COM interfaces, like IOleClientSite
, which I want to pass-through to WebBrowserSite
. All of them are exposed to COM with ComImport
, but declared as private
or internal
by the Framework's implementation of WebBrowserSite
/UnsafeNativeMethods
. Thus, I cannot explicitly re-implement them in the derived class. I have to define my own versions, like I did with IDocHostUIHandler
.
So, the question is, how do I call a method of a private or internal COM interface defined in WebBrowserSite
, from my derived class? For example, I want to call IOleClientSite.GetContainer
. I can use reflection (like this), but that would be the last resort, second to re-implementing WebBrowser
from scratch.
My thinking is, because the Framework's private UnsafeNativeMethods.IOleClientSite
and my own ImprovedWebBrowserSite.IOleClientSite
are both COM interfaces, declared with the ComImport
attribute, the same GUID and identical method signatures. There's COM Type Equivalence in .NET 4.0+, so there has to be a way to do it without reflection.
[UPDATE] Now that I've got a solution, I believe it opens some new and interesting possibilities in customizing the WinForms version of WebBrowser
control.
This version of the question was created after my initial attempt to formulate the problem in a more abstract form was dubbed misleading by a commentator. The comment has been removed later, but I decided to keep both versions.
Why did I not want to use reflection to solve this problem? For a few reasons:
Dependency on the actual symbolic names of the internal or private methods, as given by the implementers of WebBrowserSite
, unlike with a COM interface, which is about the binary v-table contract.
Bulky reflection code. E.g., consider calling the base's private TranslateAccelerator
via Type.InvokeMember
, and I have ~20 methods like that to call.
Although less important, efficiency: a late-bound call via reflection is always less efficient than a direct call to a COM interface method via v-table.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…