2012-09-23 55 views
5

我想知道DWScript是否支持使用腳本方法作爲Delphi窗體上控件的事件處理程序。例如,我想將TButton OnClick事件鏈接到腳本中存在的方法。Delphi Web腳本(DWScript)將腳本方法鏈接到外部控件事件

我可以用RemObjects Delphi腳本引擎通過調用返回TMethod對象的GetProcMethod來做到這一點。然後,我使用SetMethodProp將腳本方法分配給按鈕的OnClick事件。

procedure LinkMethod(SourceMethodName: String; Instance: TObject; ScriptMethodName: String); 
var 
    ScriptMethod: TMethod; 
begin 
    ScriptMethod := ScriptEngine.GetProcMethod(ScripMethodName); 

    SetMethodProp(Instance, SourceMethodName, ScriptMethod); 
end; 

我想這樣做在DWScript代替雷姆對象的腳本引擎,因爲它做一些其他的東西,我需要。

回答

2

我決定改用RemObjects。這是最容易使用,並做我需要的。

1

AFAIK 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能做這樣的事情。 –

+0

目前還沒有完成,因爲DWScript是完全可以沙盒化的,並且旨在實現安全,RemObject使用的方法會導致內存損壞或崩潰(如果參數不匹配)。 RTTI在這方面已經取得了一些進展,但它仍然容易受到內存泄漏或AV的影響,因爲沒有辦法自動化Delphi事件的內存管理。 如果有人可以忍受這些限制併發布支持代碼,我會將其與適當的「謹慎」通知進行整合......-) –