2011-07-31 13 views
15

Udało mi się osadzić Chromium w moich projektach Delphi 6 przy pomocy Delphi Chromium Embedded. Teraz chcę mieć możliwość uruchomienia kodu Javascript i mieć wyniki zwrócone do mojej aplikacji Delphi hosta. Moja obecna metoda polega na wywołaniu ExecuteJavascript() i użyciu elementu DOM, do którego wywołanie JavaScript zapisuje swoje wyniki, i odpytania tego elementu w metodzie TTimer od Delphi w celu pobrania wyników. Jednak czytałem o użyciu natywnych funkcji i rozszerzeń V8 mieć JavaScript nazywają „call back” do mojego kodu Delphi jako sposób, aby otrzymać wyniki zamiast:Jak odsłonić "funkcje macierzyste" do Javascript na stronie internetowej przy użyciu Chromium i Delphi 6?

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

chciałbym spróbować to i ja też chciałby wiedzieć, jak dołączyć detektory zdarzeń oparte na Delphie do elementów DOM na stronie internetowej (onblur, onmousedown itp.). Szukam próbek, które pokażą mi, jak zrobić te dwie rzeczy, jeśli ktoś wie, gdzie je znaleźć.

+2

Wow, Delphi-6, gdzie musisz ręcznie wykonywać wszystkie kody Unicode i Chromium z pełną obsługą Unicode.Teraz brzmi jak niedopasowanie impedancji do mnie :) –

+0

"Niedopasowanie impedancji". W pokoju jest inżynier elektronik. :) Masz rację, ale Delphi 6 nadal jest moim ulubionym IDE. Przynajmniej na razie. –

+0

Chciałbym być inżynierem elektroniki; Nigdy nie miałem okazji studiować tego, ale wciąż mam wrażenie, że wiedza o inżynierii elektronicznej i odczuwaniu tego, co może pójść nie tak, jest niezwykle przydatna w IT. Rozumiem cię jak Delphi 6, ale zachęcam do zapoznania się z bardziej aktualnymi wersjami. Niedawno musiałem wrócić, a było tak wiele brakowało ... –

Odpowiedz

14

Mocowanie słuchaczy jest dość łatwe (tylko w starszych wersjach 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; 

W odniesieniu do rozszerzonych funkcji dla uzyskania JavaScript wynika bezpośrednio: (? Jeszcze) bagażnik ich nie zawierają. Wygląda na pracę w toku.

Edit:

Pozbycie odpytywanie poprzez rozszerzeń:

To jest rzeczywiście możliwe, kod JavaScript, żeby zadzwonić do kodu Delphi za pomocą rozszerzeń. Ponadto możesz przesyłać wartości z JavaScript do Delphi - może to służyć do przesyłania wyników bez potrzeby odpytywania.

Najpierw w sekcji initialization zarejestrować rozszerzenie, który tworzy obiekt JavaScript później ma być używany podczas oddzwanianie:

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 zostanie wywołana później. TMyHandler jest zdefiniowany jako

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

Realizacja dla celów demonstracyjnych jest prosta do teraz:

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

teraz przetestować dzwoniąc pod Delphi z JavaScript po prostu zrobić:

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

ta powinna wyświetlić komunikat z komunikatem "Execute!".

wyciągnąłem skrypt demo z próbki nazwie cefclient które można znaleźć w \ demos \ cefclient folderu w głównym składnikiem reż. Kod przykładowy rozszerzenia jest nieco ukryty i zmieszany z innym kodem demo. Ale dla nas szczególne znaczenie ma implementacja TExtension.Execute (odpowiednik mojego TMyHandler.Execute). Tam możesz dowiedzieć się, jak określić, która funkcja jest wywoływana i jak przekazywać parametry. (Link to the code.)

+0

Dziękuję Heinrich. Tego właśnie potrzebowałem. "Jeśli chodzi o rozszerzone funkcje uzyskiwania wyników JavaScript ...". Jeden z wątków, które przeczytałem, wskazywał na pewne obawy, ponieważ wymagałoby to zablokowania wywołującego wątku podczas zwracania wyniku. Rozumiem tę troskę, ale osobiście chciałbym ją zobaczyć, stosując zwykłe zastrzeżenia dotyczące blokowania wątków. Ale to moja opinia. –

+0

Cieszę się, że mogę pomóc. W pełni zgadzam się, że rozszerzone funkcje mogą być przydatne, szczególnie przydatne jest 'executeScriptAndReturnValue'. –