15

在Delphi Chromium Embedded的帮助下,我已成功地将 Chromium 嵌入到我的 Delphi 6 项目中。现在我希望能够执行 Javascript 代码并将结果返回到我的主机 Delphi 应用程序。我当前的方法是调用 ExecuteJavascript() 并使用 Javascript 调用将其结果写入的 DOM 元素,并在 Delphi 的 TTimer 方法中轮询该元素以检索结果。但是,我阅读了有关使用本机函数和 V8 扩展将 Javascript 调用“回调”到我的 Delphi 代码中作为接收结果的一种方式:

http://magpcss.org/ceforum/viewtopic.php?f=7&t=180

我想试试这个,我也想知道如何将基于 Delphi 的事件侦听器附加到网页中的 DOM 元素(onblur、onmousedown 等)。我正在寻找一些样本,如果有人知道在哪里可以找到它们,它们会告诉我如何做这两件事。

4

1 回答 1

14

附加侦听器非常容易(仅在旧版本的 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 - 这可以用于传输结果而无需轮询。

首先在您的initialization部分中注册扩展,它会创建一个稍后在回调时使用的 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'sExecute将在稍后调用。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);

这应该会显示“执行!”的消息框。

我从名为cefclient的示例中提取了演示脚本,您可以在组件根目录的\demos\cefclient文件夹中找到该示例。扩展示例代码有点隐藏,并与其他演示代码混合在一起。但我们特别感兴趣的是TExtension.Execute(相当于 my TMyHandler.Execute)的实现。在那里您可以找到如何确定正在调用哪个函数以及如何传递参数。(链接到代码。

于 2011-08-01T07:01:27.247 回答