Link to home
Start Free TrialLog in
Avatar of pjelias
pjelias

asked on

Check if a Form is Open ?

Hi,

hopefully this is an easy one.

How do I check if a Form is open within Delphi 5 ?

I have a main menu, which opens several forms, but if I click any menu option more than once, multiple instances of the form open. The app is NOT an MDI app.

I have tried searching Experts-Exchange, but am unable to view past the 1st page of results.


Thanks
pjelias
Avatar of edey
edey

well, you could try looking for it with the findWindow api, though I would think the answer would be to try & never instantiate it more then once.  When show it you could try something like:

if form1 = nil then
 form1 := TForm1.create(some_owner);
form1.show;

GL
Mike
This is how I do it and it basically is the same as edey's comment just different syntax

if not Assigined(form1) then
     form1 := TForm1.create(nil);

or

if not Assigined(form1) then
     form1 := TForm1.create(Owner_of_Form);
Avatar of pjelias

ASKER

Have tried both, neither works. Form will not open at all.
Do I have to initialise form1 first (vwForm in my case).

My code below.

var sysUser: String;
    vwForm: TForm;
    rwAccess : String;
begin
  sysUser:=LowerCase(SysInfo.CurrentUser);
  case menuBar.SelectedIndex of
  0:begin
     rwAccess:=AccessType(sysUser,'BUILDUP');

     if rwAccess='RW' then begin
        if not Assigned(vwForm) then begin
          vwForm:=TFormBuildUp.Create(Self,[arWrite]);
          vwForm.Show;
        end;
     end;
  ... other code below.

When I track the vwForm variable I get the following

vwForm: ([csInheritable], True, False, $5C7DA4, [fsCreatedMDIChild])

All Other code works until I add the code re: Checking if Form is opened.

Any ideas ?
ASKER CERTIFIED SOLUTION
Avatar of CrazyOne
CrazyOne
Flag of United States of America 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
I got to hit the sack so I will check back on this thread after I get some sleep.
Avatar of kretzschmar
you could iterate through the mainforms-childforms,
and compare its classname like

function mainform.formexists : TForm;
begin
  result := nil;
  for i := 0 to mdichildcount - 1 do
    if mdichilds[i] is TFormBuildUp then
      result := forms[i];
end;

and you could it call like

aform := formexists;
if aform = nil then
  with TFormBuildUp.Create(self) do
     show
else
  aform.show;

(just from head, syntax errors possible)

meikl ;-)
oh, no mdichilds,
then use
formcount instead of mdichildcount,
forms[] instead of mdichilds[]

meikl ;-)
Avatar of pjelias

ASKER

CrazyOne,

How Obvious ?

I need to get away from my pc every now and then, and relook at the code after a while.

The code I had worked, which is similar to Kretzschmar's code, but as I stated, it is not an MDI App.

The problem was that the Form was included in the Apps Autocreate method, which I moved, and now works OK, as CrazyOne suggested.


Thanks to all.
Hi,

Well Meikl, will this also work with a non MDI application ?

Pjelias,

Are you using the sample form I posted in the other question ? If so, add the following line to the template form :

unit ARSample;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  { The different types of Access Right }
  TAccessRight = ( arRead, arWrite, arAdd, arRemove );
  { Will be used to hold any combination of TAccessRight }
  TAccessRights = set of TAccessRight;

  TForm1 = class(TForm)
    btnEdit: TButton;
    btnPost: TButton;
    btnCancel: TButton;
    btnDelete: TButton;
    btnDuplicate: TButton;
    btnInsert: TButton;
    btnButton1: TButton;
    procedure btnButton1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    FAccessRights: TAccessRights;
    procedure SetAccessRights(const Value: TAccessRights);
    { Private declarations }
  protected
    procedure DisableButtons;
  public
    { Public declarations }
    Constructor Create( AOwner : TComponent; ARights : TAccessRights ); reintroduce; overload;
    property AccessRights : TAccessRights read FAccessRights write SetAccessRights;
  end;

<B>  TAccessRightsFormClass = Class of TForm1;</B>

Where you should replace TForm1 with the Class of the form you are using.  Then in the main form put the unit in the interface uses clause ( the topmost one ) and remove it from the implementation uses clause.

Next create a new method in your main form it should look like this :

unit MainForm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, arSample;

type
  TForm2 = class(TForm)
    btnButton1: TButton;
    procedure btnButton1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure ShowOrCreateForm( aFormClass : TAccessRightsFormClass; AccessRights : TAccessRights );
  end;

var
  Form2: TForm2;

implementation

{$R *.DFM}

procedure TForm2.btnButton1Click(Sender: TObject);
begin
  ShowOrCreateForm( TForm1, [ arRead, arWrite ] );
end;

{*****************************************************************************
  Name           : TForm2.ShowOrCreateForm
  Author         : Lesage Stefaan
  Arguments      : aFormClass   - The class of the form you are looking for
                   AccessRights - The Access rights which should be used to
                                  create a new form if it isn't found.
  Return Values  : None
  Exceptions     : None
  Description    : This method will loop over all forms in the application to
                   find a form of the given class.  If such a form is found, it
                   will be shown.  If none was found, one will be created with
                   the given access rights and shown.
  History        :

  Date         By                   Description
  ----         --                   -----------
  03/07/2001   Lesage Stefaan       Initial creation of the Procedure.
 *****************************************************************************}

procedure TForm2.ShowOrCreateForm(aFormClass: TAccessRightsFormClass; AccessRights : TAccessRights);
var
  lcv   : Integer;
  Found : Boolean;
  aForm : TForm;
begin
  { Initialise the Variable }
  Found := False;
  aForm := Nil;

  { Loop over all forms of the application }
  for lcv := 0 to Pred( screen.FormCount ) do
  begin
    { Check if the form is of the given class }
    if Screen.Forms[ lcv ] is aFormClass then
    begin
      { If so Show it }
      aForm := Screen.Forms[ lcv ];
      Found := True;
    end;
  end;

  { If a form of our formclass was not found, create it }
  if ( Not Found ) then
  begin
    aForm := aFormClass.Create( Self, AccessRights );
  end;

  if ( Assigned ( aForm ) ) then
  begin
    aForm.Show;
  end;
end;

end.

As you see I added a button to my form which calls the method I created.  You should simply pass the class of the form you are looking for and the access rights which should be used to create a new form if none was found.

Best regards,


Stefaan

Just a few seconds too late ;-)
Avatar of pjelias

ASKER

Stefaan,

just got a message re: the code you posted, took a look, it looks a bit cleaner than what I have done.

Question - if I was to open say 4-5 Forms at the same time (may be possible), using the above method, would it matter If the same Form variable was used, while Forms remained open - aForm.


pjelias
Hi,

Well the method I have given doesn't use any form variable at all.  It will check if a given Form Class is found.  The only drawback is that you won't be able to have two instances of a TForm1, but I thought that was exactly what you wanted to have.

Best regards,


Stefaan
It's really easy to steal questions  :o)

Sorry for the previous comments...
Steal questions ? What do you mean by that ?

Best regards,


Stefaan
Buying a question without paying. I'm not going to make a habit of it, don't worry   :o)
And, did you find a good answer ?
On the question "Can I steal a question?": Yes!
On the question "Check if a Form is Open?": I didn't look  :o)