How to check if a modal form exists?

Hi,

I am trying to write a centralized (in a seperate unit) procedure that manages the creation, display and release of forms. The slimmed down version of my procedure looks roughtly like this:

procedure OpenAForm(Sender: TObject);
var
  f:TForm;
begin
  // check if frmMain exists
  if frmMain <> nil then
  begin
    if Sender = frmMain.mnuAbout then f := TfrmAbout.Create(frmMain);
    if Sender = frmMain.mnuProgramSettings then f := TfrmProgramSettings.Create(frmMain);
    if Sender = frmMain.mnuFSAdvancedSetup then f:= TfrmFSAdvancedSetup.Create(frmMain);
  end;

  // check if frmFSAdvancedSetup exists
  if frmFSAdvancedSetup <> nil then
  begin
    if Sender = frmFSAdvancedSetup.cmdManagef := TfrmFSManagement.Create(frmFSAdvancedSetup);
  end;

  try
    f.ShowModal;
  finally
    f.Release;
  end;
end;


The way the forms are shown on screen is as follows: frmMain displays modal form frmFSAdvancedSetup, which in turn displays a modal form frmFSManagement. Checking the existance of the main form goes fine, but even if frmFSAdvancedSetup is on screen, it returns nil, thereby crashing my app with an Access Violation.

So, how exactly can I make sure that modal forms are detected as being onscreen. This procedure looked fine in theory, but reality turned out a bit less succesful. Any help appreciated.

-edit: slimmed the code down a bit too much, corrected-
wileyecoyoteAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
esoftbgConnect With a Mentor Commented:
Never say that something is the best. (It could be improved and then it becomest better from the best one .... ha, ha, ha):

procedure  ShowModalfrmFSAdvancedSetup;
var
  N:      Integer;
  I:      Integer;
begin
  N := -1;
  for I := 0 to (Screen.FormCount-1) do
    if (Screen.Forms[I] is TfrmFSAdvancedSetup) then
      N := I;
  if (N >= 0) then
  try
    Screen.Forms[N].ShowModal
  finally
    Screen.Forms[N].Release;
    Screen.Forms[N] := nil;
  end
  else
  try
    frmFSAdvancedSetup := TfrmFSAdvancedSetup.Create(nil);
    frmFSAdvancedSetup.ShowModal;
  finally
    frmFSAdvancedSetup.Release;
    frmFSAdvancedSetup := nil;
  end;
end;
0
 
vadim_tiCommented:
function ShowForm(FormClass: TFormClass):Integer;
var
  Reference: TForm;
begin
  result := mrCancel;
  Reference := FormClass.Create(nil);
  if Assigned(Reference) then begin
    try
      Reference.ShowModal;
      result :=  Reference.ModalResult;
    finally
      Reference.Release;
    end
  end
end;

0
 
wileyecoyoteAuthor Commented:
Hmmm, it still crashes when I'm trying to display that second modal form (frmFSManagement). Again, it halts the program with a Access Violation. To be precise, it crashes on the Reference.ShowModal line. Any idea what might be causing it?
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
vadim_tiCommented:
1)may be it is autocreated form
2)may be it crashes in onShowEvent
0
 
esoftbgCommented:
procedure  ShowModalfrmFSAdvancedSetup;
var
  N:      Integer;
  I:      Integer;
begin
  N := 0;
  for I := 0 to (Screen.FormCount-1) do
    if (Screen.Forms[I] is TfrmFSAdvancedSetup) then
      N := I;
  try
    if (N >= 0) then
      Screen.Forms[N].ShowModal
    else
    begin
      frmFSAdvancedSetup := TfrmFSAdvancedSetup.Create(nil);
      frmFSAdvancedSetup.ShowModal;
    end;
  finally
    frmFSAdvancedSetup.Release;
    frmFSAdvancedSetup := nil;
  end;
end;
0
 
wileyecoyoteAuthor Commented:
Close, but there is still a bug in here somewhere. The app gets within the If statement right to the ShowModal line, where it shouldn't. I'll take a look at it in the morning (it's 1AM now here). Focus seems to be getting lost now. See you again in the morningn.
0
 
esoftbgCommented:
O.k. see you morning .... (Here is 02:04 am)
0
 
esoftbgCommented:
Oooops !
procedure  ShowModalfrmFSAdvancedSetup;
var
  N:      Integer;
  I:      Integer;
begin
  N := -1; // this was wrong above
  for I := 0 to (Screen.FormCount-1) do
    if (Screen.Forms[I] is TfrmFSAdvancedSetup) then
      N := I;
  try
    if (N >= 0) then
      Screen.Forms[N].ShowModal
    else
    begin
      frmFSAdvancedSetup := TfrmFSAdvancedSetup.Create(nil);
      frmFSAdvancedSetup.ShowModal;
    end;
  finally
    frmFSAdvancedSetup.Release;
    frmFSAdvancedSetup := nil;
  end;
end
0
 
esoftbgCommented:
This should be the best:

procedure  ShowModalfrmFSAdvancedSetup;
var
  N:      Integer;
  I:      Integer;
begin
  N := -1; // this was wrong above
  for I := 0 to (Screen.FormCount-1) do
    if (Screen.Forms[I] is TfrmFSAdvancedSetup) then
      N := I;
  try
    if (N >= 0) then
      Screen.Forms[N].ShowModal
    else
    begin
      frmFSAdvancedSetup := TfrmFSAdvancedSetup.Create(nil);
      frmFSAdvancedSetup.ShowModal;
    end;
  finally
    if (N >= 0) then
    begin
      Screen.Forms[N].Release;
      Screen.Forms[N] := nil;
    end
    else
    begin
      frmFSAdvancedSetup.Release;
      frmFSAdvancedSetup := nil;
    end;
  end;
end;
0
 
wileyecoyoteAuthor Commented:
Well, you can't assign nil to a Screen.Forms[N] property, but that's okay. I'll rebuild the function anyway so it takes not only frmFSAdvancedSetup, but other forms as well. I'll fix that one in the process.

Thanks for the help!
0
 
esoftbgCommented:
Hi wileyecoyote,
sorry about     Screen.Forms[N] := nil;
it was 02:20am EEST and I did a couple of mistakes ....
excuse me, i'm glad that you solved all !
Best regards,
emil
0
All Courses

From novice to tech pro — start learning today.