views:

130

answers:

3

HI

I'm using Delphi 2007 and have set the MainFormOnTaskBar property to true.

The issue that I'm having is this.

If you open a child window from the main form and then you show a message dialog from the child window you just opened. When you close the message dialog and then close the child window, the main form will be sent to the back of any other application you have on the screen.

This happens under windows Vista and Windows 7. Does anyone know why this is happens and how can I fix it?

+4  A: 

I guess that would be QC66892-Closing forms deactivates the application, which appears to have been fixed with Delphi 2009 according to the report. At the bottom of the QC report you'll find a comment by Andreas Hausladen including a link to his fix of the bug. But you'd really want to utilize his VCL Fix Pack which includes many other fixes as well.

Sertac Akyuz
thank you for that. Yes I found that it happens when closing any form, not just modal forms. For example if I open a child form from the main form then then open a second child form from the first child form. Closing the second child form and then closing the first child form will send the main form to the back of any other applications.
no spoon
I downloaded the fix for QC #66892 and noticed that it mentioned about a missing stdcall directive was causing the issue. So rather than including the fix unit in my project I just added the stdcall to the DoFindWindow function of Forms.pas and recompiled the VLC. Works great, thank you for that.
no spoon
@no spoon - You're welcome, but the credit is really Andy's. :)
Sertac Akyuz
Correction, it worked on my test application but doesn't work on my main application. I doesn't seem to pick up the stdcall directive. I have tried adding Andy's HideStackTrashingFix to the uses clause but that doesn't seem to work either.
no spoon
Basically in my main application DoFindWindow never gets call, like when it does not have the stdcall directive. I've done a full clean rebuild (deleted all dcu's) which hasn't solved the issue. I guess something in the main application is preventing this from working properly.
no spoon
Ahh I've found the reason. In our main application when we close a child screen we handle the OnClose event of the form and return back caFree. However FindTopMostWindow (which uses DoFindWindow) only gets call if you return back caHide (the default). This is also why Andy's code does not solve the issue either because his code also hooks FindTopMostWindow, its a bit of a pickle really.
no spoon
A: 

I've fixed this in two ways.

Firstly by adding stdcall to the end of DoFindWindow in Forms.pas as described by Andreas Hausladen. This handles when a child form is hidden (CloseAction = caHide) instead of released when closing the form.

Secondly - copied the code from TCustomForm.CMShowingChanged that calls FindTopMostWindow and then activates the window that was returned into TCustomForm.CMRelease.

(Edit: code block needs to be indented by 4 spaces)

procedure TCustomForm.CMRelease;
var
  NewActiveWindow: LongInt;
begin
  if Application.MainFormOnTaskbar then
  begin
    NewActiveWindow := 0;

    if (GetActiveWindow = Handle) and not IsIconic(Handle) then
    begin
      NewActiveWindow := FindTopMostWindow(Handle);
    end;

    if NewActiveWindow <> 0 then
    begin
      SetActiveWindow(NewActiveWindow);
    end;
  end;

  Free;
end;

This seems to have done it, I'll continue testing to make sure.

no spoon
A: 

The PopupMode and PopupParent properties were added specifically to TForm to address this issue. Before showing the child form, set it's PopupParent to the main form, and it's PopupMode to pmAuto.

PopupParent specifically affects the Z-order of windows when other windows are shown.

The Delphi 2007 help has some documentation on these two properties, but you have to go through TForm to get to them. Use 'TForm,Pop' as your search topic (w/o the quotes, obviously ) to get there. The docs are a little confusing about PopupParent, because it discusses the effect that PopupMode has on the automatic assignment of PopupParent. A little experimentation after reading the docs should pay off, though.

Ken White
Alright thank you, I'll look into it.
no spoon