Forms Delphi

Title: Robust Form Initialization
Question: When you need to use a form in you Delphi program, it is important how you control the creation and initialization, if you want the code to be completely failsafe. This article describes how this can be accomplished with simple means and describes the problems you can get into, if you do not consider this.
Answer:
RAD Approach
In Delphi a form has a FormCreate and a FormShow event, these two are where you normally initialize the form or other vice you initialize it in the code wrapping the displaying of the form, e.g. like this:
var
f: TForm;
FormNotCancelled: Boolean;
begin
f := TForm.Create(nil);
try
f.Initialize;
FormNotCancelled := f.ShowModal = mrOk;
if FormNotCancelled then
ShowMessage(Hello);
finally
f.Free;
end;
This is a nice way to do it and errors are handled correctly.
If there is an error (exception) during Initialize or FormShow the form will not be displayed and instead an exception takes proper care of everything.
If however circumstances is that you do not want an external call to an Initialize method, but you want to use FormCreate or FormShow instead (to e.g. create controls), you need to be careful. Lets imagine you do not have a call to an Initialize in the code from before and you move the initializing code to the FormCreate event instead.
If code in the FormCreate event fails, an exception is thrown, but the expected result is not what then actually happens. This has to do with the Windows message system.
The remaining part of the FormCreate is skipped, but then the FormShow is invoked!
So if you want to use FormCreate for some initialization, you actually need to check in the FormShow, that it completed in the FormCreate.
E.g. use a flag like FormCreatedCompletedSuccessfully.
You actually need to check it in all code until the form is successfully shown on the screen. This is error prone, so the approach with an Initialize method is always recommended.
Sometimes you want the form to display and then make some time consuming initialization.
You can use the Initialize method for this. If you want 2 steps you would of cause need both an Initialize and RemainingInitialize methods for example. The RemainingInitialize you could call in the FormShow event.
If something goes wrong there, there IS a way to handle it. Close the form and raise an exception.
Events Beginning to Fire to Early
When a control has been created there is a good chance it can start generating events.
But that might lead to other errors, if the form failed during its initialization or some parts still need to initialize!
It is not safe to begin to execute code in the events before the form has been completely initialized and displayed. Except if you really know what is going on. Often you just disregard this problem and fix it if it causes errors; I just wanted to let you know the potential is there for bugs.
To prevent unwanted events you can use a flag like:
FormShowCompletedSuccessfully
You set this to True right before you exit FormShow and in all dangerous events you start with this code:
If not FormShowCompletedSuccessfully then
Exit;
For this and other reasons you should be much alerted when using events. As the application grows you will get more and more unexpected situations if you use a lot of events. Sometimes it is fine, other times it gets a mess to debug.
Some controls can fire after the form has been closed
You can then set FormShowCompletedSuccessfully to False in the beginning of FormClose to prevent this.
Hope this article makes sense and allows you to write more robust code. The techniques were applied in a commercial application named SQLMerger (www.blibler.com/SQLMerger - it is a tool for merging database data contents)