Page 1 of 2
Get document
Posted: Fri Jul 26, 2019 1:26 pm
by X11
how get
Document: ICefDomDocument from Chromium1
Code: Select all
SimpleNodeSearch(Chromium1...???, 'link-ajax j-v-contacts-expand-link');
Thanx
Re: Get document
Posted: Fri Jul 26, 2019 2:14 pm
by salvadordf
The DOMVisitor demo shows how to get a ICefDomDocument instance and make simple node searches using TCefFastDomVisitor2.
Chromium allows you to access ICefDomDocument in the render process and you will need to send messages to the browser process to use the results in Delphi. Read the code comments for more details.
Re: Get document
Posted: Tue Aug 20, 2019 9:50 am
by X11
comment in uDOMVisitor
// To send messages from the render process you must use the browser.SendProcessMessage
// procedure with a PID_BROWSER parameter. The browser process receives those messages in
// the TChromium.OnProcessMessageReceived event.
Code: Select all
MSG1 = 'mymessage';
...
...
...
procedure TMiniBrowserFrm.Chromium1LoadEnd(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
httpStatusCode: Integer);
var
msg: ICefProcessMessage;
begin
if frame.IsMain then
begin
msg := TCefProcessMessageRef.New(MSG1);
msg.ArgumentList.SetString(0, 'Chromium1LoadEnd');
browser.SendProcessMessage(PID_BROWSER, msg); // error here
end;
end;
[dcc32 Error] uMiniBrowser.pas(978): E2003 Undeclared identifier: 'SendProcessMessage'
Re: Get document
Posted: Tue Aug 20, 2019 10:05 am
by salvadordf
Thanks for reporting this issue!
The latest CEF API moved that procedure to the ICefFrame interface. The demos use the right "frame" parameter to call SendProcessMessage but the comments are outdated.
It should say :
Code: Select all
// To send messages from the render process you must use the frame.SendProcessMessage
// procedure with a PID_BROWSER parameter. The browser process receives those messages in
// the TChromium.OnProcessMessageReceived event.
I'll fix it the next time I upload a new CEF4Delphi version.
Re: Get document
Posted: Tue Aug 20, 2019 10:10 am
by X11
Ok. But, how can I solve my problem (problem) now?
Thnx
Re: Get document
Posted: Tue Aug 20, 2019 10:14 am
by salvadordf
replace this :
Code: Select all
browser.SendProcessMessage(PID_BROWSER, msg);
with this :
Code: Select all
frame.SendProcessMessage(PID_BROWSER, msg);
Re: Get document
Posted: Tue Aug 20, 2019 10:48 am
by X11
Code: Select all
procedure CreateGlobalCEFApp;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.RemoteDebuggingPort := 9000;
GlobalCEFApp.OnProcessMessageReceived := GlobalCEFApp_OnProcessMessageReceived;
GlobalCEFApp.DisableFeatures := 'NetworkService';
GlobalCEFApp.Cache := 'cache';//ExtractFilePath(Application.ExeName) + 'Cache\' ;
GlobalCEFApp.UserDataPath := 'UserData';// ExtractFilePath(Application.ExeName) + 'UserData\';
GlobalCEFApp.LogFile := 'debug.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
end;
on form i drop Memo1 and add code "MiniBrowserFrm.Memo1.Lines.Add('GlobalCEFApp_OnProcessMessageReceived');"
Code: Select all
procedure GlobalCEFApp_OnProcessMessageReceived(const browser : ICefBrowser;
const frame : ICefFrame;
sourceProcess : TCefProcessId;
const message : ICefProcessMessage;
var aHandled : boolean);
var
TempFrame : ICefFrame;
TempVisitor : TCefFastDomVisitor2;
begin
aHandled := False;
MiniBrowserFrm.Memo1.Lines.Add('GlobalCEFApp_OnProcessMessageReceived');
...
....
end;
but line "GlobalCEFApp_OnProcessMessageReceived" does not appear in Memo1
in memo i see only "Chromium1LoadEnd"
Code: Select all
procedure TMiniBrowserFrm.Chromium1LoadEnd(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame;
httpStatusCode: Integer);
var
msg: ICefProcessMessage;
begin
if frame.IsMain then
begin
msg := TCefProcessMessageRef.New(MSG1);
msg.ArgumentList.SetString(0, 'Chromium1LoadEnd');
frame.SendProcessMessage(PID_BROWSER, msg);
Memo1.Lines.Add('Chromium1LoadEnd');
end;
end;
Re: Get document
Posted: Tue Aug 20, 2019 10:57 am
by salvadordf
GlobalCEFApp.OnProcessMessageReceived is executed in the render process and it's not possible to access anything from the browser process directly.
The Memo is one of the controls created in the browser process and it's not possible to use it from the render process.
You need to send a process message to send that information from the render process to the browser process.
Re: Get document
Posted: Tue Aug 20, 2019 11:00 am
by X11
ok, where, how?
Re: Get document
Posted: Tue Aug 20, 2019 11:13 am
by salvadordf
Add this inside the GlobalCEFApp_OnProcessMessageReceived procedure :
Code: Select all
procedure GlobalCEFApp_OnProcessMessageReceived(const browser : ICefBrowser;
const frame : ICefFrame;
sourceProcess : TCefProcessId;
const message : ICefProcessMessage;
var aHandled : boolean);
var
msg: ICefProcessMessage;
begin
msg := TCefProcessMessageRef.New(MY_CUSTOM_MESSAGE_NAME);
msg.ArgumentList.SetString(0, 'This is the information I need to send to the browser process');
frame.SendProcessMessage(PID_BROWSER, msg);
end;
Then modify TChromium.OnProcessMessageReceived to handle a message with the "MY_CUSTOM_MESSAGE_NAME" name
Code: Select all
procedure TDOMVisitorFrm.Chromium1ProcessMessageReceived(Sender: TObject;
const browser: ICefBrowser; const frame: ICefFrame; sourceProcess: TCefProcessId;
const message: ICefProcessMessage; out Result: Boolean);
begin
Result := False;
if (message = nil) or (message.ArgumentList = nil) then exit;
if (message.Name = MY_CUSTOM_MESSAGE_NAME) then
begin
// You should save message.ArgumentList.GetString(0) in a class field for later processing because TChromium.OnProcessMessageReceived is executed in a CEF thread and we shouldn't handle VCL controls outside the main application thread.
Memo1.Lines.Add(message.ArgumentList.GetString(0));
Result := True;
end;
end;