How to know when the IDEEngine has completed work?

Hello,

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?

Regards,

Yogesh

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?

Regards,

Yogesh



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:

Form1.Show;

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.

Regards,

Yogesh

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);
var
   P:Pointer;
begin
   try
      P := @Application.Mainform;
      Pointer(P^) := aForm;
     except on E:Exception do
       begin
           ErrMess(E.Message);
       end;
   end;
end;

procedure TatMyFuncsLibrary.__SetMainForm(AMachine: TatVirtualMachine);
var ExStyle: Cardinal;
begin
  with AMachine do
    begin
         SetAsMainForm(TForm(VarToObject(GetInputArg(0))));
    end;
end;


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

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

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.

Regards,

Yogesh
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.

Regards,

Yogesh

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);
begin
  with amachine do
    SendMessage( getinputargasinteger(0),getinputargasinteger(1), getinputargasinteger(2),  getinputargasinteger(3) )
end;

Then in formscripter I introduce constant wm_user and form TFormScripter (which is form activating the scripter) 
  IDEScripter.AddForm(formscripter, 'TFormscipter');
  IDEScripter.AddConstant('wm_user',WM_USER);
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.