Run project with forms

In my application I have two scripter related forms, one where the customer can design a scripter form and save the files. This is very similar to theDelphiformediting demo.
On another form I want to run scripter with that saved files, but without the IDE components in this case. The operator should be able to watch that script form from but not to change it.
I have two pascal files, the main unit uTeilebild.pas :

  • uses
  •   Classes, Graphics, Controls, Forms, Dialogs, Teilebild;
  • var
  •   MainForm: TFormTeilebild;
  • begin
  •   MainForm := TFormTeilebild.Create(Application);
  •   MainForm.Show;
  • end;
the Teilbild.pas unit :
  • {$FORM TFormTeilebild, Teilebild.sfm}
  • uses
  •   Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
  •   ExtCtrls;
  • begin
  • end;
the Teilebild.sfm file :
  • object FormTeilebild: TScriptForm
  •   Caption = 'FormTeilebild'
  •   ClientHeight = 512
  •   ClientWidth = 608
  •   Color = clBtnFace
  •   Font.Charset = DEFAULT_CHARSET
  •   Font.Color = clWindowText
  •   Font.Height = -11
  •   Font.Name = 'Tahoma'
  •   Font.Style = []
  •   GlassFrame.Enabled = True
  •   OldCreateOrder = False
  •   Position = poDesigned
  •   SaveProps.Strings = (
  •     'Visible=False'
  •     'BorderStyle=bsSizeable')
  •   PixelsPerInch = 96
  •   TextHeight = 13
  •   object lbHeader: TLabel
  •     Left = 0
  •     Top = 0
  •     Width = 608
  •     Height = 33
  •     Align = alTop
  •     Alignment = taCenter
  •     AutoSize = False
  •     Caption = 'Teilebild'
  •     Color = clSilver
  •     Font.Charset = DEFAULT_CHARSET
  •     Font.Color = clWindowText
  •     Font.Height = -27
  •     Font.Name = 'Tahoma'
  •     Font.Style = []
  •     ParentColor = False
  •     ParentFont = False
  •     ExplicitLeft = 16
  •     ExplicitTop = 24
  •     ExplicitWidth = 577
  •   end
  •   object Shape1: TShape
  •     Left = 0
  •     Top = 33
  •     Width = 608
  •     Height = 1
  •     Align = alTop
  •     ExplicitLeft = 8
  •     ExplicitTop = 63
  •     ExplicitWidth = 593
  •   end
  • end
and finally the Teilebild.ssproj file :
  • [Files]
  • File1=uTeilebild.psc
  • Language1=0
  • File2=Teilebild.psc
  • Language2=0
  • FileCount=2
  • MainUnit=uTeilebild
I tried the atPascalFormScripter
    atPascalFormScripter1.ScriptFile := 'uTeilebild.psc';
    atPascalFormScripter1.Execute;

Nothing happens, what am i doing wrong ?

First comment: although it's not related to the problem, please use TatScripter instead of TatPascalFormScripter, which is deprecated.

About your problem, it must be that you are executing a different script. When using scripter component, you must be sure you have set the correct script as the current script using Currentscript property (which should be the uTeilebild.psc). 
Also, the .ssproj is not used by scripter, it's only used by TIDEEngine component. If you want to use the same project approach, use TIDEEngine to load the project and then execute it.

Finally it seems that this Problem is solved using the following code :



procedure TFormTBCarrier.btnStartScriptClick(Sender: TObject);

var

     atscript : TatScript;

begin

     atscript := atScripter1.AddScript(slPascal);

     atscript.SourceCode.LoadFromFile('uTeilebild.psc');

     atscripter1.DefaultLanguage := slPascal;

     atscripter1.LibOptions.FormFileExt := '.sfm';

     atscripter1.LibOptions.SourceFileExt := '.psc';

     atscripter1.LibOptions.UseScriptFiles := true;

     atScripter1.CurrentScript := atscript;

     RegisterClasses([TLabel, TShape]);

     atscripter1.AddComponent(FormTBCarrier);

     atScripter1.Execute;

end;



However, there is a still a Problem.

Although I added the VCL form FormTBCarrier with the AddComponent method, I get an error message if I want to make this form the parent of the scripts form.



The script code in uTeilebild.psc has been slightly expanded :

uses

Classes, Graphics, Controls, Forms, Dialogs, Teilebild;



var

     MainForm: TFormTeilebild;

begin

     MainForm := TFormTeilebild.Create(Application);

     MainForm.Parent := FormTBCarrier;

     MainForm.BorderStyle := bsNone;

     MainForm.Show;

end;



The errormessage is 'Unknown identifier or variable is not declared : FormTBCarrier

source Position 8,35'.

Without the reference to FormTBCarrier the script form is displayed without Errors.



I try to integrate the script form seamlessly in my existing vcl form so there is no visual or behavioural difference to the VCL form. I hope this is possible.

Are you sure the Name property of the form is "FormTBCarries"? Try using AddObject and explicitly set the form name:

atScripter1.AddObject(FormTBCarrier, 'FormTBCarrier');

Second try, first answer was lost.



Adding the AddObject line solves the Problem.



     atscripter1.AddComponent(FormTBCarrier);

     atscripter1.AddObject('FormTBCarrier', FormTBCarrier);



When I comment out the second line, I get the error, otherwise it works.



Please note, that TFormTBCarrier inherits from TBaseForm. This is a Standard TForm with some basic application functionality.



Mysteriously, when I use the applications mainform, where TFormTBCarrier is called from, no AddObject is necessary, it works without errors.

AddComponent is just a helper method. All it does is:

  AddObject(Component.Name, Component);

So, as I said, probably at the time you call AddComponent, the Name property of FormTBCarrier is not set.

Meanwhile I added a variable named pownForm, see class declaration :



// begin class declaration / definition -------------------------------------------------------------

type

TFormTBCarrier = class(TFormBaseScreen)

      atScripter1: TatScripter;

    Timer1: TTimer;

    procedure FormShow(Sender: TObject);

    procedure Timer1Timer(Sender: TObject);

    procedure FormDestroy(Sender: TObject);

private

      { Private-Deklarationen }

          pOwnform : TFormBaseScreen;

          designmode : boolean;

public

      { Public-Deklarationen }

end;



var

FormTBCarrier: TFormTBCarrier;

// end class declaration / definition -------------------------------------------------------------



// part of script calling Routine -------------------------------------------------------------

     pOwnForm := FormTBCarrier;

//     atscripter1.AddComponent( pOwnForm );

     atscripter1.AddObject( 'pOwnForm', pOwnForm );

// end of script calling Routine -------------------------------------------------------------



I created the line containing AddComponent by copying the AddObject line and changing it.

This is surely the safest way to guarantee that the name of pownForm does not differ between them.

When the AddComponent line is commented out, as in the example above, the script runs without Errors.

If I move the comment from the AddComponent to the AddObject I get the errormessage 'Unknown identifier or variable is not declared : pOwnForm'.



Hi Gerhard, 

yes, that's expected. Not sure if you asked a question or is just confirming what I have said?

I wanted to inform you that there must be some problem with the AddComponent function. I know that it is just a helper function but in my application AddObject works and AddComponent does not. I made absoluteley sure that the same name is used in the call of them and this is what I tried to tell you.

Since I have a working solution there is no need to hurry.

Maybe I can manage to prepare a demo project to illustrate the problem.

Here is a downloadlink to a small demo project, that illustrates the Problem.

As compiled it will throw an error.

If the comments on AddComponent/AddObject are exchanged, it runs.



Demo project addComponent error

There is no problem, that's what I'm trying to say to you. TMS Scripter can't "read" Delphi variable names. It does not know the name of the component from your Delphi variable. It knows the name of the component from the Name property of the component. For example, to make your code work with AddComponent, you need to add this line before calling AddComponent:


  pOwnForm.Name := 'pOwnForm';
  atscripter1.AddComponent( pOwnForm );

Usually AddComponent works fine because the name of the component is set to the correct value. Which is not your case here, so there is no way scripter would register such instance as "pOwnForm" without having the Name property of the component set properly.

OK I understood.

pOwnForm was introduced as debug aid, but caused confusion in this case.

Previously I worked with the original component FormTBCarrier where the Name property was already set correctly.

Thank you for the help.