问题描述
我想接收和潜在的通过TWebBrowser(使用TEmbeddedWB)与提供的外部对象发送复杂的值。
例如;在JavaScript我会尝试使用公开方法与数组作为参数:
I'm trying to receive and potentially send complex values through TWebBrowser (using TEmbeddedWB) with the provided external object.For example; in javascript I would try to use the exposed method with an array as a parameter:
var test = [123, 'abc'];
external.someFunction(test);
//Or something more complex
var complexObject = {
someMethod : function(){ return 1; },
someProperty : 123,
someArray : ['xyz', 3.14]
}
external.someFunction(complexObject);
检查这两个例子中的VarType函数告诉我这是一个IDispatch接口。
Checking the VarType of both of these examples tells me it's a IDispatch.
function TSomeClass.someFunction(var Param : OleVariant) : OleVariant;
var
vType : Integer;
begin
vType := (VarType(Param) and VarTypeMask); //Says 9 (varDispatch)
Result := true;
end;
我不完全熟悉COM,我不知道如何使用这方面的工作。
I'm not completely familiar with COM and I'm not sure how to work with this.
任何帮助将是AP preciated。
Any help would be appreciated.
推荐答案
您可以把JScript的对象,就像任何其他OleVariant COM对象。有一些稍微在阵列的术语(和几乎任何的JScript对象本质上是一个稀疏数组)。
You can treat the JScript object just as any other OleVariant COM object. There are a few gotchas in terms of arrays (and just about any JScript object is essentially a sparse array).
获取JScript的对象到一个OleVariant以后,就可以调用它,就像任何普通code(不带编译的时候,当然检查)。
After getting the JScript object into an OleVariant you can simply call it as you would any normal code (without compile time checking of course).
下面是一些code处理数组:
Here is some code for dealing with arrays:
type
TJScriptArray = class
private
FArray: IDispatchEx;
FCount: Integer;
function GetProperty( const AName: String ): OleVariant;
function GetItem(Index: Integer): OleVariant;
public
constructor Create( AObj: OleVariant );
destructor Destroy; override;
public
property Count: Integer read FCount;
property Item[Index: Integer]: OleVariant read GetItem; default;
end;
function VarToDispatchEx( const AObject: OleVariant ): IDispatchEx;
begin
Result := nil;
if VarType( AObject ) <> varDispatch then
Exit;
Supports( IDispatch(AObject), IDispatchEx, Result );
end;
function IsJScriptArray( const AObject: OleVariant ): Boolean;
var
temp: IDispatchEx;
begin
temp := VarToDispatchEx( AObject );
Result := temp <> nil;
end;
constructor TJScriptArray.Create(AObj: OleVariant);
begin
inherited Create;
FArray := VarToDispatchEx( AObj );
if FArray = nil then
raise Exception.Create( 'TJscriptArray called with invalid parameters.' );
FCount := GetProperty( 'length' );
end;
destructor TJScriptArray.Destroy;
begin
inherited Destroy;
end;
function TJScriptArray.GetItem(Index: Integer): OleVariant;
begin
if Index > FCount then
raise Exception.Create( 'Index out of bounds.' );
Result := GetProperty( IntToStr( Index ) );
end;
function TJScriptArray.GetProperty(const AName: String): OleVariant;
var
sz: WideString;
id: Integer;
res: Variant;
ei: TExcepInfo;
params: TDispParams;
hr: HResult;
begin
{
ACTION: return the specified property from the jscript array
NOTE: since a jscript array is a sparse array there may be
gaps. In that case a null variant is returned. This is
signalled by the name (id) not existing.
}
sz := AName;
hr := FArray.GetDispID( PWideChar(sz), 0, id );
if hr = disp_e_UnknownName then begin
Result := Null;
Exit;
end
else
OleCheck( hr );
VarClear( res );
FillChar( ei, sizeof(ei), 0 );
FillChar( params, sizeof(params), 0 );
OleCheck( FArray.InvokeEx( id, 0, dispatch_PropertyGet, @params, @res, @ei, nil ) );
Result := res;
end;
这篇关于通过外部接口接收复杂的JavaScript值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!