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

Which IE tab is calling IInternetProtocol->Start

358 views
Skip to first unread message

BartMichael

unread,
Dec 30, 2009, 2:18:02 PM12/30/09
to
Hello!
I have a browser helper object (Internet Explorer DLL) implementing
IInternetProtocol. It is registered and works fine.

In Internet Explorer 7 and especially 8, when we open many tabs:

How to detect which tab is calling IInternetProtocol->Start?

So far (spending few days) I have found that:
a) Testing GetCurrentThreadId does not work. IInternetProtocol->Start
is often called in a thread different from the main thread of a tab
(=BHO DLL main thread).

b) We should implement IHttpNegotiate - see Igor's post
http://groups.google.com/group/microsoft.public.inetsdk.programming.webbrowser_ctl/browse_frm/thread/3a255f3cf3f827df
and in IHttpNegotiate->BeginningTransaction we should obtain
IWindowForBindingUI->GetWindow
and compare it with IWebBrowser2->Document as IOleWindow->GetWindow


1) How to get IHttpNegotiate working? I have found two descriptions:
A) implement IServiceProvider in the same object (with
IInternetProtocol?) and return IHttpNegotiate pointer from
IServiceProvider->QueryService. Will QueryService be called by
Internet Explorer automatically or should we call a function?

B) in IInternetProtocol->Start call something like:
CreateURLMonikerEx(null, Url, FMoniker, URL_MK_UNIFORM); //or
URL_MK_LEGACY. CreateURLMoniker is outdated in IE 7/8
CreateAsyncBindCtx(0, this, null, FBindCtx);
RegisterBindStatusCallback(FBindCtx, this, pPrevBSCB, 0);
FMoniker->BindToStorage(FBindCtx, null, IStream, FStream);

2) Should IHttpNegotiate be implemented in the same object with
IInternetProtocol?

3) How to obtain IServiceProvider, if our IHttpNegotiate is NOT the
same object as IInternetProtocol?
If IHttpNegotiate is implemented IN THE SAME OBJECT with
IInternetProtocol, we can use OIProtSink from IInternetProtocol->Start
(if Start is called BEFORE IHttpNegotiate->BeginningTransaction)
OIProtSink->QueryInterface gives us IServiceProvider
IServiceProvider->QueryService gives IWindowForBindingUI
Finally we get IWindowForBindingUI->GetWindow

Sorry for askong this questioon, but I spent few days searching on the
Internet and testing my code.

I would be very grateful for any suggestions.

Best regards
Bart Michael

Igor Tandetnik

unread,
Dec 30, 2009, 3:02:35 PM12/30/09
to
BartMichael wrote:
> How to detect which tab is calling IInternetProtocol->Start?
>
> b) We should implement IHttpNegotiate - see Igor's post
> http://groups.google.com/group/microsoft.public.inetsdk.programming.webbrowser_ctl/browse_frm/thread/3a255f3cf3f827df
> and in IHttpNegotiate->BeginningTransaction we should obtain
> IWindowForBindingUI->GetWindow
> and compare it with IWebBrowser2->Document as IOleWindow->GetWindow

Did you try Switch/Continue trick as described in that thread? It appears to be necessary.

> 1) How to get IHttpNegotiate working? I have found two descriptions:
> A) implement IServiceProvider in the same object (with
> IInternetProtocol?)

With IInternetProtocolSink.

> and return IHttpNegotiate pointer from
> IServiceProvider->QueryService. Will QueryService be called by
> Internet Explorer automatically

Yes. By the built-in HTTP protocol handler, to be precise (I'm assuming your APP is forwarding to the built-in APP).

> B) in IInternetProtocol->Start call something like:
> CreateURLMonikerEx(null, Url, FMoniker, URL_MK_UNIFORM); //or
> URL_MK_LEGACY. CreateURLMoniker is outdated in IE 7/8
> CreateAsyncBindCtx(0, this, null, FBindCtx);
> RegisterBindStatusCallback(FBindCtx, this, pPrevBSCB, 0);
> FMoniker->BindToStorage(FBindCtx, null, IStream, FStream);

Depending on how you register your APP, that will probably just create a new instance of your APP and call Start on it, expecting it to perform an HTTP request.

> 2) Should IHttpNegotiate be implemented in the same object with
> IInternetProtocol?

It's mostly irrelevant which object it's implemented on.

> 3) How to obtain IServiceProvider, if our IHttpNegotiate is NOT the
> same object as IInternetProtocol?

The real client's IServiceProvider can be queried from IInternetProtocolSink which you get in Start.

> If IHttpNegotiate is implemented IN THE SAME OBJECT with
> IInternetProtocol, we can use OIProtSink from IInternetProtocol->Start
> (if Start is called BEFORE IHttpNegotiate->BeginningTransaction)
> OIProtSink->QueryInterface gives us IServiceProvider
> IServiceProvider->QueryService gives IWindowForBindingUI
> Finally we get IWindowForBindingUI->GetWindow

IWindowForBindingUI::GetWindow only works from the main STA thread (otherwise it returns NULL), and Start is called on a worker thread more often than not. That's why you need Switch/Continue. IHttpNegotiate is a red herring - you don't need anything to do with it in order to get IWindowForBindingUI::GetWindow to work (back when that discussion occurred, I mistakenly believed otherwise).
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925

BartMichael

unread,
Dec 30, 2009, 3:52:44 PM12/30/09
to
Thank You VERY much Igor!!! You really know EVERYTHING about IE :-)

I will try to implement Your solution.

Best regards
Bart

0 new messages