添加监听器非常容易(仅适用于旧版本的CEF):
procedure MouseDownCallback(const Event: ICefDomEvent);
begin
ShowMessage('Mouse down on '+Event.Target.Name);
end;
procedure AttachMouseDownListenerProc(const Doc: ICefDomDocument);
begin
Doc.Body.AddEventListenerProc('mousedown', True, MouseDownCallback);
end;
procedure TMainForm.Button1Click(Sender: TObject);
begin
ChromiumComponent.Browser.MainFrame.VisitDomProc(AttachMouseDownListenerProc);
end;
关于直接获取JavaScript结果的扩展功能:主干代码库尚未包含它们(还?)。似乎正在进行中。
编辑:
通过扩展摆脱轮询:
确实,您的JavaScript代码可以使用扩展回调到Delphi代码。此外,您可以从JavaScript发送值到Delphi——这可以用于在不需要轮询的情况下传输结果。
首先,在您的初始化部分注册扩展,该扩展将创建一个JavaScript对象以便在回调时使用:
procedure RegisterExtension;
var
Code:string;
begin
Code :=
'var cef;'+
'if (!cef)'+
' cef = {};'+
'if (!cef.test)'+
' cef.test = {};'+
'(function() {'+
' cef.test.__defineGetter__(''test_param'', function() {'+
' native function GetTestParam();'+
' return GetTestParam();'+
' });'+
' cef.test.__defineSetter__(''test_param'', function(b) {'+
' native function SetTestParam();'+
' if(b) SetTestParam(b);'+
' });'+
' cef.test.test_object = function() {'+
' native function GetTestObject();'+
' return GetTestObject();'+
' };'+
'})();';
CefRegisterExtension('example/v8', Code, TMyHandler.Create as ICefv8Handler);
end;
initialization
RegisterExtension;
TMyHandler
的Execute
方法将会在之后被调用。 TMyHandler
的定义如下:
TMyHandler = class(TCefv8HandlerOwn)
protected
function Execute(const name: ustring; const obj: ICefv8Value;
const arguments: TCefv8ValueArray; var retval: ICefv8Value;
var exception: ustring): Boolean; override;
end;
目前为了演示目的,实现简单:
function TMyHandler.Execute(const name: ustring; const obj: ICefv8Value; const arguments: TCefv8ValueArray; var retval: ICefv8Value; var exception: ustring): Boolean;
begin
ShowMessage('Execute!');
end;
现在,为了测试从JavaScript调用Delphi的方法,只需执行以下操作:
ChromiumComponent.Browser.MainFrame.ExecuteJavaScript('cef.test.test_object().GetMessage();', 'about:blank', 0);
这应该显示一个消息框,上面写着"Execute!"。
我从一个名为cefclient的示例中提取了演示脚本,您可以在组件根目录的\demos\cefclient文件夹中找到它。扩展示例代码有点隐蔽,并与其他演示代码混杂在一起。但对我们特别感兴趣的是TExtension.Execute
的实现(相当于我的TMyHandler.Execute
)。在那里,您可以找到如何确定调用哪个函数以及如何传递参数的方法。(链接到代码。)