Apparently, when your application is a FireMonkey application.
If you have any applications which contain code similar to this:
Application.CreateForm(TMyForm, MyForm); MyForm.InitialProperty := SomeInitialValue; Application.Run;
Then you will need to rethink how you initialise those forms in the FireMonkey framework because CreateForm() commits what I consider to be a cardinal sin (in the software development world at least):
It doesn’t do what it says it does!
In a VCL application, when you call CreateForm( class, ref ) an instance of class is created and a reference to it placed in ref, which you can then use to initialise or otherwise reference the instantiated form.
Try and do this in a FireMonkey application and it blows up in your face.
In a FireMonkey application when you call CreateForm no form is created at all!
Instead, the Application object simply takes a note of the class and the address of the reference variable provided in an internal array. No instance is created and the reference is not assigned until you call Application.Run (or alternatively the new Application.RealCreateForms).
This all has a really, really bad smell about it and frankly beggars belief.
Why go to the trouble of preserving the appearance of the behaviour of one framework in another if you are not going to preserve the behaviour itself ?
Or put more simply – if FireMonkey works differently then for crying out loud make it look different in those areas where those differences are important!
In this case, CreateForm() should have been replaced by something which was clearer in conveying the intended and expected behaviour (or rather, non-behaviour).
I suggest something along the lines of:
procedure TApplication.AddForm(const aFormClass: TComponentClass; const aReferenceVar: PObject);
Which would then have been called like this:
You would not then have needed the very smelly “RealCreateForms” method (any method which suggests that it is really doing something in place of some other thing which gave the impression of having done something but really didn’t is strongly suggestive to me of code that needs some serious re-thinking).
Or rather, you would have had a method you could call more simply and honestly… CreateForms.
i.e. two methods which both do what they say, rather than the current situation of one method which doesn’t do what it says and another method whose name contains an apology for the poor behaviour of it’s related sibling.
Two things would make this better than what we actually have imho:
- It is different from what we had (and still have) in the VCL, which is good and proper because it is – after all – doing something quite different too!
- The parameter list is more clearly expressing the behaviour of the method. It does not modify the reference variable provided and asked for, it is asking for a pointer to a reference variable.
It is far more readily apparent that whatever is going to happen to that reference is not going to occur now but at some later point.