How to know when the IDEEngine has completed work?


I finally managed to load user create project from DB and run it but now I am not able to detect as to when the Project has completed its work and the user has closed the project.

I am using following code:
LoadFromDB(PrjID);  //Do all the work to load the Project in IDEEngine
IDEEngine1.RunProject;  //Run/Execute it

So finally the project is getting loaded from DB successfully and I am able to run the project.

But now I am not able to detect as to when the project completed its activity/work.

How to detect as to when the IDEEngine or IDEScripter has completed its job?



That depends on your script and then way you interact your Delphi application with script.

A typical script project would create a form instance and call "Show" method, and finalize. So the project was "finished" already, but the form is still visible of course. It's up to you to define and setup what does it mean "project completed is activity/work".
Hello Wagner,

I do not allow the user of my software to run single scripts. It is always a project.

Now what is happening is that after a user runs a project and it is completed I have programmed to check all the updates done by the project in two tables in DB and accordingly perform some actions.

But I am not able to detect as to when the user completed is work in the Project that was run and closed the main form of the project.

Are there any possibilities to being able to add an event in the source of Scripter (IDEENgine) that would fire when a projects completes its work and all the forms associated with the project are unloaded from memory?



When scripter runs, show a form, and leave, you are left to Delphi. The scripter has stopped running already, the form is just a regular Delphi form.
You must manually set the OnClose event of script form and handle notifications there. At a more infra level, you can define a descendant of TScriptForm, override some methods to include your notification system, and then set that descendant form as your base class for script forms:

Atscripter1.ScriptFormClass := TMyScriptForm;

There is the event OnRunningChanged for the scripter, but as I said, the following script:


Will just run and finish, but the form will still be there.

Hello Wagner,

Is there a way by which I can iterate through all the modules/forms in a Scripter Project can check whether a module/form is loaded in memory or not and when all the modules/forms are unloaded from memory I can consider that the IDEEngine has completed its work?

Another way that I tried was by adding Application.Terminate here is the code:

But this is also not working as expected as the line Application.Terminate is never executed.



Use the suggestion with the script form class. That way you all forms created from script are descendant from your own form. You can then control when the forms are displayed, closed, destroyed and track when all of them are finished. Why do you want to call Application.Terminate? That would terminate your own Delphi application.

If you need close main application when script form is closed:

Define some metod: SetMainForm
In main application

procedure SetAsMainForm(aForm:TForm);
      P := @Application.Mainform;
      Pointer(P^) := aForm;
     except on E:Exception do

procedure TatMyFuncsLibrary.__SetMainForm(AMachine: TatVirtualMachine);
var ExStyle: Cardinal;
  with AMachine do

procedure TatMyFuncsLibrary.Init;
  With Scripter.DefineClass(TatMyFuncsLibrary) do
    Scripter.DefineMethod('SetMainForm',1,tkNone,nil,__SetMainForm, False, 0,'form: TForm');

In script:
MainForm := TForm2.Create(Application);

Now, if you close MainForm - it close application.

Hello Wagner,

Yes I know calling Application.Terminate will terminate my application. This is just for testing that I have put this code.

But the point is that the code below While loop is not getting executed. What is wrong with the code? Please point that out.


Hello Semenova,

Thanks for the code sample. I will check that out soon.

But actually I am not trying to close my application after the Main script form closes. I want a way to know as to when the last script form has unloaded so that I can execute the code that is necessary in my application.



MainForm variable never becomes nil.

I know that this is quite old topic, but reply because I searched the same issue.

I solved this using normal windows messages.

1) I declare procedure SendMessage to my scripter functions (this might allready be there, couldn't just find it) 
  AddMethod('SendMessage', 4,TatTypeKind.tkNone, nil, sendMessageProc);
and implemetation is
procedure TSkjScriptLibrary.sendMessageProc(amachine: Tatvirtualmachine);
  with amachine do
    SendMessage( getinputargasinteger(0),getinputargasinteger(1), getinputargasinteger(2),  getinputargasinteger(3) )

Then in formscripter I introduce constant wm_user and form TFormScripter (which is form activating the scripter) 
  IDEScripter.AddForm(formscripter, 'TFormscipter');
and add one method to it.
    procedure ScripterDone(var msg: TMessage); message wm_user+1;

And finally
in my actual script I add OnClose event
   SendMessage(formscripter.Handle, wm_user+1, 10,0);

Thank you for your contribution, Mika.