如何揭露“本机功能”在使用Chromium和Delphi 6的网页中使用Javascript? [英] How to expose "native functions" to Javascript in a web page using Chromium and Delphi 6?

查看:505
本文介绍了如何揭露“本机功能”在使用Chromium和Delphi 6的网页中使用Javascript?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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等) 。我正在寻找一些样本,如果有人知道在哪里找到它们,将会告诉我如何做这两件事。

解决方案

听众很容易(仅在旧版本的CEF中):

  procedure MouseDownCallback(const Event:ICefDomEvent); 
begin
ShowMessage('Mouse down on'+ Event.Target.Name);
结束

procedure AttachMouseDownListenerProc(const Doc:ICefDomDocument);
begin
Doc.Body.AddEventListenerProc('mousedown',True,MouseDownCallback);
结束

程序TMainForm.Button1Click(Sender:TObject);
begin
ChromiumComponent.Browser.MainFrame.VisitDomProc(AttachMouseDownListenerProc);
结束关于用于直接获取JavaScript结果的扩展功能:中继线不包含它们(还??)???????????

。似乎正在进行中。



修改



通过扩展名



您的JavaScript代码确实可以使用扩展名回调到您的Delphi代码。此外,您可以将值从JavaScript发送到Delphi - 这可以用于传输结果而无需轮询。



首先在初始化 section注册扩展名,稍后在回调时使用JavaScript对象:

  procedure RegisterExtension; 
var
代码:string;
开始

代码:=
'var cef;'+
'if(!cef)'+
'cef = {};'+
'if(!cef.test)'+
'cef.test = {};'+
'(function(){'+
'cef.test .__ defineGetter__ (''test_param'',function(){'+
'本机函数GetTestParam();'+
'返回GetTestParam();'+
'});'+
'cef.test .__ defineSetter __(''test_param'',function(b){'+
'本机函数SetTestParam();'+
'if(b)SetTestParam(b);' +
'''$
'cef.test.test_object = function(){'+
'本机函数GetTestObject();'+
'返回GetTestObject() ;'+
'};'+
'})();';

CefRegisterExtension('example / v8',Code,TMyHandler.Create as ICefv8Handler);
结束

初始化
RegisterExtension;

TMyHandler 执行将稍后被调用。 TMyHandler 定义为

  TMyHandler = class(TCefv8HandlerOwn)
protected
function Execute(const name:ustring; const obj:ICefv8Value;
const arguments:TCefv8ValueArray; var retval:ICefv8Value;
var exception:ustring):Boolean;覆盖
结束

目前,演示目的的实现很简单:

  function TMyHandler.Execute(const name:ustring; const obj:ICefv8Value; const arguments:TCefv8ValueArray; var retval:ICefv8Value; var exception:ustring):Boolean; 
begin
ShowMessage('Execute!');
结束

现在从JavaScript调用Delphi调用简单地做:

  ChromiumComponentBrowser.MainFrame.ExecuteJavaScript('cef.test.test_object()。GetMessage();','about:blank',0); 

应该显示执行!的消息框。



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


I have successfully embedded Chromium into my Delphi 6 projects with the help of Delphi Chromium Embedded. Now I want to be able to execute Javascript code and the have results returned to my host Delphi app. My current method is to call ExecuteJavascript() and use a DOM element that the Javascript call writes its results to, and poll that element in a TTimer method from Delphi to retrieve the results. However, I read about using native functions and V8 extensions to have the Javascript call "call back" into my Delphi code as a way to receive results instead:

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

I would like to try this and I also would like to know how to attach Delphi based event listeners to DOM elements in the web page (onblur, onmousedown, etc.). I am looking for some samples that would show me how to do these two things if anyone knows where to find them.

解决方案

Attaching listeners is quite easy (only in older versions of 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;

Regarding the extended functions for getting JavaScript results directly: the trunk doesn't contain them (yet?). Seems to be work in progress.

Edit:

Getting rid of polling via extensions:

It is indeed possible for your JavaScript code to call back into your Delphi code using extensions. Furthermore you can send values from JavaScript to Delphi - this could be used to transfer results without the need to poll.

First in your initialization section register the extension, which creates a JavaScript object later to be used when calling back:

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's Execute will be invoked later. TMyHandler is defined as

TMyHandler = class(TCefv8HandlerOwn)
protected
  function Execute(const name: ustring; const obj: ICefv8Value;
    const arguments: TCefv8ValueArray; var retval: ICefv8Value;
    var exception: ustring): Boolean; override;
end;

The implementation for demonstration purposes is simple for now:

function TMyHandler.Execute(const name: ustring; const obj: ICefv8Value; const arguments: TCefv8ValueArray; var retval: ICefv8Value; var exception: ustring): Boolean;
begin
  ShowMessage('Execute!');
end;

Now to test calling into Delphi from JavaScript simply do:

ChromiumComponent.Browser.MainFrame.ExecuteJavaScript('cef.test.test_object().GetMessage();', 'about:blank', 0);

This should display the message box saying "Execute!".

I pulled the demo script from a sample named cefclient which you can find in the \demos\cefclient folder in the component root dir. The extension sample code is a bit hidden and mingled with other demo code. But of special interest for us is the implementation of TExtension.Execute (the equivalent to my TMyHandler.Execute). There you can find how to determine which function is being called and how to pass parameters. (Link to the code.)

这篇关于如何揭露“本机功能”在使用Chromium和Delphi 6的网页中使用Javascript?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆