Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi - How to prevent Forms/MsgBoxes to move under prior form?

Many times after the Windows 98 era we have experienced that some dialogs lose their Z-Order and move back to the prior form.

For example:

Dialog1.ShowModal;

Dialog1.OnClickButton() : ShowMessage('anything');

When MessageBox appears, it sometimes doesn't have focus and is moved under Dialog1. The users are confused about it, they say: My application froze!!! But if they use Alt+Tab to move to another app and back, the focus returns to the MessageBox and it will be the foreground window.

We have experienced this with ShowMessage, MessageBox, normal forms, and also QuickReport forms.

Does anyone know about this? Is it a Windows bug? How can you prevent it? How to catch this?

Thanks for your help: dd


I really said that AFTER Win98, so all OSs (Win7 also) are affected by this problem. We used Delphi 6 Prof, so the properties are not working with Default forms.

Somebody said that message dialogs are controllable with MessageBox + MB_APPLMODAL. This is good news, but we have many old forms and components, third party tools.

So it is hard work to make a completely new application with substitution of the forms.

But we will try doing this.

I think the answer is this is a half application problem and half a Windows problem. If Windows sometimes handles this, and sometimes doesn't - that seems to be a Windows bug. But if we can force good modal window making then it is a programming bug.

Can somebody explain to me what is the meaning of the WS_POPUP flag? Does it have some side effect or not?

Thanks: dd

like image 964
durumdara Avatar asked Jun 08 '10 12:06

durumdara


2 Answers

That's what the PopupMode and PopupParent properties are for.

E.g., you can do:

Dialog1.PopupMode := pmExplicit;
Dialog1.PopupParent := self;
Dialog1.ShowModal;

This tells Windows the correct Z-order.

like image 71
Craig Stuntz Avatar answered Nov 06 '22 19:11

Craig Stuntz


For old versions of delphi (prior to Delphi 2007), on forms OTHER than your main form:

interface
  TMyForm = Class(TForm)
  protected
    procedure CreateParams(var Para: TCreateParams); override;
  end;
...
implementation
...
procedure TMyForm.CreateParams(var Para: TCreateParams);
begin
  inherited;
  Para.Style := Para.Style or WS_POPUP;
  { WinXP Window manager requires this for proper Z-Ordering }
  // Para.WndParent:=GetActiveWindow;
  Para.WndParent := Application.MainForm.Handle;
end;

For message boxes include MB_TOPMOST in your flags:

Application.MessageBox(PChar(amessage), PChar(atitle),    otherflags or MB_TOPMOST);
like image 42
Warren P Avatar answered Nov 06 '22 21:11

Warren P