Delphi - Как предотвратить Forms/MsgBoxes для перемещения под предшествующей формой?

Много раз после эры Windows 98 мы испытывали это, некоторые диалоговые окна теряют свой Z-порядок и пятятся к предшествующей форме.

Например:

Dialog1.ShowModal;

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

Когда MessageBox появляется, он иногда не фокусируется и перемещен под Dialog1. Пользователи смущены этим, они говорят: Мое приложение заморозилось!!! Но если они используют Alt+Tab для перемещения в другое приложение и назад, фокус возвращается в MessageBox, и это будет активное окно.

Мы испытали это с ShowMessage, MessageBox, нормальными формами и также формами QuickReport.

Кто-либо знает об этом? Действительно ли это - ошибка Windows? Как можно предотвратить его? Как поймать это?

Спасибо за помощь: dd


Я действительно сказал, что ПОСЛЕ Win98, таким образом, все OSs (Win7 также) затронуты этой проблемой. Мы использовали профессора Delphi 6, таким образом, свойства не работают с формами По умолчанию.

Кто-то сказал, что диалоговые окна сообщения управляемы с MessageBox + MB_APPLMODAL. Это - хорошие новости, но у нас есть много старых форм и компонентов, сторонних инструментов.

Таким образом, это - тяжелая работа для подавания абсолютно новой заявки с заменой форм.

Но мы попытаемся делать это.

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

Кто-то может объяснить мне, каково значение флага WS_POPUP? Это имеет некоторый побочный эффект или нет?

Спасибо: dd

16
задан Karl Nicoll 22 May 2015 в 17:41
поделиться

3 ответа

Вот для чего нужны свойства PopupMode и PopupParent.

Например, вы можете сделать:

Dialog1.PopupMode := pmExplicit;
Dialog1.PopupParent := self;
Dialog1.ShowModal;

Это сообщает Windows правильный Z-порядок.

16
ответ дан 30 November 2019 в 22:01
поделиться

Я полчаса изучал эту страницу и FAQ, но так и не нашел, как оставить комментарий, так что простите меня за это нарушение протокола.

Прежде всего, я хотел бы уточнить, что автор сообщения, IMHO, не использует Windows 98. Он пишет "после эры Windows 98", что, как я понимаю, означает, что он сталкивается с этой проблемой с версиями Windows после 98.

Поскольку у меня тоже есть эта проблема (CB2009), я хотел бы подчеркнуть вопрос автора "Это ошибка Windows?", на который я не увидел ответа. Если это ошибка Delphi/Builder, может быть, есть способ избежать ее? Я не вижу, как перехват всех потенциальных диалогов является работоспособным решением, как и избежание использования fsStayOnTop. У меня есть форма настроек, которая должна оставаться поверх основной формы, но форма настроек может и будет всплывать диалоги, которые при определенных условиях будут исчезать под формой настроек.

Было бы очень полезно понять, где поддержка z-порядка идет не так, поскольку это может дать подсказку, как этого избежать.

0
ответ дан 30 November 2019 в 22:01
поделиться

Для старых версий delphi (до Delphi 2007), на формах ДРУГИХ, чем ваша главная форма:

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;

Для окон сообщений включите MB_TOPMOST в ваши флаги:

Application.MessageBox(PChar(amessage), PChar(atitle),    otherflags or MB_TOPMOST);
6
ответ дан 30 November 2019 в 22:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: