2012-09-23 14 views
5

Mi chiedo se DWScript supporti l'utilizzo di un metodo di script come gestore di eventi per un controllo su un modulo Delphi. Ad esempio voglio collegare un evento OnClick di TButton a un metodo che esiste nello script.Delphi Web Script (DWScript) collega un metodo di script a un evento di controllo esterno

Sono in grado di farlo con il motore di script RemObjects Delphi chiamando GetProcMethod che restituisce un oggetto TMethod. Quindi utilizzo SetMethodProp per assegnare il metodo di script all'evento OnClick di un pulsante.

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

    SetMethodProp(Instance, SourceMethodName, ScriptMethod); 
end; 

mi piacerebbe farlo in DWScript al posto del Rem oggetti motore di script, come fa alcune altre cose che ho bisogno.

risposta

2

Ho deciso di andare con RemObjects. Era il più facile da usare e fa quello di cui ho bisogno.

1

AFAIK DWScript non supporta direttamente ciò che si sta tentando di ottenere ma potrebbe essere implementato in modo diverso. Proverò a postare del codice sorgente su come potrebbe essere implementato, ma probabilmente dovrai adattarlo alle tue esigenze.

In primo luogo, dichiarare un po 'di classe wrapper che dovrebbe essere separata per ogni metodo di script:

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; 

Ora dobbiamo creare un'istanza di questa classe da qualche parte nel nostro codice (ad esempio in creare l'evento di modulo):

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; 

Ora, quando chiamiamo MainClick nostro script viene compilato ed eseguito:

Script method executed from form's event

+1

Grazie per quello. Purtroppo però non conoscerò il nome dell'evento dei parametri richiesti fino al runtime. RemObjects gestisce l'intercettazione della chiamata all'evento e l'inoltro dei parametri sul gestore di eventi script. In questo modo non hai bisogno di sapere nulla sul metodo che viene invocato in fase di compilazione. Speravo che DWS facesse qualcosa del genere. –

+0

Al momento non è possibile perché DWScript è pensato per essere completamente sandboxable e mira alla sicurezza, l'approccio utilizzato da RemObject causerà corruzione della memoria o arresti anomali in caso di mancata corrispondenza tra i parametri. L'RTTI è progredito un po 'su questo, ma sarà comunque vulnerabile a perdite di memoria o AV, dal momento che non c'è modo di automatizzare la gestione della memoria per gli eventi Delphi. Se qualcuno può vivere con queste limitazioni e pubblicare il codice di supporto, lo integrerò ... con le opportune avvertenze "cautela" ;-) –