是否可以使用IActiveScript中可变数量的参数调用Delphi方法?

时间:2011-03-06 13:43:06

标签: javascript delphi scripting

我正在使用Delphi 2006和psvActiveScript

示例:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, 
  ObjComAuto, ComObj, psvActiveScript;

type
  TForm1 = class(TForm)
    btnExecute: TButton;
    procedure btnExecuteClick(Sender: TObject);
    procedure ASWError(Sender: TObject; Line, Pos: Integer; ASrc, ADescription: String);
  end;

var
  Form1: TForm1;
  ASW: TpsvActiveScriptWindow;

implementation

{$R *.DFM}

type
  {$METHODINFO ON}
  TMySriptableClass = class(TObjectDispatch)
  public
    constructor Create;
    procedure Alert(msg: string);
    // THIS OR SOMETHING SIMILAR NOT POSSIBLE? **********************
    function FnWithVarNumOfArgs(const args: array of string): string;
    // **************************************************************
  end;
  {$METHODINFO OFF}

constructor TMySriptableClass.Create;
begin inherited Create(Self, False); end;

procedure TMySriptableClass.Alert(msg: string);
begin ShowMessage(msg); end;

function TMySriptableClass.FnWithVarNumOfArgs(const args: array of string): string;
begin Result := 'OK'; end;


procedure TForm1.btnExecuteClick(Sender: TObject);
var
  MyObj: TMySriptableClass;
begin
  ASW := TpsvActiveScriptWindow.Create(self);
  ASW.ScriptLanguage := 'JScript';
  ASW.OnError := ASWError;

  MyObj := TMySriptableClass.Create;
  ASW.AddNamedItem('MyObj', MyObj);

  try
    ASW.Execute(
      'MyObj.Alert("Warning: Here comes Error");'+
      'MyObj.FnWithVarNumOfArgs("1","2","3")'
    );
  finally
    ASW.Free;
  end;
end;

procedure TForm1.ASWError(Sender: TObject; Line, Pos: Integer; ASrc, ADescription: String);
begin Showmessage(ADescription + ': ' + ASrc); end;

end.

2 个答案:

答案 0 :(得分:2)

[...]
uses
  activex, objcomauto, comobj;

type
  {$METHODINFO ON}
  TMySriptableClass = class(TObjectDispatch)
  public
    [...]
    function FnWithVarNumOfArgs(const args: OleVariant): string;
    [...]


function TMySriptableClass.FnWithVarNumOfArgs(const args: OleVariant): string;
var
  dispParams: activex.DISPPARAMS;
  vtRet, Element: OleVariant;
  Enum: IEnumVARIANT;
  Fetched: LongWord;
begin
  if TVarData(args).VType = varDispatch then begin
    OleCheck(IDispatch(args).Invoke(DISPID_NEWENUM, GUID_NULL,
                                    LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
                                    dispParams, @vtRet, nil, nil));
    Enum := IUnknown(vtRet) as IEnumVARIANT;
    while (Enum.Next(1, Element, Fetched) = S_OK) do
      ShowMessage(Element);
  end;

  Result := 'OK';
end;


    [...]
    ASW.Execute('var myArray=["myarg1", 5, true];' +
                'MyObj.FnWithVarNumOfArgs(myArray);');
    [...]

答案 1 :(得分:1)

现在你已经设置了它的方式,你需要传入一个字符串数组,因为你声明了这个参数。 在Delphi中,可以使用

来完成
MyObj.FnWithVarNumOfArgs(Array("1","2","3"))

这会创建一个具有给定值的动态arry,然后将其传递给FnWithVarNumOfArgs。

从脚本语言 Delphi的Array函数肯定不可用,你需要用指针做一些聪明的事情,我不知道你是否能够让它工作。

可能你最好的选择是使用所谓的Variant Open Array Parameters。

来自帮助:http://docwiki.embarcadero.com/RADStudio/en/Parameters_(Delphi)#Variant_Open_Array_Parameters

  

变量开放数组参数允许   你以不同的方式传递数组   键入的表达式为单个   程序或功能。定义一个   例程与变量打开数组   参数,指定const数组为   参数的类型。因此

     程序DoSomething(A:数组   常数);

     

声明一个名为的过程   DoSomething可以操作   异构数组。

     

const构造的数组是   相当于TVReRe的数组。   TVarRec,在系统单元中声明,   表示具有变体的记录   可以保存整数值的部分,   布尔,字符,真实,字符串,   指针,类,类引用,   接口和变体类型。   TVarRec的VType字段表示   数组中每个元素的类型。   某些类型作为指针传递   而不是价值;特别是,   字符串作为指针传递并且必须   被强制转换为字符串。