Application blocking when trying to access TWebbrowsers HTML

Edit He narrowed it down to 1 line,

HTML := wb.OleObject.Document.documentElement.innerHTML; 

which consumes time ... how can it accelerate?

Using the following code, my application can hang for 1-2 seconds while it tries to access the HTML page of the page (Delphi XE).

 function Button1Click(Sender : TObject); begin wb.navigate('http://10.0.0.154/stats'); // Use a timer to poll the page - dont wait and process app messages timer1.enabled := true; end; procedure Timer1Timer(Sender : TObject); var HTML : WideString; begin If GetHTML(HTML) = true then begin Timer1.enabled := false; { do something } end; end; function GetHTML(var HTML : WideString) : boolean; var Document : IHTMLDocument2; begin HTML := ''; Result := false; Document := wb.DOcument as IHTMLDocument2; If Assigned(Document) then begin try HTML := wb.OleObject.Document.documentElement.innerHTML; Result := true; except Result := false; end; end; end; 

However, I noticed that my GetHTML method may take 1-2 seconds to return something, and it blocks the user interface. Looking at AQTime with Delphi XE, he says the method call is slow (1-2 seconds). This is sporadic, and I wonder if it fails when the page is still in medium load.

The page I am loading is an internal page full of javascript and 500k large, I cannot use OnDocumentComplete because it fires while the page is not ready yet, even if I do the ReadyState check, it still fires early.

Anyone who can shed some light if their faster way to access TWebbrowser HTML files?

+3
source share
3 answers

Remember that OnDocumentComplete can run several times (frames) when navigating a page.

How to implement OnDocumentComplete correctly:

 procedure YourForm.OnDocumentComplete( Sender: TObject; const pDisp: IDispatch; var URL: OleVariant); var currentBrowser: IWebBrowser; topBrowser: IWebBrowser; document: OleVariant; windowName: string; begin currentBrowser := pDisp as IWebBrowser; topBrowser := (Sender as TWebBrowser).DefaultInterface; if currentBrowser = topBrowser then ShowMessage('Complete document was loaded') else begin document := currentBrowser.Document; windowName := document.ParentWindow.Name; ShowMessage(Format('Frame "%s" was loaded', [windowName])); end; end; 

A source:

http://www.cryer.co.uk/brian/delphi/twebbrowser/twebbrowser_events.htm#OnDocumentComplete

+4
source

Your problem is that you are not letting TWebBrowser complete the page loading before trying to get the HTML. This is just a guess, because you are not showing how the code you call wb.Navigate is, and you have to deal with exceptions that receive InnerHTML.

You should try the following:

 procedure TForm1.GetHTML(URL: string; var HTML: string); begin wb.Navigate(URL); Application.ProcessMessages; while wb.Busy do Application.ProcessMessages; HTML := wb.OleObject.Document.documentElement.innerHTML; end; 
+2
source

As with the @crefird answer, I suspect that you are trying to access InnerHTML before the browser finishes its work ...

If ReadState / Busy does not return an accurate representation of the TWebBrowser busy state, you can do this:

1) Create a global variable or a private member of your form ... for example, "FBrowserBusy: Boolean" (DO NOT FORGET TO INITIALIZE THAT TRUE ONLY CALL ON ".Navigate") 2) As @crefird showed in his answer, use "while" loop, replace "wb.Busy" with "FBrowserBusy". 3) Add the OnDocumentComplete event to the TWebBrowser instance and set this FBusy: = False;

This will eliminate any collision and ensure that the TWebBrowser object finishes loading the document before your external routine continues polling.

Hope you find this helpful!

0
source

Source: https://habr.com/ru/post/919111/


All Articles