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
Solved

How do I free a non modal window in a MDI App?

Posted on 2002-05-31
15
462 Views
Last Modified: 2010-04-04
We have a MDI Application that needs a non modal window which can be left open when the user closes the application, how do I get the application to free this window automatically on closure?

We are using packages and the application doesn't know about the window.
0
Comment
Question by:chrisgreening
  • 3
  • 3
  • 3
  • +6
15 Comments
 
LVL 3

Expert Comment

by:tongalite
ID: 7046566
Hi,
you could try this:
Sst up the closequery event of your mainform.
Good luck
T.

*******************************

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);

var
  h: HWND;
begin
  h := FindWindow(nil, 'your_non-modalform_caption');
  if h <> 0 then PostMessage(h, WM_CLOSE, 0, 0);
end;
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 7046713
Provide a onClose-event-procedure in your childform like

procedure TChildForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

meikl ;-)
0
 

Author Comment

by:chrisgreening
ID: 7047142
tongalite,

thanks for that but still no joy, still getting Access Violations any other suggestions and we do have an onClose Event on the childform kretzschmar
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 3

Expert Comment

by:tongalite
ID: 7047168
Hi cg,

when you say...
" We are using packages and the application doesn't know about the window"
Do you mean it's an external window (in a dll perhaps)?
Can you be a bit more specific :)
T.
0
 

Author Comment

by:chrisgreening
ID: 7047283
soz it is a form in one of our packages(bpl)
0
 

Author Comment

by:chrisgreening
ID: 7047297
LOMSlaine may add to this post as he works with me and he is the developer having this problem.
0
 

Expert Comment

by:LOMSlaine
ID: 7047308
We have a MDI Application, on this application we have a window that is popped up, this is a NON-MDI form and is NON-Modal. This form is created from an object in a Package, with the application being the owner (this was changed from the object it was created in an attempt
to resolve this issue), The problem begin is that the Application is throwing errors when it trys to unload the package that the form is held.

In the forms close event i have action := CaFree, the forms destructor is called and seems to go through ok. i just get 4 run time errors and an error saying that all forms couldn't be shut down.

I will be happy to answer any questions, if anyone could help i would be really grateful
0
 
LVL 1

Expert Comment

by:thegroup
ID: 7047311
If a window in your application remains open then your application remains open. You could close (hide) the main window but this doesn't close your application.

When you close (destroy) your main form your application closes, release all bpl in use and this closes all child windows that where created in there.

In your case the non modal window close happens automatically on application close. You not need to do a thing.
0
 

Expert Comment

by:LOMSlaine
ID: 7047360
Well, we are getting access violations when the package that contains the form is unloaded.
0
 
LVL 4

Expert Comment

by:nestorua
ID: 7048754
HI,
Could you tell me the following:
1.Is your Form created from the package is a ChildForm for your MDI Form.
2.How do you create that form (I mean post the simplest code
of creation your form which generates errors).
Sincerely,
Nestorua.
0
 
LVL 1

Expert Comment

by:DavidLeeding
ID: 7052537
This might be a longshot...but here goes...I have come across a similar problem to yours: an application which opened a non-modal window in an MDI context would always generate errors on closing the form. The only way we could find to resolve it was to set the form variable to nil, eg:

    winStudents := nil;

where winStudents is a variable in the main form unit created using something like:

  winStudents := TfrmStudents.Create(Application);
 
The key bit of code sits in the OnAppMessage of the main form, and is triggered in reponse to a message sent by the problematic form when it is closed, eg:

// In child form:
// -------------
procedure TfrmStudents.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // Send message to main form...

  PostMessage(frmMain.Handle,
              WM_USER + MSG_CLOSESTUDENTS, 0, 0);
  Action := caFree;

  //NB: MSG_CLOSESTUDENTS is (obviously) a constant with
  //an arbitrary value defined for the whole project
end;


//In main form:
// -----------
procedure TfrmMain.FormCreate(Sender: TObject);
begin
  Application.OnMessage := OnAppMessage;

  //.....etc
end;

procedure TfrmMain.OnAppMessage(var Msg : TMsg; var Handled : Boolean);
begin
  if Msg.Message = (WM_USER + MSG_CLOSESTUDENTS) then
  begin
    winStudents := nil;
    Handled := TRUE;
  end;
end;

procedure TfrmMain.mnuStudentsClick(Sender: TObject);
begin
  // Create/Open the students window
  // winStudents is a global variable of TfrmStudents

  winStudents := TfrmStudents.Create(Application);
  //... show window, disable menu item, yada yada
end;


Hope this helps!

0
 

Expert Comment

by:LOMSlaine
ID: 7056628
problem with this is for every window created like this we a variable will have to be held on the main application, this isn't very practical as new screens are added on a weekly basis, with this in mind it would be hard to maintain the application with all the screens
0
 
LVL 3

Expert Comment

by:tongalite
ID: 7057330
Hi again cg.

I was looking at another forum and came across this question which is similar in nature to your problem. Not a solution but you might be interested. Here it is:
tongalite.
********************


I get an error when closing an MDI form using:
close;
but it works when I click the form close button (the cross in the right corner).
Where is the difference?
 

I get this..... *address violation at... read of address...etc*
It has something to do with the way this close works. There is a close on the children and on the main form. If I close the children first it works now !?
The failure just happens if I try to use this in the child form:

PROCEDURE TChild.Exit1Click(Sender: TObject);
VAR Action: TCloseAction  ;
BEGIN
   Child.Close;
   Action := caFree;
END;

Close alone just close the child form. Procedure CloseAll;Close; does not close the main form as well.
At the moment I close the childs from the childs menu and the main formcontains the exit button.
However I can close everyting at once via the forms right/top exit button!??
 
************************  
 
REPLY:
When the form executes this method it is already in the process of being closed.
If the object 'Child' refers to the instance of the form you are trying to close then I would expect an access violation. This would have the effect of sending another windows WM_CLOSE message to the form that you have just destroyed.
I suspect the line Child.Close should be removed as per code sample below.

PROCEDURE TChild.Exit1Click(Sender: TObject);
VAR Action: TCloseAction  ;
BEGIN
//   Child.Close;
   Action := caFree;
END;

To be more specific, you assigned the mainform as the "Owner" of the child form, by sending it as the parameter to the Create method. This is very important and is commonly done. This is telling the mainform to call close when it is closed.
I generally don't do this with the Children of a form. I usually send Nil to the Create... This means that I need to close the Children myself, but I already know that there is an array of the Children anyway.
If you are telling it to automatically close it when the main form is closed, then you cannot allow the user to close any of the children (and instead hide it) and that makes no sense.
So, do not take out the close in the main form's close handler.... instead call the child's constructor with Nil as the parameter.
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9010394
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

PAQ with No Refund

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
0
 
LVL 6

Accepted Solution

by:
Mindphaser earned 0 total points
ID: 9101756
Force accepted

** Mindphaser - Community Support Moderator **
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

808 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