2011-07-31 16 views
15

He incrustado con éxito Chromium en mis proyectos Delphi 6 con la ayuda de Delphi Chromium Embedded. Ahora quiero poder ejecutar código Javascript y tener los resultados devueltos a mi aplicación host Delphi. Mi método actual es llamar a ExecuteJavascript() y usar un elemento DOM al que la llamada Javascript escribe sus resultados, y sondear ese elemento en un método TTimer de Delphi para recuperar los resultados. Sin embargo, he leído sobre el uso de las funciones nativas y extensiones V8 de tener el Javascript llamada "call back" en mi código de Delphi como una manera de recibir los resultados de su lugar:¿Cómo exponer "funciones nativas" a Javascript en una página web usando Chromium y Delphi 6?

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

me gustaría probar esto y yo también me gustaría saber cómo adjuntar detectores de eventos basados ​​en Delphi a elementos DOM en la página web (onblur, onmousedown, etc.). Estoy buscando algunas muestras que me muestren cómo hacer estas dos cosas si alguien sabe dónde encontrarlas.

+2

Wow, Delphi-6 donde tienes que hacer todo Unicode a mano y Chromium con soporte completo Unicode.Ahora eso suena como un desajuste de impedancia para mí :) –

+0

"Impedancia no coincidente". Hay un ingeniero de electrónica en la sala de gente. :) Tienes razón, pero Delphi 6 sigue siendo mi IDE favorito. Por ahora. –

+0

Ojalá fuera un ingeniero de electrónica; Nunca tuve la oportunidad de estudiarlo, pero todavía tengo la sensación de que conocer la ingeniería electrónica y tener una idea de qué puede salir mal allí es tremendamente útil en la TI. Entiendo que te guste Delphi 6, pero te insto a que busques versiones más actuales. Recientemente tuve que volver, y había tanto que extrañaba ... –

Respuesta

14

Colocación de los oyentes es bastante fácil (sólo en las versiones anteriores de 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; 

En cuanto a las funciones ampliadas para conseguir JavaScript resultados directamente: (¿aún) el tronco no los contiene. Parece ser un trabajo en progreso.

Editar:

Deshacerse de sondeo a través de extensiones :

De hecho, es posible que el código JavaScript para llamar de nuevo en su código de Delphi usando extensiones. Además, puede enviar valores de JavaScript a Delphi; esto podría usarse para transferir resultados sin necesidad de sondear.

Primero en su sección initialization registrar la extensión, lo que crea un objeto JavaScript para posteriormente ser usado en la llamada de vuelta:

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 se invocará después. TMyHandler se define como

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

La aplicación con fines de demostración es simple por ahora:

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

Ahora para probar la llamada en Delphi desde JavaScript simplemente hacer:

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

Esto debería mostrar la cuadro de mensaje que dice "¡Ejecutar!".

Saqué el guión de demostración de una muestra llamada cefclient que se puede encontrar en las \ demos \ cefclient carpeta en el directorio raíz de componentes. El código de muestra de extensión está un poco oculto y mezclado con otro código de demostración. Pero de especial interés para nosotros es la implementación de TExtension.Execute (el equivalente a mi TMyHandler.Execute). Allí puede encontrar cómo determinar qué función se está llamando y cómo pasar parámetros. (Link to the code.)

+0

Gracias Heinrich. Eso es lo que necesitaba. "En cuanto a las funciones extendidas para obtener resultados de JavaScript ...". Uno de los hilos que leí indicó que había algo de preocupación sobre esto porque implicaría bloquear el hilo de llamada mientras se devolvía el resultado. Entiendo esa preocupación, pero personalmente me gustaría verla con las advertencias habituales sobre bloqueo de hilos. Pero esa es mi opinión. –

+0

Me alegro de ser de ayuda. Estoy totalmente de acuerdo en que las funciones extendidas podrían ser útiles, especialmente los sonidos 'executeScriptAndReturnValue' a la mano. –

Cuestiones relacionadas