I have a multi-threaded application with many forms, but I need to instantiate some classes and call some initialization elements before creating the forms. Of course, I have to execute the appropriate exit code.
Here is a simplified .dpr file:
begin // .dpr project file LoadDlls; try Config := TConfig.Create; try Application.Initialize; Application.Title := 'Foo'; Application.CreateForm(TMainForm, MainForm); Application.CreateForm(TOtherForm, OtherForm); //...other forms... Application.Run; finally Config.Free; end; finally UnloadDlls; end; end;
The problem is that the code inside the finally blocks will execute before the OnDestroy / destructor my forms. This becomes clear by looking at the finalization section of the Form block:
finalization if Application <> nil then DoneApplication;
And DoneApplication calls Application.DestroyComponents , which effectively frees all Application owned Forms.
So, forms created using Application.CreateForm will be destroyed after any code inside the main begin..end block.
I want all forms to be destroyed after Application.Run so that their OnDestroy event handlers can see the Config object and the external functions defined in my DLLs. The same if an exception occurs. But I also want to have standard application exception handling if Config.Free or UnlodDlls raise (the application should still exist).
Note that:
- I would prefer not to use the
finalization block (is this possible in .dpr?) To clear the code and debug the code; - Currently, I prefer not to change too much code (for example, dynamically create forms)
I think the easiest solution is to explicitly call Application.DestroyComponents after Application.Run . Do you think there are any flaws? Is there a more elegant solution?
thanks
source share