2
votes

I have trouble in minimizing all my MDIChildren and came across MDIChild to minimize not activated properly

My code to minimize all my children is:

procedure TMainWindow.MinimizeAll1Click(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to MDIChildCount - 1 do begin
    MDIChildren[i].WindowState := wsMinimized;
    //ShowWindow(MDIChildren[i].Handle, SW_MINIMIZE)
  end;
end;

I tried both methods (SW_MINIMIZE and wsMinimized) but for some reason one last MDI children form gets NOT minimized. However if you try to minimize all the children again, it works. The minimize all works in the MDIAPP example from Delphi XE. How do I properly minimize all MDI Children in 1 routine?

1
Just reverse your loop and done.OnTheFly
@user539484 I suspect that works also. But if it does it relies heavily on implementation details. Can you prove that it works? So I would strongly advise that your proposal is not used. You don't need to think about implementation details if you take a non-mutating copy of the list of children first, and then walk over that non-mutating list.David Heffernan
The reverse loop is actually not bad at all. I didn't think of that.Benjamin Weiss
@BenjaminWeiss State a proof as to why the reverse loop works. Even if you can, that proof will depend on the private unpublished details of the Windows MDI implementation.David Heffernan
@David Heffernan, yes I can, and you can either. Your answer why forward loop fails, same applies to why reverse succeeds.OnTheFly

1 Answers

3
votes

Minimizing an MDI child window changes the order in which the forms appear in MDIChildren[]. This indexed property always returns the active MDI child in MDIChildren[0]. So, the cleanest way to do what you want is to take a copy of all the forms first, and then start minimizing.

var
  i: Integer;
  Forms: array of TForm;
....
SetLength(Forms, MDIChildCount);
for i := 0 to high(Forms) do
  Forms[i] := MDIChildren[i];
for i := 0 to high(Forms) do
  Forms[i].WindowState := wsMinimized;