Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

BHO & IDocHostUIHandler

81 views
Skip to first unread message

Gsw.Zero

unread,
Sep 2, 2004, 6:24:30 AM9/2/04
to
[Environment: Windows XP SP2, IE 6.0 SP2; Visual C++ 6.0 SP6, Platform SDK Feb.
2003.]

I am implementing a BHO object using ATL and the ATL object calls at a certain
point SetUIHandler, as in the following sequence (error handling omitted):

HRESULT CFindHook::ChangeUIHandler()
{
CComPtr<IDispatch> spDoc;
m_spWebBrowser2->get_Document(&spDoc);
CComPtr<ICustomDoc> spCustomDoc;
spDoc->QueryInterface(IID_ICustomDoc, (void **)&spCustomDoc);
CComPtr<IDocHostUIHandler> spDocHostUIHandler;
QueryInterface(IID_IDocHostUIHandler, (void **)&spDocHostUIHandler);
spCustomDoc->SetUIHandler(spDocHostUIHandler);
}

(IObjectWithSite' s GetSite and SetSite are doing "the normal things" in almost
all the samples - as storing IWebBrowser2 object, calls Advise, get main browser
window and subclass it).
No hooks are installed, only window subclassing and browser event advise.

Both the Internet Explorer main window (IEFrame) and browser window
(Internet_Explorer Server) are subclassed, and the window procedures simply
calls the previous (default) procedure, as in the following example for browser
window (again error handling is omitted):

// set this as property for retrieval in window procedure
::SetProp(m_hwndBrowser, CFindHook::s_lpcszThisPropName, (HANDLE)(this));
// ...
// replace window procedure
m_lpfnBrowserWndProc = (WNDPROC)SetWindowLong(m_hwndBrowser, GWL_WNDPROC,
(LONG)BrowserWndProc);

and the window procedure is:

LRESULT CALLBACK CFindHook::BrowserWndProc(HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
CFindHook *pFindHook = (CFindHook *)::GetProp(hWnd,
CFindHook::s_lpcszThisPropName);
if((pFindHook != NULL) && (pFindHook->m_lpfnBrowserWndProc))
return ::CallWindowProcW(pFindHook->m_lpfnBrowserWndProc, hWnd, uMsg,
wParam, lParam);

return ::DefWindowProc(hWnd, uMsg, wParam, lParam); // should not happen -->
failsafe
}

The main browser window procedure follows the same trivial idea.

The implementation of IDocHostUIHandler is trivial, and follows the
recommendations from
http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/hosting/wbcustomization.asp

ShowContextMenu, ShowUI, GetExternal, TranslateUrl and FilterDataObject returns
S_FALSE (and sets the output variables, if any, to NULL).
The rest of the methods return E_NOTIMPL.

Problems:
1. Invoking the "Find (on This Page...) Ctrl+F" dialog from Ctrl+F
accelerator works, but not from the Edit menu item.
2. Trying to select some text with the mouse in a page does not work (nothing
happens). Select All (Ctrl+A) accelerator works instead.

If I comment ChangeUIHandler call everything is normal, so I think that the
implementation of IDocHostUIHandler is either incomplete, or there are also
other interfaces to implement (IOleClientSite? IOleInPlaceSite? IOleWindow?
others as well?).

The same above link mention also that the client (IE, in this case) should call
OleInitialize instead of CoInitialize:
********
[begin quote]
There are a few more important points to remember when initializing the
WebBrowser Control. Your application should use OleInitialize rather than
CoInitialize to start COM. OleInitialize enables support for the Clipboard,
drag-and-drop operations, OLE, and in-place activation. Use OleUninitialize to
close the COM library when your application shuts down.

The ATL COM Wizard uses CoInitialize rather than OleInitialize to open the COM
libraries. If you use this wizard to build an executable program, you need to
change the CoInitialize and CoUninitialize calls to OleInitialize and
OleUninitialize. For a Microsoft Foundation Classes (MFC) application, be sure
that your application calls AfxOleInit, which calls OleInitialize, in its
initialization process.
[end quote]
********

Can anyone help me with an idea to locate the cause of the problems mentioned
above? (Igor... ? :) ).

Many thanks,
Cristian Amarie


Igor Tandetnik

unread,
Sep 2, 2004, 10:12:59 AM9/2/04
to
"Gsw.Zero" <gsw...@hotmail.com> wrote in message
news:e5oCHcNk...@TK2MSFTNGP10.phx.gbl

> I am implementing a BHO object using ATL and the ATL object calls at
> a certain point SetUIHandler, as in the following sequence (error
> handling omitted):
>
> Problems:
> 1. Invoking the "Find (on This Page...) Ctrl+F" dialog from Ctrl+F
> accelerator works, but not from the Edit menu item.

Don't know what could possibly cause this.

> 2. Trying to select some text with the mouse in a page does not work
> (nothing happens). Select All (Ctrl+A) accelerator works instead.

Do you, by any chance, set DOCHOSTUIFLAG_DIALOG flag in
IDocHostUIHandler::GetHostInfo?

Do the problems still occur is you don't subclass the windows, but only
set IDocHostUIHandler? You don't seem to need subclassing anyway - your
window proc does not do anything useful.

Also, be aware that "Internet_Explorer Server" window is not permanent -
it is often destroyed and a new one created. For example, go to an HTML
page, then to a PDF document, then to another HTML page - you will see
that Internet_Explorer Server window now has a different HWND handle. So
you will have to keep track of it and resublcass every time a new such
window is created (assuming you really need to subclass, which I don't
see any indication of).
--
With best wishes,
Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken


Gsw.Zero

unread,
Sep 2, 2004, 10:31:58 AM9/2/04
to
> Do you, by any chance, set DOCHOSTUIFLAG_DIALOG flag in
> IDocHostUIHandler::GetHostInfo?
R: No. GetHostInfo just returns E_NOTIMPL.

> Do the problems still occur is you don't subclass the windows, but only set
> IDocHostUIHandler?
> You don't seem to need subclassing anyway - your window proc does not do
> anything useful.

R: At the time when I wrote the message it does not, but now does a keyboard
trap and some message handling (already implemented and working correctly).

> Also, be aware that "Internet_Explorer Server" window is not permanent -
> it is often destroyed and a new one created. For example, go to an HTML
> page, then to a PDF document, then to another HTML page - you will see
> that Internet_Explorer Server window now has a different HWND handle. So
> you will have to keep track of it and resublcass every time a new such
> window is created (assuming you really need to subclass, which I don't
> see any indication of).

R: Thanks for the tip - I know that Internet_Explorer Server is often changed
(that's why the window retrieval and subclass is done in Invoke); also may be
other windows as well containing such a window class (toolbars containing
WebBrowser objects, for example) etc.

Seems that the only disturbing call is SetUIHandler.

I'll continue looking on myself and, if I'll find a solution, I'll post it.

Thanks again,
Cristian Amarie


Gsw.Zero

unread,
Sep 3, 2004, 12:43:05 PM9/3/04
to
It was IDocHostUIHandler::GetHostInfo.
It seems that it should return S_FALSE instead of E_NOTIMPL (don't ask :) -
trial an error).

MSDN:
Return Value: Returns S_OK if successful, or an error value otherwise.

Me :)
Return value:
Returns S_OK to inform back MSHTML that the host returned its UI
capabilities.
Returns S_FALSE if the host does not attempt to change UI capabilities and
let MSHTML to use its default behavior.
(?) Returns an error value to inform MSHTML that the host UI capabilities
could not be set. *

* I don't know what MSHTML will do in this case (see E_NOTIMPL returned).

Another question about what you told me in the previous message:


>> Also, be aware that "Internet_Explorer Server" window is not permanent -
>> it is often destroyed and a new one created.

There is a programmatic way - even undocumented - as a DISPID_ handling, windows
message etc. that tells
"a new Internet_Explorer Server was created (or about to be created)" ?

Many thanks,
Cristian Amarie


"Gsw.Zero" <gsw...@hotmail.com> wrote in message

news:uPnVbmP...@TK2MSFTNGP12.phx.gbl...

Igor Tandetnik

unread,
Sep 3, 2004, 12:55:40 PM9/3/04
to
"Gsw.Zero" <gsw...@hotmail.com> wrote in message
news:u0nqXUdk...@tk2msftngp13.phx.gbl

> Another question about what you told me in the previous message:
>>> Also, be aware that "Internet_Explorer Server" window is not
>>> permanent - it is often destroyed and a new one created.
>
> There is a programmatic way - even undocumented - as a DISPID_
> handling, windows message etc. that tells
> "a new Internet_Explorer Server was created (or about to be created)"
> ?

I'd probably just compare the current HWND with the one I subclassed
earlier every time NavigateComplete2 event fires. Alternatively, your
subclassing window proc should see WM_DESTROY message when the current
window is about to be destroyed - that should give you a clue. However,
I'm not sure whether the new window is already created by this time and
can be accessed.


--
With best wishes,
Igor Tandetnik

"On two occasions, I have been asked [by members of Parliament], 'Pray,
Mr. Babbage, if you put into the machine wrong figures, will the right
answers come out?' I am not able to rightly apprehend the kind of
confusion of ideas that could provoke such a question." -- Charles
Babbage


0 new messages