{$O-}

unit Unit1;

interface

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

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;

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;

procedure TForm1.Button2Click(Sender: TObject);
begin
  TProcP(P_SetHandler);
  ShowMessage('ClickMe contains script-defined event handler now.');
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  TProcP(P_RestoreHandler);
  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.
