?
Solved

MDI Child prevent multiple instance

Posted on 2005-03-13
17
Medium Priority
?
347 Views
Last Modified: 2010-04-05
Hi,

I am developing a program using MDI, i want my application to display only 1 instance of a form.
prevent multiple instance of the same form


Best Regads
Mohamed Thooloon
0
Comment
Question by:thooloon
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
17 Comments
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 13532719
Look at the answer DarkCore_ gave me to similar question. I use his solution now:
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21156003.html
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 13532965
Hi,

We are using our own TForms, who inherit from the normal TForm, but with some extra functionality :
  - Public Property 'AssociatedMenuItem'
  - Virtual Create-method : CreateWithParams
  - Private Procedure : procedure CheckAssociatedMenuItem( Checked : Boolean );

From within our MDI-Form, when a menu-item is clicked to open a ChildForm, we make use of the 'CreatWithParams' instead of the normal 'Create'.
With thsi call you must provide the menu-item linked to open this form. This menu-item will then be checked before the form is showed. If the AssociatedMenuItem is already checked, then the form is nog created again, just showed.


Underneath you find a code snippet of the extentions we made :
If you extend a normal Form with this code (I hope I did'nt forget anything), and you then add it to Delphi's Repository, you can add new forms to your project who inheritd from this form.


unit Form_DBInput;

interface
...

type
  TfrmDBInput = class(TForm)
     ...
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    FAssociatedMenuItem     : TMenuItem;
    ...
    procedure CheckAssociatedMenuItem( Checked : Boolean );
  protected
    ...
  public
    { Public declarations }
    ...
    constructor CreateWithParams( AOwner : TComponent; AAssociatedComponent : TComponent); virtual;
    property AssociatedMenuItem: TMenuItem read FAssociatedMenuItem write FAssociatedMenuItem;
  end;

...


procedure TfrmDBInput.FormShow(Sender: TObject);
begin
  { Check the Associated Menu Item }
  CheckAssociatedMenuItem( True );
end;


procedure TfrmDBInput.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  { UnCheck the Associated Menu Item }
  CheckAssociatedMenuItem( False );
  Action := caFree;
end;


procedure TfrmDBInput.FormDestroy(Sender: TObject);
begin
  AssociatedMenuItem := Nil;
end;


constructor TfrmDBInput.CreateWithParams(AOwner, AAssociatedComponent: TComponent);
begin
  AssociatedMenuItem := Nil;
  if ( AAssociatedComponent is TMenuItem ) then
  begin
    AssociatedMenuItem := ( AAssociatedComponent as TMenuItem );
  end
  inherited Create( AOwner );
end;


procedure TfrmDBInput.CheckAssociatedMenuItem(Checked: Boolean);
begin
  if Assigned( FAssociatedMenuItem ) then
  begin
    FAssociatedMenuItem.Checked := Checked;
  end;
end;



From within your MDI-MainForm, you can place the following code in the OnClick-Menu from a Munu-Item :
  { If the menu-item is not checked, create the form , otherwise just show it. }
  if not mniMenuItem.Checked then
  begin
    frmYourInheritedForm := TfrmYourInheritedForm.CreateWithParams(Self, mniMenuItem);
  else
    frmYourInheritedForm .Show;



I hope to be of some help,

The Mayor.
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 13533213
Hi thooloon,

Since my previous post was too difficult to understand, I made you a new Form, that inherits from the normal TForm, but with the extra functionality to check/uncheck an Associated MenuItem.
This functionality should be used when the form is opened from the MDI-Form.
When a menu-item is clicked, you can provide this menu-item with the special Create-Method for this form.
It will then check the menu-item to be able to detect if it just needs to be showed or really created.

Just make a new, form, set the FormStyle to 'fsMDIChild', set Name to 'FrmBaseMDIChild'. Then save the form to disk with the name 'FORM_BASE_MDI_CHILD'.
At last, replace the code beneath with the code in your Form, and save it again.
Right click the form and choose 'Add To Repository'. You can then add this form to the Delphi-repository. This is to create new forms in your applications that inherit from this 'FrmBaseMDIChild'.


unit FORM_BASE_MDI_CHILD;

interface

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

type
  TFrmBaseMDIChild = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormShow(Sender: TObject);
  private
    FAssociatedMenuItem: TMenuItem;
    procedure CheckAssociatedMenuItem( Checked : Boolean );
    { Private declarations }
  public
    { Public declarations }
    constructor CreateWithParams( AOwner : TComponent; AAssociatedComponent : TComponent ); virtual;
    property AssociatedMenuItem: TMenuItem read FAssociatedMenuItem write FAssociatedMenuItem;
  end;

var
  FrmBaseMDIChild: TFrmBaseMDIChild;

implementation

{$R *.DFM}

{ TForm1 }

procedure TFrmBaseMDIChild.CheckAssociatedMenuItem(Checked: Boolean);
begin
  if Assigned( FAssociatedMenuItem ) then
  begin
    FAssociatedMenuItem.Checked := Checked;
  end;
end;

constructor TFrmBaseMDIChild.CreateWithParams( AOwner, AAssociatedComponent: TComponent );
begin
  AssociatedMenuItem := Nil;
  if ( AAssociatedComponent is TMenuItem ) then
    AssociatedMenuItem := ( AAssociatedComponent as TMenuItem );
  inherited Create( AOwner );
end;

procedure TFrmBaseMDIChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  { UnCheck the Associated Menu Item }
  CheckAssociatedMenuItem( False );
  Action := caFree;
end;

procedure TFrmBaseMDIChild.FormShow(Sender: TObject);
begin
  { Check the Associated Menu Item }
  CheckAssociatedMenuItem( True );
end;

end.







From you MDI-MainForm, you have to place the following code in the OnClick of the MenuItem from where you need to show the MDIChild-Form :

  if not YourMenuItem.Checked then
    frmNewForm := TfrmNewForm.CreateWithParams(Self, YourMenuItem)
  else
    frmNewForm .Show;



I hope this is a bit clearer now. If you have questions please ask them.

Best regards,

The Mayor.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 13

Expert Comment

by:BlackTigerX
ID: 13536686
just use a global variable, I
- created another unit (GlobalVars.pas),
- declared a MyMDIOpen:Boolean var
- include GlobalVars in your main form and in the MDIChild form
- then when you create your MDI child, you set it to True, when you close it, you set it to false

if not (MyMDIOpen) then
begin
  with MDIChildWindow.Create...
  MyMDIOpen:=True
end

...that simple
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 13542295
Hi Thooloon,

I made a little demo app to show you what my code is doing.
Is it possible to provide your email-address, so that I can send you the little application ?

Best regards,

The Mayor.
0
 
LVL 1

Author Comment

by:thooloon
ID: 13542342
Dear Mayor

PLease mail to my email address
thooloon@gmail.com

Best Regards
Thooloon
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 13543005
Hi thooloon,

I just sent you an email with the complete project in it.
Also the base-form is included.
Y ou can entirely use this form to add it tou your delphi repository.
From then on you can make MDI-Applications in wich the MDIChilds inherit from your base-form.

Best regards,

The Mayor.
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 13543017
This way of working (Object Oriented) has 1 great advantage :
All changes in your base-form is automatically applied to all the forms that inherit.
If e.g. you provided a company-logo on the base-form, and that logo needs to be changed, then you only have to do this in you base-form and just recompile all projects that make use of forms that inherit from your base-form.
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 13543058
Hm, looks like I cannot send you the mail ...
I got a delivery Failure Report from our Mail-system : illegal attachment.
Maybe it is because the attachment is a zip-file.

I will try it again from my webmail on.
Keep in track with you mail.

The Mayor.
0
 
LVL 1

Author Comment

by:thooloon
ID: 13553267
Dear Mayoor

I am stil waiting for your mail,

Best Regards
Mohamed Thooloon
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 13553650
oops,

I send it to you yesterday. Maybe there went something wrong again.
I will try it again.
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 13553665
I just checked my webmail, and indeed I got the same error again (illegal attachment).
I wilt save it to a rar-file instead.
I do it immediately.

Best regards,

The Mayor.
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 13553684
Just tried it again with a Rar-File this time.
I'll keep you informed about errors I get.
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 13554281
Since I got an error on the rar-file too, I tried to rename the rar-file to a .txt extention.
I sent the file again and now I don't get any errors.

Can you check if this email has been sent to you ?
So you'll have to rename the attachment to a rar-extention, and then extract it.
Please let me know if you have any problems.

Best regards,
0
 
LVL 1

Author Comment

by:thooloon
ID: 13562561
Dear Mayor
I reveived your attachment there was 3 files, 2 of them is a picture file and other file i have renamed to .rar extention and found that the file is corrupt, the size of the RAR file is only 6 bytes. please send the file again or if you use MSN Messanger you can add me (thooloon@hotmail.com) and can  send  the file directly

Best Regards
Thooloon
0
 
LVL 6

Accepted Solution

by:
wimmeyvaert earned 150 total points
ID: 13562754
Hi Thooloon,

I'm at work for the moment, and there I can't make use of the MSN Messenger.

Maybe I do another attempt to send you the email from my webmail on and with the txt-attachment.

The reason of the problem may be the fact that we are using Lotus Notes as our Email-Client.

I'll try it right away.
0
 
LVL 6

Expert Comment

by:wimmeyvaert
ID: 13572325
Thanks for the points !
Glad I was able to help you with your problem.

Best regards,

The Mayor.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
Suggested Courses

764 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