[Lazarus] A change in LCL require your TCustomForm descendants to have a resource or to use a CreateNew constructor

Paul Ishenin ip at kmiac.ru
Wed Feb 2 03:25:31 CET 2011


Hello, Lazarus mailing list.

I've changed the behavior of TCustomForm.Create constructor. Now it 
raises an exception if your TCustomForm descendant has no resource.

1. Why the change is needed.

Historically TCustomForm has 2 constructors: Create() - for creating 
forms from resources and CreateNew() - for resourceless forms. When IDE 
creates a new form it creates a new unit (.pas file) and a new resource 
(.lfm file). IDE also adds {$R *.lfm} directive into the form unit file 
to attach the form resource into the executable. During the runtime 
TCustomForm.Create searches for resource and construct itself based on 
information from that resource. But what can happen if it can't find an 
appopriate resource? You will see an empty form. I think most of you 
will spend plenty of time trying to understand why do you see an empty 
form if you or someone else accidentally remove the {$R *.lfm} 
directive. So absence of the form resource is an exceptional situation 
and LCL must report an exception. LCL already report an exception if you 
have no resource for TFrame and TDataModule descendants.

On the other hand there are some situations when you want to construct a 
form in code without any resources. How to be in this case? You must use 
CreateNew() constructor - the difference between Create and CreateNew 
only in resource search. Moreover Create constructor also calls 
CreateNew inside.

2. How this change can affect your applications.

This change is applied only for new projects created by the Lazarus IDE. 
It does not affect your old projects.

3. Should you change anything in your application.

Yes, please do. If you are using Create() constructor to construct your 
resourceless forms - you are doing a mistake. Please replace it with 
CreateNew(). This will also speedup your form construction because no 
resource will be searched and no resource will be accidentally loaded. 
To simplify the search of accidental Create() constructor calls set 
"RequireDerivedFormResource" variable to True and test how your 
application works. If you see no exceptions - then you are doing things 
right.

4. How to change the behavior back.

The behavior is controlled by a global variable 
*RequireDerivedFormResource* which is set to True for all new 
applications created by the IDE and is set to False by default. If you 
for some reason want the old behavior just remove 
"RequireDerivedFormResource := True" line from .lpr file of your new 
application.

--
Best regards,
Paul Ishenin.





More information about the Lazarus mailing list