Недавно созданное модальное окно теряет фокус и становится недоступным в Windows Vista

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

Обычно, когда это происходит, мне приходится использовать Alt + Tab или Windows + Tab, чтобы найти "скрытое" модальное окно, но это не всегда работает.

Такое поведение просто происходит в Vista, но это довольно раздражает.

Есть ли какой-нибудь способ предотвратить эту "странную фокусировку"?

Благодарю.

* РЕДАКТИРОВАТЬ *

Очевидно, установка Application.MainFormOnTaskbar:= True решила проблему, но пока рано делать поспешные выводы, потому что это происходит случайным образом.

* РЕДАКТИРОВАТЬ 2 *

ModalFormOnTaskbar не решил проблему, после этого я попытался установить PopupMode = pmAuto, но это только усугубило проблему.

Прямо сейчас я пытаюсь установить PopupParent явно и сообщу, если проблема решена.

5 ответов

Решение

Посмотрите на свойство PopupParent. Возможно, вы захотите установить его явно для вашей модальной формы до вызова ShowModal. Когда PopupParent равен nil (по умолчанию), VCL ведет себя немного по-разному в зависимости от значения соответствующего свойства PopupMode.

Если вы установите PopupParent модальной формы в форму, активную непосредственно перед вызовом ShowModal, это может помочь.

Проблема, с которой вы начали сталкиваться, когда Windows XP представила концепцию оконного ореола. Из-за необычной архитектуры, которую использует Delphi (все формы являются потомками скрытого окна - TApplication), многие приложения Delphi сталкиваются с той же проблемой.

Один из способов быстро решить эту проблему - отключить двоичные окна при инициализации приложения:

var 
  User32: HMODULE; 
  DisableProcessWindowsGhosting: TProcedure; 
begin 
  User32 := GetModuleHandle('USER32'); 
  if User32 <> 0 then 
  begin 
    DisableProcessWindowsGhosting := GetProcAddress(User32, 'DisableProcessWindowsGhosting'); 
    if Assigned(DisableProcessWindowsGhosting) then 
      DisableProcessWindowsGhosting; 
  end; 
end;

Другое возможное (более элегантное, но трудоемкое) решение - нормализовать ваше приложение Delphi.

Третьим вариантом будет переход на Delphi 2006 (Delphi 10.0).

Помимо проблемы, о которой вы сообщаете, архитектура Delphi привносит еще больше странностей, среди которых различные меню панели задач и невозможность мигать.

Мне удалось уменьшить количество таких случаев, удалив все вызовы Application.ProcessMessages, которые есть в моем коде, где бы я ни мог.

Alt+P+V (.dpr) имеет Application.MainFormOnTaskbar := True; по умолчанию, я не знаю почему, но если я поставлю Application.MainFormOnTaskbar := False; проблема решена.

Вы можете попробовать редактирование Forms.pas добавить код ниже в TCustomForm.ShowModal()незадолго до звонка Application.ModalStarted():

if Assigned(Application) then begin
  while PeekMessage(msg, Application.Handle, CM_ACTIVATE, CM_DEACTIVATE, PM_REMOVE) do begin
    TranslateMessage(msg);
    DispatchMessage(msg);
  end;
end;

У меня была такая же проблема в Windows 10, и я решил ее, заменив в файле dpr/dproj:

… Application.CreateForm(TFrmMain, FrmMain);

Application.run;...

От

… Application.CreateForm(TFrmMain, FrmMain);

Попробуйте FrmMain.ShowModal; Наконец FrmMain.Free; Конец;

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