I have a problem using the OnLoadEnd event of a TChromium (DCEF1).
I have a form with a TButton and a TChromium.
The OnClick event of the button calls a function which lists the forms of the loaded page. If I wait the page finish loading and then click the button, this function works OK; but if I call this function from the TChromium OnLoadEnd event handler the callback function is never called and thus, I get a empty list.
Button code (read the comments into the code):
procedure TForm2.Button3Click(Sender: TObject);
var
Q: TWebChromium;
begin
Q := TWebChromium.Create(Chromium1); // <- class to access DOM
Q.WebFormNames; // <- method to get forms name
ShowMessage(Q.Forms.Text); // <- show forms
end;
OnLoadEnd code:
procedure TForm2.Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser;
const frame: ICefFrame; httpStatusCode: Integer; out Result: Boolean);
begin
if (browser <> nil) and (browser.GetWindowHandle = TChromium(Sender).BrowserHandle) and ((frame = nil) or (frame.IsMain)) then
begin
Button3Click(nil);
end;
end;
Method code to obtain forms name (read the comments into the code):
procedure TWebChromium.WebFormNames;
var
Finish: Boolean;
EndTime: TTime;
begin
FForms.Clear; // <- property (TStringList)
if not Assigned(FWebBrowser) then // <- FWebBrowser: property that contain the TChromium
raise Exception.Create('WebBrowser not assigned');
if not (FWebBrowser is TChromium) then
raise Exception.Create('The WebBrowser property is not a TChromium.');
Finish := False;
TChromium(FWebBrowser).Browser.MainFrame.VisitDomProc(
procedure (const doc: ICefDomDocument) // <- this procedure is not called if this method is called from OnLoadEnd event
begin
FForms.CommaText := GetFormsName(doc.Body);
Finish := True;
end
);
EndTime := IncSecond(Time, 4);
repeat Application.ProcessMessages until Finish or (Time > EndTime);
if Time > EndTime then
raise Exception.Create('Time out');
end;
Well, i know that this question was asked years ago, but i'm pretty new to TChromium. Here's my solution raised from previous proposals. In general, TChromium sends Event OnLoadEnd, but does so before loading, for example, JS. So I solve the problem so that I wait for some time in the OnLoadEnd procedure in case any scripts still load, and then send a notification, like this
procedure TForm1.OnLoadEndCust(Sender: TObject; const browser: ICefBrowser;
const frame: ICefFrame; httpStatusCode: Integer);
var EndTime: TTime;
begin
EndTime := IncSecond(Now, 2);
repeat Application.ProcessMessages until (Now > EndTime);
end;
So far - that's enough, but is there any other, better or more ellegant solution?
And why we should use VisitDomProc in code above? When we are calling it from OnLoadEnd it seems to be unnecessary. What d'you think guys?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With