Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
Member Area
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Become a Member
-Why sign up!
-Chat Online!
-Indexes NEW!!
-Build your resume
-Find a job
-Post a job
-Resume Search
-Link to us
Visit Embarcadero
Embarcadero Community
How to manage a Single Instance of a Non-Modal Form Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
Delphi 2.x
User Rating
No Votes
# Votes
DSP, Administrator
Reference URL:
			Author: Dmitri Papichev

How to manage the application's non-modal forms properly - to make sure that only 
one instance of a form is present at any given time, like it is done automatically 
for modal forms?


When you have a modal form, you create, display and destroy it usually in a single 
uninterrupted sequence of code instructions, therefore it is easy to ensure that 
your form variable is equal to NIL after the form is expired, so you easily 
eliminate the risk of creating the same form twice or, even worse, attempting to 
access non-existing form when the only form's remains you actually have is the form 
variable with non-NIL value in it. 

The problem with non-modal forms is that you usually create and display them in one 
place, then do whatever you want with your application (and not only that form), 
and order them to destroy themselves when they are no longer needed at any time - 
you cannot say beforehand where and when that will happen. 
It is natural to close and free such a non-modal form from itself, but where to put 
clean-up instructions then? Without them, the application cannot know whether the 
form is alive - it relies merely on the form variable value (is it equal to NIL?) 
to determine if the form is still around. It is possible to introduce some 
application-level flags to keep track of the forms presence, but it is not an 
elegant solution. 

Fortunately, as almost always with Delphi, there is a clear way to solve the 

Suppose you have frmNonModal as a form variable of TfrmNonModal class. 

The procedure is simple: 

   1. Add the following OnDestroy event handler to the form: 

1   procedure TfrmNonModal.FormDestroy(Sender: TObject);
2   begin
3     frmNonModal := nil;
4     inherited;
5   end; {TfrmNonModal.FormDestroy}

Note that you cannot substitute frmNonModal with Self, though it seems to be the 
same from the first glance. The difference is that Self points to the object itself 
(and we don't want to nullify it prematurely), and frmNonModal is just an external 
(to the object) variable, which points to the object. By setting this variable to 
NIL we do not affect any internal functionality of the object, but rather just 
disconnect its link to the outer world. In our case this is exactly what we need, 
as we plan to check this variable when creating the form, as shown below.   

   2. Add the following OnClose event handler to the form: 
7   procedure TfrmNonModal.FormClose(Sender: TObject; var Action: TCloseAction);
8   begin
9     inherited;
10    Action := caFree;
11  end; {TfrmNonModal.FormClose}

This is needed to instruct our form to free itself when we close it. Note that by 
default Action is caHide, i.e. your form is just being closed (hidden), but not 
destroyed after calling TForm.Close. 
   3. Bring your form to life as follows, for example in the menu item's OnClick 
event handler on your main form (of TfrmMain class): 
13  procedure TfrmMain.itmNonModalFormClick(Sender: TObject);
14  begin
15    if Assigned(frmNonModal) then
16    begin
17      {if the form already exists, just bring it to the front}
18      frmNonModal.Show;
19      frmNonModal.WindowState := wsNormal;
20      frmNonModal.BringToFront;
21    end
22    else
23    begin
24      {create the form if it does not exist}
25      frmNonModal := TfrmNonModal.Create(Application);
26      try
27        {display as non-modal form}
28        frmNonModal.Show;
29      except
30        {clean up the form and form variable if unsuccessful}
31        FreeAndNil(frmNonModal);
32      end; {try}
33    end; {if}
34  end; {TfrmMain.itmNonModalFormClick}

That's it. Now your application always knows whether your non-modal form is present (created), and manages to allow not more than a single instance of such form at a time. 

Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10


Share this page
Download from Google

Copyright © Mendozi Enterprises LLC