How to get the original IDocHostUIHandler provided by Internet Explorer?
In the documentation of the IDocHostUIHandler Interface, there is a paragraph about the default UI handler provided by IE when talking about a memory leak caused by using ICustomDoc from a BHO:
To avoid a memory leak:
1. Always forward the IDocHostUIHandler::ShowUI and
IDocHostUIHandler::HideUI methods to the original handler.
2. Release the pointer to the original UI handler when your object is called
with IObjectWithSite::SetSite(NULL).
开发者_运维百科
How to get the host interface in order to release it?
While not officially supported, you can still get a reference to the original IDocHostUIHandler
in order to pass calls through on all of the methods you don't plan on overriding in your BHO.
First you cast the document as an IOleObject
and then call GetClientSite
in order to obtain the original IOleClientSite
object. This can then be cast to either IDocHostUIHandler
or IOleCommandTarget
in order to call the methods from those interfaces on the original handler/target.
Here is an example code snippet from the DocumentComplete event of a C# BHO (Explorer
is an instance of ShDocVw.WebBrowserClass
, UIHandler
is my own IDocHostUIHandler
class which passes calls through to the object passed in the initializer, and all of the interfaces were taken directly from http://pinvoke.net):
IOleObject obj = Explorer.Document as IOleObject;
if (obj != null)
{
IOleClientSite cs = null;
obj.GetClientSite(ref cs);
if (cs != null)
{
ICustomDoc cDoc = Explorer.Document as ICustomDoc;
if (cDoc != null)
{
cDoc.SetUIHandler(new UIHandler(cs));
}
}
}
This was adapted from C++ code available in the PopupBlocker project available here http://www.codeproject.com/Articles/4003/Popup-Window-Blocker
The whole passage nowadays reads
It is not intended to replace an existing IDocHostUIHandler that is provided by Internet Explorer or the WebBrowser control. If you try to replace that interface from a Browser Helper Object (BHO) using ICustomDoc, you may experience unexpected behavior such as memory leaks.
So it is simply not supported what you are trying to do (at least officially).
精彩评论