rooky06
rooky06

Reputation: 31

Wait until a page is fully loaded in WebBrowser Delphi

I am using the code below to wait for a page to be fully loaded when I browse by code, and that works perfectly, but when I click on a link in a page, the WebBrowser1DocumentComplete or WebBrowser1NavigateComplete2 event fires several times if the page contains frames, of JS etc.

I would like to be able to wait for the page to load completely when I click on the link, but I don't know how.

WebBrowser1.Navigate(URL);
repeat
  Application.ProcessMessages;
  Sleep(0);
until WebBrowser1.ReadyState = READYSTATE_COMPLETE;

Upvotes: 1

Views: 1611

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595981

First, you should not be using such a loop at all, you shoud be using the TWebBrowser.OnDocumentComplete event to detect when the document is ready.

Second, getting multiple OnDocumentComplete/OnNavigateComplete2 events is expected behavior when frames are used in the HTML. You get an event for each frame, and a final event from the main window.

This behavior is documented on MSDN:

https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa768282(v=vs.85)

The WebBrowser Control fires the DocumentComplete event when the document has completely loaded, and the READYSTATE property has changed to READYSTATE_COMPLETE. Following are some important points about the firing of this event.

  • In pages with no frames, this event fires one time after loading is complete.
  • In pages where multiple frames are loaded, this event fires for each frame where the DownloadBegin event has fired.
  • This event pDisp parameter is the same as the IDispatch interface pointer of the frame in which this event fires.
  • In the loading process, the highest level frame, which is not necessarily the top-level frame, fires the final DocumentComplete event. At this time, the pDisp parameter is the same as the IDispatch interface pointer of the highest level frame.

And even in Embarcadero's DocWiki:

http://docwiki.embarcadero.com/Libraries/en/SHDocVw.TWebBrowser.OnDocumentComplete

Write an OnDocumentComplete event handler to take specific action when a frame or document is fully loaded into the Web browser. For a document without frames, this event occurs once when the document finishes loading. On a document containing multiple frames, this event occurs once for each frame. When the multiple-frame document finishes loading, the Web browser fires the event one final time.

So, in the TWebBrowser.OnDocumentComplete, you need to check the pDisp parameter to see whether it is the IDispatch of the main document or not.

Upvotes: 3

Related Questions