paxCompiler for Delphi. Script-defined event handlers.


Script

type
  TMyHandler = class
     procedure Handle(Sender: TObject);
  end;

procedure  TMyHandler.Handle(Sender: TObject);
begin
   ShowMessage('Script-defined handler. Sender:  ' + Sender.ClassName);
end;

procedure  TMyHandler.Dispose(Sender: TObject);
begin
   Free;
end;

var
   X: TMyHandler;
   E: TNotifyEvent;

procedure SetHandler;
begin
   E := ClickMe.OnClick;
   ClickMe.OnClick := X.Handle;
end;

procedure RestoreHandler;
begin
   ClickMe.OnClick := E;
end;

begin
   X := TMyHandler.Create;

   Form1.OnDestroy := X.Dispose;
   ShowMessage('The script was compiled and initialized successfully.');
end.

Delphi Application

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, PaxProgram, PaxCompiler;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Memo1: TMemo;
    ClickMe: TButton;
    PaxCompiler1: TPaxCompiler;
    PaxPascalLanguage1: TPaxPascalLanguage;
    PaxProgram1: TPaxProgram;
    procedure Button1Click(Sender: TObject);
    procedure ClickMeClick(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
    P_SetHandler: Pointer;
    P_RestoreHandler: Pointer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  H_TButton, H_TForm1: Integer;

type
  TProcP = procedure;

// create compiled-script
procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  H: Integer;
begin
  if PaxProgram1.DataSize > 0 then
  begin
    ShowMessage('Script is already compiled.');
    Exit;
  end;

  PaxCompiler1.Reset;
  PaxCompiler1.RegisterLanguage(PaxPascalLanguage1);
  PaxCompiler1.AddModule('1', 'Pascal');
  PaxCompiler1.AddCode('1', Memo1.Lines.Text);
  PaxCompiler1.RegisterVariable(0, 'ClickMe', H_TButton, @ClickMe);
  PaxCompiler1.RegisterVariable(0, 'Form1', H_TForm1, @Form1);

  PaxPascalLanguage1.SetCallConv(_ccREGISTER);

  if PaxCompiler1.Compile(PaxProgram1) then
  begin
    H := PaxCompiler1.GetHandle(0, 'SetHandler', true);
    P_SetHandler := PaxProgram1.GetAddress(H);

    H := PaxCompiler1.GetHandle(0, 'RestoreHandler', true);
    P_RestoreHandler := PaxProgram1.GetAddress(H);

    PaxProgram1.Run;
  end
  else
    for I:=0 to PaxCompiler1.ErrorCount - 1 do
      ShowMessage(PaxCompiler1.ErrorMessage[I]);
end;

// set up script-defined event handler
procedure TForm1.Button2Click(Sender: TObject);
begin
  PaxProgram1.BeginCall;
  TProcP(P_SetHandler);
  PaxProgram1.EndCall;

  ShowMessage('ClickMe contains script-defined event handler now.');
end;

// restore host-defined event handler
procedure TForm1.Button3Click(Sender: TObject);
begin
  PaxProgram1.BeginCall;
  TProcP(P_RestoreHandler);
  PaxProgram1.EndCall;

  ShowMessage('Host-defined handler is restored.');
end;

procedure TForm1.ClickMeClick(Sender: TObject);
begin
  ShowMessage('Host-defined event handler. Sender: ' + Sender.ClassName);
end;

initialization

  H_TButton := RegisterClassType(0, TButton);
  H_TForm1 := RegisterClassType(0, TForm1);
  RegisterHeader(0, 'procedure ShowMessage(const Msg: string);', @ShowMessage);

end.


Copyright © 2006-2017 Alexander Baranovsky. All rights reserved.