I don't need extensions but your demo code was helpful for me. The right solution in my case was:
1. Create TCefCustomRenderProcessHandler, fill MessageName and OnCustomMessage properties
Code: Select all
FProcessHandler := TCefCustomRenderProcessHandler.Create;
FProcessHandler.MessageName := EVAL_JS;
FProcessHandler.OnCustomMessage := RenderProcessHandler_OnCustomMessage;
GlobalCEFApp.RenderProcessHandler := FProcessHandler as ICefRenderProcessHandler;
2. Send to render process message with code for eval
Code: Select all
var
msg: ICefProcessMessage;
begin
msg := TCefProcessMessageRef.New(EVAL_JS);
msg.ArgumentList.SetString(0, sScript);
FChromium.SendProcessMessage(PID_RENDERER, msg);
3. Catch this message in render proccess
Code: Select all
procedure TChromiumClient.RenderProcessHandler_OnCustomMessage(const pBrowser: ICefBrowser;
uSourceProcess: TCefProcessId; const pMessage: ICefProcessMessage);
var
pV8Context : ICefv8Context;
pReturnValue : ICefv8Value;
pException : ICefV8Exception;
begin
if (pMessage = nil) or (pMessage.ArgumentList = nil) then exit;
if pMessage.Name = EVAL_JS then
begin
pV8Context := pBrowser.MainFrame.GetV8Context;
if pV8Context.Enter then
begin
pV8Context.Eval(pMessage.ArgumentList.GetString(0), '', 1, pReturnValue, pException);
ParseEvalJsAnswer(pMessage, pBrowser, pReturnValue, pException);
pV8Context.Exit;
end;
end;
end;
4. Parse the results and send message back to browser process
Code: Select all
procedure TChromiumClient.ParseEvalJsAnswer(const pMessage: ICefProcessMessage; pBrowser: ICefBrowser;
pReturnValue : ICefv8Value; pException : ICefV8Exception);
var
pAnswer: ICefProcessMessage;
strResult : String;
bGoodDataType : Boolean;
begin
pAnswer := TCefProcessMessageRef.New(EVAL_JS);
if (pReturnValue = nil) or (not pReturnValue.IsValid) then
begin
pAnswer.ArgumentList.SetBool(0, false);
pAnswer.ArgumentList.SetString(1, pException.Message);
end else
begin
bGoodDataType := True;
if pReturnValue.IsString then strResult := pReturnValue.GetStringValue
else if pReturnValue.IsBool then strResult := BooleanToStr(pReturnValue.GetBoolValue)
else if pReturnValue.IsInt then strResult := IntToStr(pReturnValue.GetIntValue)
else if pReturnValue.IsUInt then strResult := IntToStr(pReturnValue.GetUIntValue)
else if pReturnValue.IsDouble then strResult := FloatToStr(pReturnValue.GetDoubleValue)
else bGoodDataType := False;
if bGoodDataType then
begin
pAnswer.ArgumentList.SetBool(0, true);
pAnswer.ArgumentList.SetString(1, strResult);
end else
begin
pAnswer.ArgumentList.SetBool(0, false);
pAnswer.ArgumentList.SetString(1, 'Result data type need to be string, int, uint or double!');
end;
end;
pBrowser.SendProcessMessage(PID_BROWSER, pAnswer);
end;
5. And catch result message in OnProcessMessageReceived of browser process
P.S. Thank you,
salvadordf, for your work and help.