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