Delphi Web Script(DWScript)如何将脚本方法链接到外部控件事件?

5
我想知道DWScript是否支持将脚本方法用作Delphi窗体上控件的事件处理程序。例如,我想将TButton的OnClick事件链接到脚本中存在的方法。
使用RemObjects Delphi脚本引擎,可以通过调用GetProcMethod来返回一个TMethod对象来实现此功能。然后,使用SetMethodProp将脚本方法分配给按钮的OnClick事件。
procedure LinkMethod(SourceMethodName: String; Instance: TObject; ScriptMethodName: String);
var
  ScriptMethod: TMethod;
begin
  ScriptMethod := ScriptEngine.GetProcMethod(ScripMethodName);

  SetMethodProp(Instance, SourceMethodName, ScriptMethod);
end;

我希望使用DWScript来完成这个任务,而不是Rem对象脚本引擎,因为DWScript可以执行我需要的其他一些操作。
2个回答

2

我决定选择RemObjects,它最易于使用并且可以满足我的需求。


1
据我所知,DWScript不直接支持您尝试实现的功能,但可以以不同的方式实现。 我会尝试发布一些源代码,说明如何实现它,但您可能需要根据自己的需求进行调整。
首先,声明一个小包装类,每个脚本方法应该分开声明:
type
  TDwsMethod = class
  private
    FDoExecute: TNotifyEvent;
    FScriptText: string;
    FDws: TDelphiWebScript;
    FLastResult: string;
    FMethod: TMethod;
  protected
    procedure Execute(Sender: TObject);
  public
    constructor Create(const AScriptText: string); virtual;
    destructor Destroy; override;

    property Method: TMethod read FMethod;
    property LastResult: string read FLastResult;
  published
    property DoExecute: TNotifyEvent read FDoExecute write FDoExecute;
  end;

constructor TDwsMethod.Create(const AScriptText: string);
begin
  inherited Create();
  FDoExecute := Execute;
  FScriptText := AScriptText;
  FDws := TDelphiWebScript.Create(nil);
  FMethod := GetMethodProp(Self, 'DoExecute');
end;

destructor TDwsMethod.Destroy;
begin
  FDws.Free;
  inherited Destroy;
end;

procedure TDwsMethod.Execute(Sender: TObject);
begin
  ShowMessage('My Method executed. Value: ' + FDws.Compile(FScriptText).Execute().Result.ToString);
end;

现在我们必须在代码中的某个地方创建这个类的实例(例如,在窗体的创建事件中):
procedure TMainForm.FormCreate(Sender: TObject);
begin
  FDWSMethod := TDwsMethod.Create('PrintLn(100);'); //in constructor we pass script text which needs to be executed
  //now we can set form's mainclick event to our DWS method
  SetMethodProp(Self, 'MainClick', FDWSMethod.Method);
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  FDWSMethod.Free;
end;

现在当我们调用MainClick时,我们的脚本被编译并执行:

Script method executed from form's event


1
谢谢您的回复。不幸的是,直到运行时我才能知道事件的名称和所需的参数。RemObjects 处理拦截事件调用并将参数转发到脚本事件处理程序。这样,您在编译时不需要了解被调用的方法的任何信息。我希望 DWS 也能做到这一点。 - There is no spoon
目前还没有完成,因为DWScript旨在完全可隔离且旨在安全,RemObject使用的方法将导致参数不匹配时出现内存损坏或崩溃。 RTTI在这方面取得了一些进展,但仍然容易受到内存泄漏或AV的影响,因为无法自动管理Delphi事件的内存。如果有人可以接受这些限制并发布支持代码,我会集成它...附带适当的“警告”提示;-) - Eric Grange

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接