using only MSHTML (i'm doing CoCreateInstance(CLSID_HTMLDocument,..)),
how can i detect navigation errors, like 404.
thanks.
Nicolas
I have not tried it myself, but I believe MSHTML will use your
implementation of IBindHost if you provide one. If it does, then you can
use IBindHost::MonikerBindToStorage to install your own
IBindStatusCallback implementation and watch the progress of the
download operation. Don't forget to forward all method calls to
IBindStatusCallback that MSHTML provides.
--
With best wishes,
Igor Tandetnik
"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken
Also I tried to register my own IBindStatusCallback to the bind
context, but as soon as MSHTML start streaming it replaces it by its
own.
And then it fails if i try to replace it with mine after MSHTML
started streaming....
Any idea what object i could overload to try to get the calls and get
HTTP request status back ? i'm thinking implementing my own IBindCtx
right now.. but i'm afraid it may be more work tha needed...
thanks
"Igor Tandetnik" <itand...@mvps.org> wrote in message news:<ODDGiWAS...@TK2MSFTNGP12.phx.gbl>...
If it is called at all, it should be called with SID_SBindHost as the
first parameter (which is the same as IID_IBindHost).
> Any idea what object i could overload to try to get the calls and get
> HTTP request status back ? i'm thinking implementing my own IBindCtx
> right now.. but i'm afraid it may be more work tha needed...
Now that I think of it, it's an interesting idea, and it just might
work. Here's how I'd go about it. Write an object implementing IBindCtx.
Internally, it creates a stock IBindCtx implementation with
CreateBindCtx, and forwards almost all method calls to it. It also
stores IBindStatusCallback object you want to use to intercept the
notifications.
The two method calls your bind context object does not forward are
RegisterObjectParam and GetObjectParam, when called with the key of
"_BSCB_Holder_". That's what RegisterBindStatusCallback uses to put an
IBindStatusCallback pointer into the bind context. So when
RegisterObjectParam is called with this key, you cache
IBindStatusCallback pointer passed as the second parameter - this is the
one supplied by MSHTML. When GetObjectParam is called with this key, you
return your IBindStatusCallback. Now you should be able to preview all
notifications. Don't forget to forward all calls to MSHTML's callback.
If you end up trying this technique out, please post the result to the
group, whether positive or negative. It could be useful, assuming it
works.
Another way is with a Passthrough APP - see
http://groups.google.com/groups?selm=u0bu6ca6DHA.2556%40TK2MSFTNGP09.phx.gbl
That's considerably more complicated.
After the call to IPersistMoniker->Load(), I successfully start
receiving calls on my custom IBindStatusCallback object. GetBindInfo()
and OnStartBinding() both get called... But then, sadly, before the
ReadyState gets to "Complete" an access violation occurs. I am
guessing that MSHTML might be QueryInterface()'ing for for some other
interface that my custom IBindStatusCallback object doesn't implement.
"Igor Tandetnik" <itand...@mvps.org> wrote in message news:<u5JxWIbS...@TK2MSFTNGP11.phx.gbl>...
Can you place a breakpoint in QueryInterface and see what you are being
queried for? Also, make sure your reference counting is correct. A crash
right before the end of operation suggests that maybe your object gets
destroyed prematurely, and the crash occurs in the last Release.
I have successfully implemented this technique. Thanks to Igor, I am
now detecting status codes. A couple things to look out for....in
GetObjectParam you have to call AddRef on your IBindStatusCallback
class whenever you provide it to MSHTML because MSHTML will call
Release on it when it is done using it (this could be causing your
crash). Also, you must write your own QueryInterface in you class
that implements IBindStatusCallback. When it is called with
IID_IBindStatusCallback or IID_IUnknown, you provide a pointer to your
class (this), otherwise you forward the call to the QueryInterface
function in the IBindStatusCallback pointer that you stored when
MSHTML called RegisterObjectParam. Hope this helps. Thanks again
Igor!!!!!
Very, very bad idea. Don't do this. It violates COM rules. Imagine the
caller doing QI for an alternate interface (say IAuthenticate or
IHttpNegotiate) and then querying the resulting pointer back for
IBindStatusCallback. It'll get MSHTML's pointer, not yours, because
MSHTML does not know anything about your man-in-the-middle. Then it may
issue IBindStatusCallback calls bypassing your implementation.
You should implement all interfaces that are actually being queried for
in the same way - by forwarding to MSHTML's implementation. I would
expect IAuthenticate, IHttpNegotiate[2], IHttpSecurity,
IWindowForBindingUI and IServiceProvider.
Curious. Never heard of these interfaces. Are you saying the whole
construct does not work if you simply don't implement them and return
E_NOINTERFACE from QI?
IAsyncBindCtx has all the same methods and signatures as IBindCtx. So
you just implement IBindCtx, and return it from QI for both IID_IBindCtx
and IID_IAsyncBindCtx. IID_IAsyncBindCtx is declared in urlmon.h
IBindStatusCallbackHolder is derived from IBindStatusCallback and has no
methods above and beyond IBindStatusCallback. So again, implement
IBindStatusCallback and return it from QI for both
IID_IBindStatusCallback and IID_IBindStatusCallbackHolder. The IID for
the latter is {79eac9cc-baf9-11ce-8c82-00aa004ba90b} - it does not seem
to be defined in any public header.
I'm not exactly sure what these extra interfaces are for. They appear to
be some kind of markers - not providing any functionality, but just the
fact that the object implements them means something to the system.
Where are you getting the status codes from? Are you using
IBinding::GetBindResult() successfully? Or are you getting the info
from somewhere else?
danger...@gmail.com (John) wrote in message news:<40c80290.0406...@posting.google.com>...
First, GetBindResult should work. May it be that you are calling it
incorrectly? Show some code.
Second, OnStopBinding comes with an error code as an HRESULT. Many of
these codes correspond to HTTP status codes. In particular, 404 would
result in INET_E_OBJECT_NOT_FOUND.
Finally, you should be able to query IBinding for IWinInetHttpInfo and
get all the information from the HTTP response. In particular, status
code can be retrieved with QueryInfo(HTTP_QUERY_STATUS_CODE |
HTTP_QUERY_FLAG_NUMBER)
"Igor Tandetnik" <itand...@mvps.org> wrote in message news:<e1QM7LlT...@TK2MSFTNGP12.phx.gbl>...