Как я могу переместить форму Delphi перед другой?

У меня есть приложение, которое всегда показывает как минимум две формы одновременно.

Обычно у меня есть список вакансий в дочерней форме основной формы с соответствующими деталями, отображаемыми в основной форме. Другие детали могут управляться с помощью ShowModal.

Текущая проблема заключается в том, что пользователи недавно запросили возможность перетаскивания основной формы перед списком заданий.

Насколько я вижу, поскольку форма списка вакансий создается после основной формы и вызывается для отображения из основной формы, она получает «переднюю» позицию.

Можно ли как-то это изменить во время выполнения, т.е. могу ли я установить активную форму на передний план?


person Dan Kelly    schedule 01.11.2011    source источник


Ответы (2)


Примечание. В остальной части этого ответа термин принадлежит принимает значение, используемое документация Windows. Это отличается от значения того же термина в VCL.

Происходит то, что ваше окно списка заданий является окном верхнего уровня.

Владение накладывает на окно несколько ограничений.

  • Принадлежащее окно всегда выше своего владельца в z-порядке.
  • Система автоматически уничтожает принадлежащее окно, когда уничтожается его владелец.
  • Принадлежащее окно скрыто, когда его владелец свернут.

Если вы хотите, чтобы ваше окно списка заданий могло располагаться ниже главного окна в z-порядке, оно не может принадлежать главному окну. Вы можете добиться этого следующим образом:

class TJobListForm = class(...)
protected
  procedure CreateParams(var Params: TCreateParams); override;
...
procedure TJobListForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.WndParent := Application.Handle;
end;

Это делает окно списка заданий окном верхнего уровня, принадлежащим скрытому окну приложения. Или как вариант:

procedure TJobListForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.WndParent := 0;
end;

Это делает окно списка заданий бесхозным окном верхнего уровня. Таким образом, теперь он получает кнопку на панели задач.

Внесение таких изменений будет иметь далеко идущие последствия для вашего приложения. Второй и третий пункты в приведенном выше списке являются очевидными воздействиями. Также будет затронуто поведение ваших окон при сворачивании и их взаимодействие с панелью задач. Я только поцарапал на поверхности здесь. Вы, вероятно, обнаружите, что удаление окна со списком заданий из главного окна сильно повлияет на вашу программу. Вы обнаружите, что Windows делает за вас много работы за кулисами для собственного окна. Возможно, вам придется воспроизвести часть этой работы, если вы переключитесь на не принадлежащее окну.

person David Heffernan    schedule 02.11.2011
comment
Спасибо за это - именно то, что нужно. Поведение, кажется, именно то, что я ожидал, давайте посмотрим, что думает пользователь, запросивший изменение. - person Dan Kelly; 04.11.2011

Пока форма списка заданий не является дочерним элементом какого-либо другого окна (т. е. ее свойство Parent не установлено, а ее метод CreateParams() не переопределен для установки поля TCreateParams.WndParent), и она отображается с использованием метода Show() вместо ShowModal(). метод, то пользователь должен иметь возможность свободно переключаться между двумя окнами по своему желанию.

person Remy Lebeau    schedule 01.11.2011
comment
Немодальные окна обычно принадлежат основной форме и поэтому всегда находятся выше основной формы. Обратите внимание, что под принадлежащим я подразумеваю терминологию Windows, а не терминологию VCL. - person David Heffernan; 02.11.2011
comment
@David: владение немодальными окнами зависит от версии Delphi. В более старых версиях до того, как было введено свойство PopupMode, они принадлежали окну TApplication. В более новых версиях pmNone использует MainForm, только если Application.MainFormOnTaskBar равно True, pmAuto использует MainForm, только если нет подходящего ActiveForm, а Application.MainFormOnTaskBar - это True, а pmExplicit использует MainForm, только если PopupParent не назначено. - person Remy Lebeau; 02.11.2011
comment
Ясно, что в этом случае окно списка заданий принадлежит главному окну. Это ясно из сообщения о поведении z-порядка. - person David Heffernan; 02.11.2011