Is calling ShowModal with setting PopupParent a good idea and is it necessary in newer Delphi versions?
Asked Answered
C

2

6

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 [...]

Camera answered 9/1, 2015 at 16:11 Comment(6)
Does this still apply? I never do this (but I've used D2007 and DXE2). The linked posts are from 2009 and 2010.Paranoid
@JanDoggen I got these kind of errors reported for Win7 and Win8 for my application compiled under D2006. (But they occur rarely.) Whether they still occur with newer Delphi versions is part of, what I would like to know.Camera
Occurs in XE2 too (at least under Win7).Translative
@DavidHeffernan, check out what Alois wondered.Translative
@Edijs all very impreciseDeceased
@DavidHeffernan I edited the question to be more precise about the original problem. I think Edijs is referring to this behaviour.Camera
D
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;
Delila answered 5/8, 2015 at 22:34 Comment(4)
New blog post url is: community.embarcadero.comHass
@Hass Link fixed. Now pointing to personal Allen Bauer's blog which contains a copy of all posts he created during Embarcadero times.Delila
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 PopupParentOliphant
@EdwinYip I only edited that post for some grammar and spelling errors. The content is fully ventiseis' .Silage
H
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

Hass answered 16/3, 2018 at 13:25 Comment(1)
Re #2, same in XE4's TCustomForm.set_PopupParent, FPopupMode will be changed to pmExplicit when changing PopupParentOliphant

© 2022 - 2024 — McMap. All rights reserved.