2016-09-11 9 views
3

Я пытаюсь реализовать fpcef3 визуализацию обработчика процесса как подпроцесс:Как реализовать в FreePascal/Lazarus CeF3 визуализации обработчика процесса в подпроцессе

следующие примеры, представленные на fpcef3 github repo, мне удалось создать вынести обработчик процесса подпроцесса:

Program subprocess; 

{$mode objfpc}{$H+} 

Uses 
    {$IFDEF UNIX}{$IFDEF UseCThreads} 
    cthreads, 
    {$ENDIF}{$ENDIF} 
    cef3lib, cef3types, cef3api, Handler; 

Var 
    Args : TCefMainArgs; 

begin 
    CefLoadLibrary; 
    CefRenderProcessHandler := TCustomRenderProcessHandler.Create; 

    {$IFDEF WINDOWS} 
    Args.instance := HINSTANCE(); 

    Halt(cef_execute_process(@Args, nil, nil)); 
    {$ELSE} 
    Args.argc := argc; 
    Args.argv := argv; 

    Halt(cef_execute_process(@Args, nil, nil)); 
    {$ENDIF} 
end. 

TCustomRenderProcessHandler идентичен обработчику, снабженным, например JavaScript в примерах SUBDIR:

Unit Handler; 

{$MODE objfpc}{$H+} 

(* 
* Everything in here is called from a render process, so there is no access to GUI and all the 
* data of the main process. 
*) 

Interface 

Uses 
    Classes, SysUtils, 
    cef3types, cef3intf, cef3ref, cef3own, cef3lib; 

Type 
    { Custom handler for the render process } 
    TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn) 
    protected 
    // Test Window Bindings 
    procedure OnContextCreated(const browser: ICefBrowser; const frame: ICefFrame; const context: ICefv8Context); override; 
    // Test Extension 
    procedure OnWebKitInitialized; override; 
    end; 

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

Implementation 

Var 
    mystr : String; 

{ TMyHandler } 

function TMyHandler.Execute(const name : ustring; const obj : ICefv8Value; 
    const arguments : ICefv8ValueArray; var retval : ICefv8Value; 
    var exception : ustring) : Boolean; 
begin 
    // return a value 
    //retval := TCefv8ValueRef.NewString('TMyHandler'); 
    retval := TCefv8ValueRef.NewDate(Now); 

    Result := True; 
end; 

{ TCustomRenderProcessHandler } 

procedure TCustomRenderProcessHandler.OnContextCreated(const browser : ICefBrowser; 
    const frame : ICefFrame; const context : ICefv8Context); 
Var 
    myWin : ICefv8Value; 
    args : ICefv8ValueArray; 
begin 
    myWin := context.GetGlobal; 
    mystr := 'a test string'; 
    SetLength(args, 1); 
    args[0] := TCefv8ValueRef.NewString(mystr); 
    myWin.SetValueByKey('myval', args[0], []); 
end; 

procedure TCustomRenderProcessHandler.OnWebKitInitialized; 
Var 
    Code: ustring; 
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; 

end. 

И, наконец, в основной форме моего мастер-процессе, я обеспечиваю путь к подпроцессу:

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    CefSingleProcess := False; 

    //CefRenderProcessHandler := TCustomRenderProcessHandler.Create; 
    CefBrowserSubprocessPath := 'C:\Users\aludin\fpCEF3-master\Examples\SubProcess\subprocess64.exe' 
end;  

При запуске главного приложения, браузер хрома отображается правильно, однако обработчик не дозвонился (Я вижу, однако, что подпроцесс запущен). Что я делаю неправильно при инициализации обработчика?

Благодарим за помощь!

+0

@MartynA Итак, я проверил оба проекта, и они оба скомпилированы в 64-битные Windows-exes. Я также использую конкретный 64-битный CEF3. Я не проверял, работает ли это в 32 битах, но создание 64-битных exes действительно не должно быть проблемой (так как основному процессу удается успешно загружать CEF3 и отображать вид браузера) – BigONotation

+0

@MartynAAПодробнее спасибо за совет! Я попытаюсь подключиться к подпроцессу ... но почему-то я чувствую, что обработчик процесса визуализации вообще не инициализируется ... – BigONotation

+0

Пытался подключиться к подпроцессу и, как ожидалось, выполнить метод рендеринга обработчик никогда не называется. Я подозреваю, что основной процесс не «видит» обработчик рендеринга subprocess ... следовательно, возникает проблема инициализации в подпроцессе – BigONotation

ответ

2

ОК, наконец, понял, и я чувствую, что добавляю пару проклятых слов здесь, потратив столько времени на это.

После того, как в исходных файлах fpcef3 и однократном шаге основной процесс был расколото, я понял, что вам нужно создать экземпляр приложения ICefApp и назначить обработчик обработчика процесса для этого приложения. Поэтому, чтобы упростить мою жизнь и избежать реализации интерфейса ICefApp, я «захватил» класс, используемый внутри основного процесса. Обновленная реализация подпроцесс теперь задается следующим кодом:

Program subprocess; 

{$mode objfpc}{$H+} 

Uses 
    {$IFDEF UNIX}{$IFDEF UseCThreads} 
    cthreads, 
    {$ENDIF}{$ENDIF} 
    cef3lib, cef3types, cef3api, cef3own, cef3intf, Handler; 

Var 
    Args : TCefMainArgs; 
    app : ICefApp; 

begin 
    CefLoadLibrary; 
    CefRenderProcessHandler := TCustomRenderProcessHandler.Create; 
    app := TInternalApp.Create; 
    {$IFDEF WINDOWS} 
    Args.instance := HINSTANCE(); 

    Halt(cef_execute_process(@Args, CefGetData(app), nil)); 
    {$ELSE} 
    Args.argc := argc; 
    Args.argv := argv; 

    Halt(cef_execute_process(@Args, CefGetData(app), nil)); 
    {$ENDIF} 
end. 

Теперь экземпляр ICefApp будет использовать обработчик визуализации процесса, назначенного CefRenderProcessHandler. Наконец, обратите внимание, как cef_execute_process() был изменен, чтобы принять приложение в качестве дополнительного параметра.

+0

Рад, что вы это поняли, +1 – MartynA

+0

Привет, я сам подошел к этой проблеме. Ваше решение работает нормально. Но не могли бы вы объяснить, как мы должны делать это наоборот? Создание 'ICefApp', назначение пользовательского обработчика и т. Д.?? – Vassilis

+0

@VassilisGr Извините, я не понял ваш вопрос? Что ты имеешь в виду, наоборот? – BigONotation

 Смежные вопросы

  • Нет связанных вопросов^_^