Link to home
Start Free TrialLog in
Avatar of wileyecoyote
wileyecoyote

asked on

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-
Avatar of vadim_ti
vadim_ti

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;

Avatar of wileyecoyote

ASKER

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?
1)may be it is autocreated form
2)may be it crashes in onShowEvent
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;
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.
O.k. see you morning .... (Here is 02:04 am)
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
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;
ASKER CERTIFIED SOLUTION
Avatar of esoftbg
esoftbg
Flag of Bulgaria image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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!
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