Недавно созданное модальное окно теряет фокус и становится недоступным в 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; Конец;