通过外部接口接收复杂的JavaScript值

通过外部接口接收复杂的JavaScript值

本文介绍了通过外部接口接收复杂的JavaScript值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想接收和潜在的通过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值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 20:47