Solved

How to check if a modal form exists?

Posted on 2004-10-27
233 Views
Last Modified: 2010-05-18
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-
0
Question by:wileyecoyote
    11 Comments
     
    LVL 6

    Expert Comment

    by: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;

    0
     

    Author Comment

    by:wileyecoyote
    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
     
    LVL 6

    Expert Comment

    by:vadim_ti
    1)may be it is autocreated form
    2)may be it crashes in onShowEvent
    0
     
    LVL 12

    Expert Comment

    by:esoftbg
    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
     

    Author Comment

    by:wileyecoyote
    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
     
    LVL 12

    Expert Comment

    by:esoftbg
    O.k. see you morning .... (Here is 02:04 am)
    0
     
    LVL 12

    Expert Comment

    by:esoftbg
    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
     
    LVL 12

    Expert Comment

    by:esoftbg
    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
     
    LVL 12

    Accepted Solution

    by:
    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
     

    Author Comment

    by:wileyecoyote
    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
     
    LVL 12

    Expert Comment

    by:esoftbg
    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

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone. Privacy Policy Terms of Use

    Featured Post

    Do You Know the 4 Main Threat Actor Types?

    Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

    Suggested Solutions

    Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
    Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
    This video Micro Tutorial is the second in a two-part series that shows how to create and use custom scanning profiles in Nuance's PaperPort 14.5 (http://www.experts-exchange.com/articles/17490/). But the ability to create custom scanning profiles a…
    Need more eyes on your posted question? Go ahead and follow the quick steps in this video to learn how to Request Attention to your question. *Log into your Experts Exchange account *Find the question you want to Request Attention for *Go to the e…

    875 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    11 Experts available now in Live!

    Get 1:1 Help Now