Recently, a callback JS function has been encountered when uploading and constructing an embedded browser.
First, I can use the External Object in webbrowser to implement interaction between JS and Delphi.
Expose such an interface to JS through external
procedure UploadFile(FileName:String; Callback:Variant);
JS calls
External. uploadfile ('C: \ test.txt ', function (sentsize, totalsize) {alert (sentsize )})
You can directly trigger the upload and accept the upload progress in real time.
The problem is that variant has the following restrictions in Delphi:
VaR X: variant; begin X: = something; X. callback (); // method 1, which can be executed normally; X (); // method 2, which cannot be compiled through end.
If JS sends a callback like this, an object is sent, instead of a function:
External. uploadfile ('C: \ test.txt ', {callback: function (sentsize, totalsize) {alert (sentsize )}})
The problem will be solved. According to the previous definition, JavaScript sends an anonymous function, and in Delphi, it means the idispatch or variant type. We cannot directly write brackets behind it, called as a function.
I read the COM object call document with my research mentality and obtained the following method to call the function objects sent from Js.
procedure DoCallback(Disp:Dispatch; Params: array of Variant);var I: Integer; Ret: Variant; Args: array of Variant; DispParams: TDispParams;begin SetLength(Args, Length(Params)); for I := 0 to Length(Params) - 1 do Args[Length(Params) - I - 1] := Params[I]; DispParams.cArgs := Length(Args); if Length(Args) > 0 then DispParams.rgvarg := @Args[0] else DispParams.rgvarg := nil; DispParams.cNamedArgs := 0; DispParams.rgdispidNamedArgs := nil; Disp.Invoke(0, GUID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, DispParams, @Ret, nil, nil);end;
The DISP parameter is a function object sent from JS and can be converted to the idispatch interface;
Call an instance
Docallback (disp, [1, 2, 3]);