Board index » delphi » MDI App. - Problem closing children

MDI App. - Problem closing children

Hi everyone,

I'm working on a MDI app. I made a child form which I use as a template (SuperClass) for all of my MDI children. On the FormClose event of that template, I added "Action := caFree;" so that all of my children close and free (instead of minimize). I tested and that code gets called for all of my children, so this is allright.

The problem is that children don't seem to be freed. I have a routine in my main form in which I close every children. I tried these 2 codes, but non of them worked :

while (MDIChildCount > 0) do
  MDIChildren[0].Close;

and

for i := (MDIChildCount - 1) downto 0 do
  MDIChildren[i].Close;

In both case, the FormClose event is correctly called the Action := caFree; is executed. But after each execution, the MDIChildCount isn't updated, and the form still is in the MDIChildren list. With the "for" case, the last form in the list (the first one closed) is placed in the first position, so I have an error when the main form tries to free it again.

I hope someone has an idea on that one
Thanks a lot

Martin

 

Re:MDI App. - Problem closing children


"Peter Below (TeamB)" <100113.1...@compuXXserve.com> wrote:

Quote
>In article <3d9c8...@newsgroups.borland.com>,  wrote:
>> while (MDIChildCount > 0) do
>>   MDIChildren[0].Close;

>Simply call Free, not Close.

>If you call Close the form will internally call Release, which delays the Free
>until the code returns to the message loop. So, after your Close statement executes
>the form does still exist. From "outside" a form you can call Free with no problems.

Thanks a lot, I now understand what was going on. But the
problem I now have is that I have some stuff that I need to
execute on the OnCloseQuery event. It seems to me that the Free
method doesn't call any of the closing events.

What I thought about is something like this :

while (MDIChildCount > 0) do
  begin
    tmp := MDIChildren[i];
    tmp.Close;
    tmp.Free;
  end;

The reason why I put a temporary variable is because of the ActiveMDIChild system which put the last form into the first MDIChildren position when I call the last form's Close method.

Is this workaround ok ?? Is it a good way to code things or it's bad programming ??

Martin

Re:MDI App. - Problem closing children


Quote
In article <3d9d991...@newsgroups.borland.com>,  wrote:

> Thanks a lot, I now understand what was going on. But the
> problem I now have is that I have some stuff that I need to
> execute on the OnCloseQuery event. It seems to me that the Free
> method doesn't call any of the closing events.

Yes, a bit surprising at first glance but there is a reason to this madness: you
cannot "undo" a destructor call, so setting CanClose to false in OnCloseQuery
would have no effect.

I tried this:

  for i:= MDIChildCount-1 downto 0 do
    MDIChildren[i].Close;
  Application.ProcessMessages;  
  showmessage( Format('MDI child count is %d', [MDIChildcount] ));  

It gets a childcount of 0 in the message. Processing messages after the loop gets
all the pending release actions executed. Would that be a solution to your problem?

An alternative construct is

  for i:= MDIChildCount-1 downto 0 do begin
    MDIChildren[i].CloseQuery;
    MDIChildren[i].Free;
  end;

CloseQuery is the method that fires the OnCloseQuery event. Calling Close instead
should do no harm, however.

--
Peter Below (TeamB)  
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be

Re:MDI App. - Problem closing children


Quote
>I tried this:

>  for i:= MDIChildCount-1 downto 0 do
>    MDIChildren[i].Close;
>  Application.ProcessMessages;  

>--
>Peter Below (TeamB)  

Thanks a lot, that worked perfectly.

Martin

Other Threads