Please see my testing:
1. getting document.GetTitle from render process back to browser process - works
(messages 'visitdom' and 'hodnota' )
2. trying add AddEventListenerProc for click event - does not work
(messages 'addListener' and 'click')
addListener reach the render, listener is set, but
'click' sent by listener (part of render) does not reach the browser
(added TCefDomEventListenerProc = procedure(const event: ICefDomEvent) is nested;
to cef3intf.pas line 123)
Unit Main;
{$MODE objfpc}{$H+}
{$modeswitch nestedprocvars}
Interface
Uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, LCLType, ExtCtrls,
cef3types, cef3lib, cef3intf, cef3lcl,cef3ref,cef3api,cef3own, cef3gui;
Type
{ TCustomRenderProcessHandler }
TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn)
protected
function OnProcessMessageReceived(const browser: ICefBrowser;
sourceProcess: TCefProcessId; const message: ICefProcessMessage): Boolean;
override;
end;
{ TMainform }
TMainform = class(TForm)
BGo : TButton;
Button1: TButton;
Chromium : TChromium;
EUrl : TEdit;
LUrl : TStaticText;
Memo1: TMemo;
procedure BGoClick(Sender : TObject);
procedure Button1Click(Sender: TObject);
procedure ChromiumKeyEvent(Sender: TObject; const Browser: ICefBrowser;
const event: PCefKeyEvent; osEvent: TCefEventHandle; out Result: Boolean);
procedure ChromiumLoadEnd(Sender : TObject; const Browser : ICefBrowser;
const Frame : ICefFrame; httpStatusCode : Integer);
procedure ChromiumProcessMessageReceived(Sender: TObject;
const Browser: ICefBrowser; sourceProcess: TCefProcessId;
const message: ICefProcessMessage; out Result: Boolean);
procedure ChromiumTitleChange(Sender : TObject;
const Browser : ICefBrowser; const title : ustring);
procedure EUrlKeyDown(Sender : TObject; var Key : Word;
Shift : TShiftState);
procedure FormCreate(Sender : TObject);
private
{ private declarations }
public
{ public declarations }
end;
Var
Mainform : TMainform;
Implementation
{$R *.lfm}
{ TMainform }
procedure TMainform.BGoClick(Sender : TObject);
var
mujFrame : ICefFrame;
begin
Chromium.Load(EUrl.Text);
mujFrame:=Chromium.Browser.GetMainFrame;
//mujFrame.ExecuteJavaScript('alert("ExecuteJavaScript works!")',mujFrame.GetURL(), 0);;
{copy javascript object handsets to windows clipboard}
//mujFrame.ExecuteJavaScript( 'var copyDiv = document.createElement("div");'+
// 'copyDiv.contentEditable = true;'+
// 'document.body.appendChild(copyDiv);'+
// 'copyDiv.innerHTML = handsets;'+
// 'copyDiv.unselectable = "off"; '+
// 'copyDiv.focus();'+
// 'document.execCommand("SelectAll");'+
// 'document.execCommand("Copy", false, null);'+
// 'document.body.removeChild(copyDiv);',mujFrame.GetURL(), 0);
end;
procedure TMainform.Button1Click(Sender: TObject);
begin
// for adding mouse event DOM listener
Chromium.browser.SendProcessMessage(PID_RENDERER,TCefProcessMessageRef.New('addListener'));
end;
procedure TMainform.ChromiumKeyEvent(Sender: TObject;
const Browser: ICefBrowser; const event: PCefKeyEvent;
osEvent: TCefEventHandle; out Result: Boolean);
begin
// for entering DOM sends message to render process (only place for obtaining DOM)
Chromium.browser.SendProcessMessage(PID_RENDERER,TCefProcessMessageRef.New('visitdom'));
end;
{TCustomRenderProcessHandler - zpracuje message poslaný do render procesu}
function TCustomRenderProcessHandler.OnProcessMessageReceived(
const browser: ICefBrowser; sourceProcess: TCefProcessId;
const message: ICefProcessMessage): Boolean;
procedure mujEventListener(const event: ICefDomEvent);
var
mojeMsg: ICefProcessMessage;
begin
mojeMsg := TCefProcessMessageRef.New('click');
mojeMsg.ArgumentList.SetString(0, string(event.Target.Name));
ShowMessage('Tady to funguje :-)');
browser.SendProcessMessage(PID_BROWSER, mojeMsg); // message to browser process
end; // does not reach its destination
procedure pokus(const document:ICefDomDocument); {user defined nested procedure}
var
mojeMessage: ICefProcessMessage;
begin
mojeMessage:=TCefProcessMessageRef.New('hodnota');
mojeMessage.GetArgumentList.SetString(0,document.GetTitle);
browser.SendProcessMessage(PID_BROWSER,mojeMessage);
// for nested type procedure variables is needed:
// adding {$modeswitch nestedprocvars} AFTER {$mode xxx} declaration in units:
// cef3intf,cef3own, cef3ref;
// and change line 121 in cef3intf.pas:
// TCefDomVisitorProc=procedure(const document:ICefDomDocument);
// to
// TCefDomVisitorProc = procedure(const document: ICefDomDocument) is nested;
end;
procedure dalsiPokus(const document:ICefDomDocument);
var
mujEventListener1:TCefDomEventListenerProc;
begin
mujEventListener1:=@mujEventListener;
document.Body.AddEventListenerProc('click',true,mujEventListener1);
end;
var
pokus1,dalsiPokus1:TCefDomVisitorProc;
begin {TCustomRenderProcessHandler.OnProcessMessageReceived}
case message.Name of
'visitdom' :
begin
pokus1:= @pokus;
browser.MainFrame.VisitDomProc(pokus1);
Result := True;
end;
'addListener' :
begin
dalsiPokus1:=@dalsiPokus;
browser.MainFrame.VisitDomProc(dalsiPokus1);
Result:=true;
end;
else
Result:=false;
end;
end; {TCustomRenderProcessHandler.OnProcessMessageReceived}
{zpracuje message poslaný do browser procesu}
procedure TMainform.ChromiumProcessMessageReceived(Sender: TObject;
const Browser: ICefBrowser; sourceProcess: TCefProcessId;
const message: ICefProcessMessage; out Result: Boolean);
begin
// ShowMessage('Tady to funguje :-)');
case message.Name of
'hodnota' :
begin
mainform.Memo1.Text:= string(message.GetArgumentList.GetString(0));
Result := True;
end;
'click' :
begin
ShowMessage('Tady to funguje :-)III');
mainform.Memo1.Text:='mouseover'+string(message.GetArgumentList.GetString(0));
Result := True;
end
else
Result:=False;
end;
end;
procedure TMainform.ChromiumLoadEnd(Sender : TObject; const Browser : ICefBrowser; const Frame : ICefFrame;
httpStatusCode : Integer);
begin
EUrl.Text := UTF8Encode(Browser.MainFrame.Url);
end;
procedure TMainform.ChromiumTitleChange(Sender : TObject; const Browser : ICefBrowser; const title : ustring);
begin
Caption := 'Browser - ' + UTF8Encode(title);
end;
procedure TMainform.EUrlKeyDown(Sender : TObject; var Key : Word; Shift : TShiftState);
begin
If Key = VK_RETURN then BGoClick(Sender);
end;
procedure TMainform.FormCreate(Sender : TObject);
begin
CefSingleProcess:=false;
{$INFO Uncomment to use a subprocess}
//CefBrowserSubprocessPath := '.' + PathDelim + 'subprocess'{$IFDEF WINDOWS}+'.exe'{$ENDIF};
CefRenderProcessHandler := TCustomRenderProcessHandler.Create; // pro přístup k DOM
end;
initialization
// CefRenderProcessHandler := TCustomRenderProcessHandler.Create; // pro přístup k DOM
end.
[0610/134955:VERBOSE1:ipc_sync_channel.cc(385)] Canceling pending sends