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

Reload detection

59 views
Skip to first unread message

Jan Ostedt

unread,
Jun 12, 2007, 2:40:17 PM6/12/07
to
Hello!
I'm using MFC (CHtmlView). I would like to trap a page refresh at an early stage to be able to
cancel it.
If the page refresh is caused by a meta tag I'm able to trap the event in BeforeNavigate2, but
if the page refresh is caused by javascript (location.reload()) I'm not able to trap the event at all.
How can that be done?
I have implemented IOleCommandTarget in order to catch OLECMDID_PREREFRESH. I succeeded
to catch the call, but it seems to take place very late in the reload process (in spite of its name) , so that
didn't work. I've worked on this for a while so I would really appreciate if someone could help me out.
Thanks in advance!
Best Regards
Jan

mh

unread,
Jun 14, 2007, 9:28:23 AM6/14/07
to

1) Add three variables:

// counter to monitor number of requests to BeforeNavigate2 vs number
of requests to DownloadBegin.
int m_nPageCounter;
// counter to monitor number of DownloadBegin and DownloadEnd calls.
int m_nObjCounter;
// variable to tell us whether a refresh request has started.
BOOL m_bIsRefresh;

2) In BeforeNavigate2 add:

m_nPageCounter++;

3) In DocumentComplete add:

m_nPageCounter--;
if( (m_bIsRefresh) && (m_nPageCounter == 0) && (m_nObjCounter == 0) )
{
//Refresh end
m_bIsRefresh = FALSE;
}

4) In DownloadBegin add:

m_nObjCounter++;
//Refresh started
if(m_nPageCounter == 0)
{
m_bIsRefresh = TRUE;
}

5) In DownloadComplete add

m_nObjCounter--;
//Refresh Ended
if( (m_bIsRefresh) && (m_nPageCounter == 0) && (m_nObjCounter == 0) )
{
m_bIsRefresh = FALSE;
}

Hope this helps
MH

Jan Ostedt

unread,
Jun 15, 2007, 9:53:36 AM6/15/07
to
Thank you very much for your answer! The proposed method is a good way
to identify a refresh, but if I want to cancel the operation I think it's too late
to detect it in DownloadBegin. Please correct me if I'm wrong.
Right now I'm considering trying to implement an Asynchronous Pluggable
Protocol handler to solve the problem. Could an APP handler be used to
detect and cancel a refresh request from the web browser control? Igor, is
that feasible?
Regards
Jan

Jan Ostedt
www.learnware.se

do you think about that

Igor Tandetnik

unread,
Jun 15, 2007, 12:17:20 PM6/15/07
to
Jan Ostedt <ost...@algonet.se> wrote:
> Right now I'm considering trying to implement an Asynchronous
> Pluggable
> Protocol handler to solve the problem. Could an APP handler be used to
> detect and cancel a refresh request from the web browser control?

I doubt it. A refresh shouldn't look any different to an APP than a
regular navigation.

It's possible there is some tell-tale header (perhaps cache related)
that appears in a refresh request but not in a regular request, that you
could try and build a heuristic around. I haven't tried anything like
that myself, you are on your own.
--
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


Jan Ostedt

unread,
Jun 15, 2007, 2:58:28 PM6/15/07
to
Igor, thank you very much for your answer. I'm pleased to hear that it might be a possible
way to go. I will have a go using your PassThroughApp. Thanks again!
Regards
Jan

Igor Tandetnik

unread,
Jun 15, 2007, 3:45:14 PM6/15/07
to
Jan Ostedt <ost...@algonet.se> wrote:
> Igor, thank you very much for your answer. I'm pleased to hear that
> it might be a possible way to go. I will have a go using your
> PassThroughApp. Thanks again!

Pay attention to BINDF flags you get from
IInternetBindInfo::GetBindInfo. There are a few flags that look
promising - e.g. BINDF_RESYNCHRONIZE.

Jan Ostedt

unread,
Jun 15, 2007, 6:05:00 PM6/15/07
to
On Fri, 15 Jun 2007 15:45:14 -0400, "Igor Tandetnik" <itand...@mvps.org> wrote:

>Pay attention to BINDF flags you get from
>IInternetBindInfo::GetBindInfo. There are a few flags that look
>promising - e.g. BINDF_RESYNCHRONIZE.

OK, I will do that. Thank you very much!
Best Regards
Jan

Jan Ostedt

unread,
Jul 15, 2007, 6:04:04 PM7/15/07
to
It took some time before I had time to work on this but now I have integrated your PassThruApp
into my MFC application (actually I used PassThruAppBeta). Thank you very much for supplying this
toolkit and for pointing me in the right direction. After a little testing it seemed like I should look for
two BINDF flags BINDF_GETNEWESTVERSION and BINDF_RESYNCHRONIZE. The first
one is on after a javascript reload(true) and the second on after a reload(false). My intention is to
cancel these reload operations. I've added some code to your OnStart function that gets the bind
info flags and if one of them is on the following statement is not executed:
hr = pTargetProtocol->Start(szUrl, spSink, spBindInfo, grfPI, dwReserved);
Instead the OnStart function returns E_ABORT. That cancels the operation but
it also makes the web browser display the information page "This program cannot display the web page".
I would like the original page to stay. I only want to cancel the reload operation. I tried to cancel the
info page in OnNavigateError, but then I get an empty page instead, so that didn't help. I've tried a
number of return codes instead of E_ABORT, but to no avail. Is there a return code that just cancels the
operation? Is it to late to cancel the operation at this stage if one wants to keep the original page?
I would really appreciate if you, Igor, or somebody else could help me out. Thanks in advance!

Best Regards
Jan

www.learnware.se

Igor Tandetnik

unread,
Jul 15, 2007, 9:55:11 PM7/15/07
to
"Jan Ostedt" <ost...@algonet.se> wrote in message
news:uf0l93d2taribp9fe...@4ax.com

> My intention is to cancel these reload operations.
> I've added some code to your OnStart function that gets the bind
> info flags and if one of them is on the following statement is not
> executed:
> hr = pTargetProtocol->Start(szUrl, spSink, spBindInfo, grfPI,
> dwReserved);
> Instead the OnStart function returns E_ABORT. That cancels the
> operation but
> it also makes the web browser display the information page "This
> program cannot display the web page".
> I would like the original page to stay.

I don't think it's possible from an APP. An APP can abort the request,
but it can't pretend the request has never happened, as far as I can
tell.

I've seen it mentioned a few times (but haven't personally verified)
that you can implement IOleCommandTarget on the same object that
implements IOleClientSite (not sure how it's done in MFC), and when the
user hits Refresh the browser would call Exec on you with the command of
OLECMDID_PREREFRESH. I'm not sure what one can do from here to abort the
operation: perhaps return an error code, perhaps call
IWebBrowser2::Stop. Probably worth playing with.

Jan Ostedt

unread,
Jul 16, 2007, 5:29:26 PM7/16/07
to
On Sun, 15 Jul 2007 21:55:11 -0400, "Igor Tandetnik" <itand...@mvps.org> wrote:

>I've seen it mentioned a few times (but haven't personally verified)
>that you can implement IOleCommandTarget on the same object that
>implements IOleClientSite (not sure how it's done in MFC), and when the
>user hits Refresh the browser would call Exec on you with the command of
>OLECMDID_PREREFRESH. I'm not sure what one can do from here to abort the
>operation: perhaps return an error code, perhaps call
>IWebBrowser2::Stop. Probably worth playing with.

In my first post in this thread I wrote:

"I have implemented IOleCommandTarget in order to catch OLECMDID_PREREFRESH. I succeeded
to catch the call, but it seems to take place very late in the reload process (in spite of its name)"

So I have already tried to implement IOleCommandTarget, but I will give it another go. May be
I did something wrong. It seems strange that the OLECMDID_PREREFRESH appears late in the
refresh process. Is there anybody else in the group that has experience in this area?

Best Regards
Jan

www.learnware.se

Jan Ostedt

unread,
Jul 19, 2007, 8:34:39 AM7/19/07
to
On Mon, 16 Jul 2007 23:29:26 +0200, Jan Ostedt <ost...@algonet.se> wrote:

>So I have already tried to implement IOleCommandTarget, but I will give it another go. May be
>I did something wrong. It seems strange that the OLECMDID_PREREFRESH appears late in the
>refresh process. Is there anybody else in the group that has experience in this area?

Now I have implemented IOleCommandTarget again and my tests reveal that the OLECMDID_PREREFRESH
actually appears very late in the refresh process, in spite of its name. The browser calls my IOleCommandTarget::Exec
many times before the OLECMDID_PREREFRESH shows up. Several of the calls have undocumented command IDs.
My intention is to detect and cancel refreshes caused by javascript location.reload(false) and location.reload(true). So
I decided to see if it was at all possible to cancel the refresh at this stage. So at the first call to
IOleCommanTarget::Exec (and at subsequent calls) after a refresh I tried to cancel the operation. First I tried
different return values but that didn't help so I changed to IWebBrowser2::Stop, which made the refresh stop, but I
ended up with a blank page instead of the original one. Very similar to what happened when I tested my PassThruApp
approach. Unfortunately it seems like this approach doesn't work either. Is there anybody in the group that has ideas
about how a javascript.reload operation can be detected and canceled? Suggestions would be greatly appreciated.

Best Regards
Jan

www.learnware.se

Jan Ostedt

unread,
Jul 20, 2007, 8:21:19 PM7/20/07
to
Hi again!
I finally managed to solve this problem. So, for the records, here is how I did it:
In my event sink for window events I added a handler for the OnBeforeUnload event. That event is fired when a javascript
location.reload() is executed. The event handler returns a string that will be added to a message box asking the user if
he or she wants to proceed or not. In my implementation of IDocHostShowUI::ShowMessage I trap that message before it is
displayed using the string to identify it. I supply IDCANCEL via the plResult output parameter to simulate a click on
the cancel button and return S_OK to not show the message box and voila, that's it.

Best Regards
Jan

www.learnware.se


0 new messages