javascript - 通过外部接口(interface)接收复杂的 JavaScript 值

标签 javascript delphi com browser external

我正在尝试使用提供的外部对象通过 TWebBrowser(使用 TEmbeddedWB)接收并可能发送复杂值。 例如;在 javascript 中,我会尝试使用公开的方法并以数组作为参数:

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。

function TSomeClass.someFunction(var Param : OleVariant) : OleVariant;
var
  vType : Integer;
begin
  vType := (VarType(Param) and VarTypeMask); //Says 9 (varDispatch)
  Result := true;
end;

我对 COM 并不完全熟悉,并且不确定如何使用它。

如有任何帮助,我们将不胜感激。

最佳答案

您可以像对待任何其他 OleVariant COM 对象一样对待 JScript 对象。数组方面存在一些问题(几乎所有 JScript 对象本质上都是稀疏数组)。

将 JScript 对象放入 OleVariant 后,您可以像调用任何普通代码一样简单地调用它(当然不需要编译时检查)。

这里是一些处理数组的代码:

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 - 通过外部接口(interface)接收复杂的 JavaScript 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/923736/

相关文章:

javascript - jQuery 向上/向下滑动效果不适用于 div

delphi - Delphi 的 $WARN 编译器指令的标识符

c++ - ATL C++ 内存泄漏与 ccomobjects safearray

delphi - 重新编译 RTL - 如果可能,那么如何?

c# - 使用包含特殊字符的密码通过 SAML 请求 STS token

delphi - 如何将 IAutoComplete 与 TStringsAdapter 一起使用?

c++ - Microsoft Word 连接点接收器示例/MFC 出现问题

javascript - 如何在 React 中使用 setState() 来清空/清除数组的值

javascript - 使用 jQuery 更新文本匹配的 HTML 容器文本

javascript - Knockout.js 未正确设置选择选项