5

To prevent newly created modal windows to become hidden under their modal parent window I got used to always set PopupParent when calling ShowModal (as adviced here, here and here):

function TMyForm.ShowModal(ParentForm: TCustomForm): Integer;
begin
    PopupParent := ParentForm;
    Result := inherited ShowModal;
end;

But when debugging (a problem of lost form placement, set in FormCreate) I realized that setting PopupParent leads to a call to ReCreateWindow, thus destroying and recreating the underlying Windows screen object.

My questions:

  1. Is it a good idea to always set PopupParent - what might be resulting problems? Do viable alternatives exist?
  2. Is this still necessary in newer versions of Delphi (I am using D2006 at the moment but plan to update)?

EDIT:

I think all the linked questions above tackle the same problem, which is best described by the 3rd link:

[A form is opened] with ShowModal, this form opens another with ShowModal, so we have stacked modal forms. There is sometimes a problem that when we call ShowModal in new form, it hides behind previous forms, instead of showing on top. After pressing alt+tab, form comes back to the top [...]

Community
  • 1
  • 1
Alois Heimer
  • 1,612
  • 1
  • 12
  • 36

2 Answers2

4

This question is quite old, but still relevant. The best source of information about this is from Allen Bauer himself: http://blog.therealoracleatdelphi.com/2004/02/popupmode-and-popupparent_10.html

(wayback: https://web.archive.org/web/20160324062228/http://blogs.embarcadero.com/abauer/2004/02/10/295 )

And there you find this: "If you explicitly set the PopupMode property to pmAuto prior to ShowModal, like at design-time, then the recreate isn’t necessary."

This way your code should be:

function TMyForm.ShowModal(ParentForm: TCustomForm): Integer;
begin
    PopupMode := pmAuto;
    PopupParent := ParentForm;
    Result := inherited ShowModal;
end;
Alexandre M
  • 904
  • 10
  • 18
  • New blog post url is: [community.embarcadero.com](https://community.embarcadero.com/blogs/entry/popupmode-and-popupparent-295) – ventiseis Mar 16 '18 at 12:59
  • 1
    @ventiseis Link fixed. Now pointing to personal Allen Bauer's blog which contains a copy of all posts he created during Embarcadero times. – Alexandre M Mar 17 '18 at 00:17
  • 1
    Not sure if it will work, because as per finding by @dummzeuch below, in `TCustomForm.set_PopupParent`, `FPopupMode` will be changed to `pmExplicit` when changing `PopupParent` – Edwin Yip May 09 '19 at 10:47
  • @EdwinYip I only edited that post for some grammar and spelling errors. The content is fully ventiseis' . – dummzeuch May 10 '19 at 17:34
3

After having spent 2 hours debugging and reading VCL code, I'll append my findings to this topic. In Delphi 10 Seattle, the behaviour is like this:

  • form window handles are allocated while creating the form by its constructor, because in TCustomForm.ReadState(Reader: TReader) the client width of the form is set which leads to the call to CreateWnd

  • so even if you put pmAuto prior ShowModal the window has to be recreated

Finally, the documentation mentions:

The PopupMode property is automatically set to pmAuto when the ShowModal method is called.

So there are these lines in ShowModal:

if (PopupMode = pmNone) and (Application.ModalPopupMode <> pmNone) then
begin
  RecreateWnd;
  //..

So to make this work, you have to change Application.ModalPopupMode as well, but this also recreates the window.

So my advice is:

  • set the value for PopupMode (pmAuto) directly in your form (dfm file)

  • setting both PopupParent and PopupMode makes little sense because they are tied together PopupParent sets pmExplicit, and pmAuto resets the popup parent to nil

dummzeuch
  • 10,406
  • 2
  • 47
  • 146
ventiseis
  • 2,760
  • 10
  • 31
  • 42
  • 1
    Re #2, same in XE4's `TCustomForm.set_PopupParent`, `FPopupMode` will be changed to `pmExplicit` when changing `PopupParent` – Edwin Yip May 09 '19 at 10:46