Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 在CEF3中输入总是失败_Delphi_Chromium Embedded - Fatal编程技术网

Delphi 在CEF3中输入总是失败

Delphi 在CEF3中输入总是失败,delphi,chromium-embedded,Delphi,Chromium Embedded,在使用repo(3.1750.1738)中最新的delphichromium嵌入代码将CEF1项目转换为CEF3时,我遇到了一些问题。简而言之,我以前有一个分机可以注册。然后在html方面,我将使用本机调用向Delphi主机注册javascript对象。它将存储对象和对象的上下文以供以后调用。但这似乎不适用于DCEF3。我可以得到对象和它的上下文。但后来当我调用context.Enter时,它失败了。我想知道这是否与cef1和cef3之间架构的变化有关。我已经把扩展名改了一点,以便在onwebk

在使用repo(3.1750.1738)中最新的delphichromium嵌入代码将CEF1项目转换为CEF3时,我遇到了一些问题。简而言之,我以前有一个分机可以注册。然后在html方面,我将使用本机调用向Delphi主机注册javascript对象。它将存储对象和对象的上下文以供以后调用。但这似乎不适用于DCEF3。我可以得到对象和它的上下文。但后来当我调用
context.Enter
时,它失败了。我想知道这是否与cef1和cef3之间架构的变化有关。我已经把扩展名改了一点,以便在
onwebkitinitalized
中注册它

这是我的密码:

unit MainUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, cefvcl, ceflib, StdCtrls;

type
  TMainForm = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    Guest: ICefv8Value;
    GuestContext: ICefv8Context;
    Browser: TChromium;
    procedure BrowserConsoleMessage(Sender: TObject; const browser: ICefBrowser;
      const message, source: ustring; line: Integer; out Result: Boolean);
  public
    function ExtensionExecute(const name: ustring; const obj: ICefv8Value;
      const arguments: TCefv8ValueArray; var retval: ICefv8Value;
      var exception: ustring): Boolean;
  end;

var
  MainForm: TMainForm;
  BrowserExt: TCefv8HandlerOwn;

implementation

{$R *.dfm}

const
  code =
   'var cef;'+
   'if (!cef)'+
   '  cef = {};'+
   'if (!cef.nes)'+
   '  cef.nes = {};'+
   '(function() {'+
   '  cef.nes.callNative = function() {'+
   '    native function callNative();'+
   '    return callNative.apply(this, arguments);'+
   '  };'+
   '})();';

type
  TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn)
  protected
    procedure OnWebKitInitialized; override;
  end;

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

function TExtension.Execute(const name: ustring; const obj: ICefv8Value;
  const arguments: TCefv8ValueArray; var retval: ICefv8Value;
  var exception: ustring): Boolean;
begin
  Result := Host.ExtensionExecute(name, obj, arguments, retval, exception);
end;

procedure TMainForm.Button1Click(Sender: TObject);
var
  o: ICefv8Value;
begin
  if GuestContext.Enter then
  begin
    o := Guest.GetValueByKey('foo');
    OutputDebugString(PChar('foo found now: ' + BoolToStr(Assigned(o), True)));
    GuestContext.Exit;
  end
  else
    OutputDebugString('GuestContext.Enter failed');
end;

function TMainForm.ExtensionExecute(const name: ustring; const obj: ICefv8Value;
  const arguments: TCefv8ValueArray; var retval: ICefv8Value;
  var exception: ustring): Boolean;
var
  o: ICefv8Value;
begin
  OutputDebugStringW(PWideChar('Execute: ' + name));
  if name = 'callNative' then
  begin
    GuestContext := TCefv8ContextRef.Current;
    Guest := arguments[0];

    o := Guest.GetValueByKey('foo');
    OutputDebugString(PChar('foo found: ' + BoolToStr(Assigned(o), True)));
  end;

  Result := True;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Browser := TChromium.Create(Self);

  Browser.Options.JavascriptDomPaste := STATE_DISABLED;
  Browser.Options.CaretBrowsing := STATE_DISABLED;

  Browser.OnConsoleMessage := BrowserConsoleMessage;

  Browser.Color := clWhite;
  Browser.Align := alClient;

  Browser.DefaultUrl := 'http://localhost/test2/home.html';

  Browser.Parent := Self;

  BrowserExt := TExtension.Create;
  TExtension(BrowserExt).Host := Self;

  Browser.Load(Browser.DefaultUrl);
end;

procedure TMainForm.BrowserConsoleMessage(Sender: TObject;
    const browser: ICefBrowser; const message, source: ustring; line: Integer;
    out Result: Boolean);
begin
  OutputDebugStringW(PWideChar('[line ' + IntToStr(Line) + '] ' + message));
end;

{ TCustomRenderProcessHandler }

procedure TCustomRenderProcessHandler.OnWebKitInitialized;
begin
  inherited;

  CefRegisterExtension('v8/nes', code, BrowserExt as ICefV8Handler);
end;

initialization
  CefRemoteDebuggingPort := 9000;
  CefRenderProcessHandler := TCustomRenderProcessHandler.Create;
  CefBrowserProcessHandler := TCefBrowserProcessHandlerOwn.Create;

end.
以及javascript代码:

console.log('startup');

var guest = {foo:function() {
  console.log('foo called');

  return 42;
}};

if (typeof(cef) !== "undefined") {
  console.log('registering guest');

  cef.nes.callNative(guest);
}
else {
  console.log('no cef');
}

console.log('startup done');

tmaninform.ExtensionExecute
被触发并发生callNative。但稍后当我点击按钮1时,上下文输入总是返回False。

这是由于CEF3体系结构更改为多线程/进程。您不能再直接调用代码,必须使用Browser.SendProcessMessage来回传递消息,并使用OnProcessMessage处理程序处理这些消息。

此外,如果从按钮1中选中Browser.Browser.MainFrame.Getv8Context,则得到零。当在DCEF1中尝试同样的事情时,我得到了一个有效的上下文。还值得指出的是,我正在使用单进程模式来测试这一点。