Boy, do I feel stupid!
As David pointed out in the comments to take one of this subject, there is a much easier way to get all the instantiated forms at run time:
var CustomForm: TCustomForm; idx: Integer; begin for idx := 0 to Screen.CustomFormCount - 1 do begin CustomForm := Screen.CustomForms[idx]; Memo1.Lines.Add(Format('%s (%s)', [CustomForm.Name, CustomForm.ClassName])); end; end;
Forgot all about Screen.CustomForms
existence. And it’s been there since at least D5… My only excuse is that I haven’t done much UI programming in the last, what, seven years.
There is also Screen.Forms
, but that only lists TForm
descendants. While Screen.CustomForms
lists all TCustomForm descendants including for example property pages.
Caveat
There is a caveat in using either. According to the docs, the order in which instantiated forms appear in both lists is affected by the Z-order of all forms. So while you are iterating over one of these lists, you shouldn’t do anything that might affect the Z-order, such as creating and/or activating another form in your application, as that would change the contents of the list!
If you need to do anything like that, then your best bet is still to use Application.Components
like I showed in take one.
Leave a Reply