"Оставайся на вершине" основной формы и модальных диалогов в Delphi XE

В Delphi XE Update 1 я получаю, казалось бы, случайное поведение модальных форм, если для FormStyle родительской (основной) формы установлено значение fsStayOnTop.

1) С MainFormOnTaskbar:= False (по старинке) все "просто работает". С новым MainFormOnTaskbar:= True модальные формы скрываются за основной формой, когда основная форма установлена ​​на "оставаться сверху". В большинстве случаев говорят

modalForm.PopupParent := self;

как раз перед вызовом modalForm.ShowModal, кажется, помогает. Но не всегда.

2) Все мои модальные формы просты, без излишеств, расположены в MainFormCenter, не используют наследование форм и т. Д. И все же исправление PopupParent работает только для примерно половины из них, в то время как другая половина все еще скрывается за основной формой. Самое странное, что в одном случае упорядочение несвязанных строк кода нарушает или делает это. Смотрите строки, отмеченные (1) и (2) в этом коде:

procedure TEchoMainForm.DBMaintenancePrompt( actions : TMaintenanceActions );
var
  frm : TDBMaintenanceForm;
begin
  frm := TDBMaintenanceForm.Create( self );
  try
    frm.Actions := actions; // (1)
    frm.PopupParent := self; // (2)
    frm.ShowModal;
  finally
    frm.Free;
  end;
end;

При выполнении в этом порядке модальная форма отображается правильно поверх главной формы. Но когда я переворачиваю линии, модальная форма прячется за основной. Строка, помеченная (1), устанавливает свойство модальной формы, что приводит к тому, что несколько флажков не проверяются в TRzCheckGroup и располагаются в TRzPageControl (из компонентов Raize). Это метод установки, который запускается, когда выполняется строка (1) выше:

procedure TDBMaintenanceForm.SetActions(const Value: TMaintenanceActions);
var
  ma : TMaintenanceAction;
begin
  for ma := low( ma ) to high( ma ) do
    cgMaintActions.ItemChecked[ ord( ma )] := ( ma in Value );
  end;
end;

Этого достаточно для показа модальной формы за основной формой, если порядок линий (1) и (2) обратный.

Это может указывать на TRzCheckGroup (которым манипулируют при выполнении кода установщика), но у меня есть две другие формы, которые показывают ту же проблему и не используют TRzCheckGroup (или TRzPageControl). И я не смог воспроизвести проблему с отдельным примером приложения с использованием компонентов Raize. Отключение формы, pagecontrol или TRzCheckGroup на время установки не имеет никакого эффекта.

Похоже, что это не проблема синхронизации, потому что когда модальная форма отображается скрытой, это всегда происходит. Изменение в поведении происходит только от перестановки строк кода.

3) Последнее замечание: мои модальные формы довольно просты, поэтому они отображаются практически мгновенно, без видимой задержки. Но когда основной формой является fsStayOnTop, то очень часто я вижу модальную форму, отображаемую поверх нее, а затем вижу, что она "отталкивается" позади. Затем, при нажатии Esc, (невидимая) модальная форма показывается поверх основной формы в течение доли секунды, затем закрывается.

Либо я упускаю что-то, что может показаться очевидным в ретроспективе, либо это призыв к экстрасенсорной отладке, я не знаю. Есть идеи, пожалуйста?


ОБНОВЛЕНИЕ. Я пытался отследить проблему в другой форме, где она возникает. Он имеет несколько кнопок (Raize) и TSyntaxMemo (расширенный компонент memo от eControl.ru). Эта форма почти не имеет ничего общего с другими формами, которые испытывают проблему. После удаления частей кода и тестирования я теперь могу воспроизвести проблему, внеся небольшое изменение в метод, который присваивает строку компоненту memo:

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

procedure TEditorForm.SetAsText(const Value: string);
begin
  Editor.Text := Value;
end;

Когда я изменяю присвоение на пустую строку, форма отображается правильно:

procedure TEditorForm.SetAsText(const Value: string);
begin
  Editor.Text := ''; // CRAZY! Problem goes away
end;

Когда я назначаю редактору один символ, форма снова начинает скрываться:

procedure TEditorForm.SetAsText(const Value: string);
begin
  Editor.Text := 'a'; // Problem is back
end;

Конечно, другие две проблемные формы не используют этот компонент редактора или его единицы.

Я попытался удалить элемент управления memo и добавить его снова (например, порядок создания и т. Д.), Но это не дало никакого эффекта. То же самое, если я создаю памятку в коде. Форма скрывается, как только непустой строке присваивается свойство Text заметки.

2 ответа

У меня была такая же проблема некоторое время назад. Моим решением было добавить Self.BringToFront; к OnShow событие модальной формы.

Windows не поддерживает многие формы для приложений. И модальная форма является самой верхней по умолчанию. Но у вас есть этот стиль для вашей собственной формы.

Одно решение: уберите верхнюю часть вашей основной формы (без видимого эффекта), вызовите модальную форму, верните самый верхний стиль, когда модальная закончится.

Другие вопросы по тегам