views:

438

answers:

4

Hi!

Many times we experienced after Windows 98 era that some dialogs are lost their Z-Order, and moved back to prior form.

For example:

Dialog1.ShowModal;

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

When MessageBox appears, sometimes not got focus, it is moved under Dialog1. The users confused on it, because they are say: application freezed!!! But if they are uses AltTab to move another app and back, the focus return to the MessageBox, and it will be the foreground Window.

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

Is anyone knows about this? Is it Windows bug? How to prevent it? How to catch this?

Thanks for your help: dd

+3  A: 

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.

Craig Stuntz
Wow, the [documentation on this](http://docwiki.embarcadero.com/VCL/en/Forms.TForm.PopupMode) is not helpful at all! But try it; it works!
Craig Stuntz
@Craig - wouldn't help with ShowMessage, MessageBox and exception messages though..
Sertac Akyuz
@Sertac, those are convenience functions around regular windows. You can do custom exception messages by handling `Application.OnException`. Likewise, if you need a customized `ShowMessage`, you can write one.
Craig Stuntz
@Craig - Sure you can - simulate a form with a system message box, find the top window, popupparent it, normalize top mosts, disable task windows, and then don't use the convenient procedures in forms.pas while doing these because probably the problem lies there to begin with... And instead of forms, you can also do CreateWindowEx, message loops etc.. but forms are convenient. ;) All of this is beyond my point, which was to point out what I said.
Sertac Akyuz
@Sertac, do you actually find it challenging to call [CreateMessageDialog](http://docwiki.embarcadero.com/VCL/en/Dialogs.CreateMessageDialog)? Really?
Craig Stuntz
@Craig - See http://qc.embarcadero.com/wc/qcmain.aspx?d=67134 for instance, to see why it will "not" help (at least for versions before D2009). Sorry if I'm sounding a bit sour on this, but I've struggled with the VCL.., I've struggled with a sysop.., worked around some, could not work around some... I can't duplicate the remaining issues but customers report "glitches".. If you excuse me, I don't want to struggle yet with a TeamB'er... All I said was that popupparent would not work with MessageBox etc..
Sertac Akyuz
If the original poster is using Delphi 7 or earlier, this won't help. And he's on Windows 98. So not exactly up with the times.
Warren P
Sertac, see my other answer.
Warren P
@Sertac, that's an entirely different issue. You're using a stay on top form (nearly always a mistake IMHO, but that's a separate issue). He is not. Regarding the WinAPI `MessageBox`, if you use it, you can do the same thing that `PopupParent` does.
Craig Stuntz
Using fsStayOnTop, as Craig says, is considered a poor solution.
Warren P
+4  A: 

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);
Warren P
A: 

I looked at this page and the FAQ for half an hour and still can't find how to post a comment, so forgive me for this breach of protocol.

First of all I'd like to make clear that the poster, IMHO, is not using Windows 98. He writes "after Windows 98 era" which I understand means he is having this problem with Windows versions after 98.

As I am having this problem too (CB2009), I'd like to emphasize the poster's question "Is it Windows bug?", which I have not seen answered. If it's a Delphi/Builder bug, maybe there is a way to avoid it? I can't see how intercepting all potential dialogs is a workable solution, nor avoid using fsStayOnTop. I have a settings form that needs to stay on top of my main form, but the settings form can and will popup dialogs that under certain conditions will disappear under the settings form.

It would be very helpful if I would understand where the support of z-order goes wrong, as it may offer a clue on how to avoid it.

Mike Versteeg
It is a windows bug, in the sense, that the Z-order of your forms is not preserved by the architecture of the Windows internal "window manager" in Windows XP, after a certain point. It is NOT a windows bug, in the sense that the Windows API itself does not guarantee that it will remember some kind of particular Z-Order that exists, unless you have set your parent-window links correctly using the CreateParams (as I have shown in my answer).
Warren P
Incidentally can you really not see any text (possibly gray) or a button labelled "Add Comment"?
Warren P
Yes, but only for my own post. Maybe one is only allowed to comment on other posts if one has enough points, but then I can post a reply.. So I do not see the logic in this. Nor why this bug exists btw, seems easy enough to get it right.
Mike Versteeg
Me too. It seems a fundamental error in the Windows platform, that Microsoft WILL NOT FIX. Thus, it falls to us, poor developers to provide what they ask for: A way for their Window Manager to determine Z-order after it 'forgets it', by checking the Win32 Window memory records (calling them objects seems a bit of a stretch). It seems that the window manager is especially prone to forgetting your window order, when your main window application message loop has points of non-responsiveness lasting > 500 msec.
Warren P
A: 

Hi!

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

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

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

But we will trying with it.

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

Somebody can explain me what is the meaning of the WS_POPUP flag? Is it have some side effect or not?

Thanks: dd

durumdara
Aha. Delphi 6 pro. Okay. use my answer then.
Warren P
Of course WS_POPUP has a side effect. It tells windows that this is a popup window. :-)
Warren P
What on EARTH do you mean by "completely new application with substitution of the forms"? Did you read my answer? No rewrite. A few lines of code per form, and you are done.
Warren P