Что такое TApplication.Handle
?
- От куда это?
- Почему он существует?
- И самое главное: почему все формы имеют его как дескриптор родительского окна?
Справка Delphi говорит:
TApplication.Handle
Предоставляет доступ к дескриптору окна основной формы (окна) приложения.
property Handle: HWND;
Описание
Используйте Handle при вызове функций Windows API, которым требуется дескриптор родительского окна. Например, DLL, которая отображает собственные всплывающие окна верхнего уровня, нуждается в родительском окне для отображения своих окон в приложении. Использование свойства Handle делает такие окна частью приложения, поэтому они сворачиваются, восстанавливаются, включаются и отключаются вместе с приложением.
Если я сфокусируюсь на словах «дескриптор окна основной формы приложения», и я пойму, что это означает дескриптор окна основной формы приложения, тогда я могу сравнить:
- "дескриптор окна основной формы приложения", с
- оконный дескриптор
MainForm
Application
но они не то же самое:
Application.MainForm.Handle: 11473728
Application.Handle: 11079574
Так что такое Application.Handle
?
- От куда это?
- Что это за дескриптор окна Windows?
- Если это дескриптор окна Windows для
Application
MainForm
, то почему они не совпадают? - Если это не дескриптор окна
MainForm
Application
, тогда что это? - Что еще более важно: почему он является конечным владельцем каждой формы
parent? - И самое главное: почему все идет наперекосяк, если я пытаюсь сделать форму
unparentedunowned (чтобы она могла отображаться на панели задач) или пытаюсь использовать что-то вроде IProgressDialog strong >?
На самом деле я спрашиваю: каково обоснование дизайна, благодаря которому существует Application.Handle? Если я могу понять почему, то как должно стать очевидным.
Обновление. Разберитесь с помощью игры из двадцати вопросов:
Говоря о решении создания окна на панели задач, сделав его владельцем null
, Питер Белов в 2000 году сказал:
Это может вызвать некоторые проблемы с модальными формами, отображаемыми из вторичных форм.
Если пользователь переключается с приложения, пока модальная форма активна, а затем возвращается к форме, которая показывала его, модальная форма может скрываться под формой. С этим можно справиться, убедившись, что модальная форма является родительской [sic; он имел в виду принадлежал] в форму, которая его показывала (используя
params.WndParent
, как указано выше)Но это невозможно со стандартными диалоговыми окнами из модуля
Dialogs
и исключений, которым требуется больше усилий, чтобы заставить их работать правильно (в основном обработкаApplication.OnActivate
, поиск модальных форм, связанных с приложением strong> черезGetLastActivePopup
и вывод их на вершину Z-порядка черезSetWindowPos
).
- Почему модальная форма застревает позади других форм?
- Какой механизм обычно выводит модальную форму на передний план и почему здесь она не работает?
- Windows отвечает за отображение окон в стопке. Что пошло не так, что Windows не показывает правильные окна?
Он также рассказал об использовании нового расширенного стиля Windows, который заставляет окно появляться на панели задач (когда обычные правила вывода окна из-под контроля недостаточны, непрактичны или нежелательны), добавляя WS_EX_APPWINDOW
расширенный стиль:
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams( params );
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
end;
Но затем он предупреждает:
Если вы нажмете кнопку вторичной формы на панели задач, когда другое приложение активно, все формы приложений все равно будут выведены на передний план. Если вы не хотите, есть вариант
Кто выносит все формы на передний план, когда владельцем формы еще Application.Handle
. Приложение делает это? Почему он это делает? Вместо того, чтобы делать это, разве он не должен этого делать? В чем обратная сторона того, не этого делать; Я вижу обратную сторону выполнения этого (системное меню не работает должным образом, эскизы кнопок на панели задач неточны, оболочка Windows не может свернуть окна.
В другом сообщении, посвященном Application
, Майк Эденфилд говорит, что родительское окно отправляет другим окнам их минимизацию , развернуть и восстановить сообщения:
Это добавит кнопку панели задач для вашей формы, но есть еще несколько мелких деталей, которые нужно обработать. Наиболее очевидно, что ваша форма по-прежнему получает минимизацию / максимизацию, которые отправляются в родительскую форму (основная форма приложения). Чтобы этого избежать, вы можете установить обработчик сообщений для WM_SYSCOMMAND, добавив такую строку, как:
procedure WMSysCommand(var Msg: TMessage); WM_SYSCOMMAND; procedure TParentForm.WMSysCommand(var Msg: TMessage); begin if Msg.wParam = SC_MINIMIZE then begin // Send child windows message, don't // send to windows with a taskbar button. end; end;
Обратите внимание, что этот обработчик имеет форму PARENT того, который вы хотите вести независимо от> остальной части приложения, чтобы избежать передачи сообщения сворачивания. Вы можете добавить аналогичный> код для SC_MAXIMIZE, SC_RESTORE и т. Д.
Как получается, что сообщения сворачивания / разворачивания / восстановления для моих окон Windows не попадают в мое окно? Это потому, что сообщения, предназначенные для окна, отправляются Windows владельцу окна? И в этом случае все формы в приложении Delphi «принадлежат» Application
? Разве это не означает, что значение владельца становится равным нулю:
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WndParent := 0; //NULL
end;
удалит Application
и его оконный дескриптор от вмешательства в мою форму, и Windows должна снова отправить мне мои сообщения о минимизации / максимизации / восстановлении?
Возможно, если бы мы сравнили и сопоставили теперь «нормальное» приложение Windows, которое делает что-то, с тем, как Borland изначально разрабатывал приложения Delphi, чтобы делать что-то - в отношении этого Application
объекта и его основного цикла.
- какое решение было решено
Application
объектом? - Какие изменения были внесены в более поздние версии Delphi, чтобы этих проблем не было?
- Разве изменение в более поздних версиях Delphi не привело к возникновению других проблем, которые так старался решить исходный дизайн приложения?
- Как эти новые приложения могут работать без вмешательства приложения?
Очевидно, Borland осознала этот недостаток в своем первоначальном дизайне. Каков был их первоначальный дизайн, какую проблему он решал, в чем был недостаток, в чем был изменен дизайн и как он решает проблему?
Create(AOwner: TComponent
). «Родитель» (или «WndParent») имеет отношение к визуальным родительским / дочерним отношениям визуальных элементов управления. Итак, почему каждая форма имеетApplication
в качестве владельца, потому чтоApplication.CreateForm(TMyForm, MyForm)
создает форму, используя себя в качестве владельца. А о родительском дескрипторе Application.Handle см.TCustomForm.CreateParams
. - person R. Hoek   schedule 03.06.2019