Forms management tip

(portuguese)

From my point of view, one thing that is really missing for Delphi/Lazarus is a better application’s form management. Two problems: an independent public variable is used to control an instance, and the ‘please place everything within the form’ approach. The first one requires the programmer to either create the form at the start of the application and not destroy it anymore, or it requires the programmer to create the forms and keep track of object destruction insuring that no variable points to a destroyed object. The second, among other problems, requires that the first one works perfectly so that the communication between forms can work.

When using the second approach there is not much work to be done. You either have to live with this limitation or write a new framework to go around it. Now, in order to maintain an up-to-date public variable, the programmer can benefit from the small tricks I will be describing here.

My suggestion to maintain an up-to-date public variable is to give it to a class method. This method takes care to create the form when this is necessary, and to update the variable when the form is destroyed. For this, implement the following method in the forms base class, in other words, the one from which all the forms will inherit:

  TBaseForm = class(TForm)
  public
    class procedure Execute(var AForm; AModal: Boolean = False);
  end;

And implement the methods like this:

class procedure TBaseForm.Execute(var AForm; AModal: Boolean);
var
  VIndex: Integer;
begin
  if not Assigned(_Forms) then
  begin
    _Forms := TStringList.Create;
    _Forms.Sorted := True;
  end;
  if not _Forms.Find(ClassName, VIndex) then
    VIndex := _Forms.Add(ClassName);
  if TForm(AForm) = nil then
    Application.CreateForm(Self, AForm);
  _Forms.Objects[VIndex] := TObject(@AForm);
  if AModal then
    TForm(AForm).ShowModal
  else
    TForm(AForm).Show;
end;

and make the public variable references nil the moment the form is destroyed:

destructor TBaseForm.Destroy;
type
  PForm = ^TForm;
var
  VIndex: Integer;
begin
  if Assigned(_Forms) and _Forms.Find(ClassName, VIndex) and
   (_Forms.Objects[VIndex] <> nil) then
  begin
    PForm(_Forms.Objects[VIndex])^ := nil;
    _Forms.Objects[VIndex] := nil;
  end;
  inherited;
end;

Finally, the StringList needs to be declared, and destroyed when the application is closed:

implementation

var
  _Forms: TStringList = nil;

...

initialization

finalization
  _Forms.Free;

end.

Done. The only thing needed is to create new forms that descend from this one and call TYourForm.Execute(YourForm). When the form is destroyed, the public variable will be assigned to nil.

11 thoughts on “Forms management tip”

  1. Great! Thank you very much!
    I always wanted to write in my site something like that. Can I take part of your post to my blog?
    Of course, I will add backlink?

    Sincerely, Timur I. Alhimenkov

  2. Unlixnist, thanks for the tip. Within few months I will change the theme, probably the source of the problem. I will also test the new one with Opera as well.

  3. Hello!
    Very Interesting post! Thank you for such interesting resource!
    PS: Sorry for my bad english, I’v just started to learn this language 😉
    See you!
    Your, Raiul Baztepo

  4. Hi !!!! 😉
    I am Piter Kokoniz. oOnly want to tell, that I like your blog very much!
    And want to ask you: will you continue to post in this blog in future?
    Sorry for my bad english:)
    Thank you!
    Piter Kokoniz, from Latvia

Comments are closed.