Delphi: Что такое Приложение. Дескриптор?

Что TApplication.Handle?

  • Куда это прибывает из?
  • Почему это существует?
  • И самое главное: почему все формы имеют его как свой родительский дескриптор окна?

Справка Delphi говорит:

TApplication. Дескриптор

Обеспечивает доступ к дескриптору окна основной формы (окно) приложения.

property Handle: HWND;

Описание

Используйте Дескриптор при вызове Windows API functions, которые требуют родительского дескриптора окна. Например, DLL, который отображает его собственные всплывающие окна верхнего уровня, нужно родительское окно для отображения его окон в приложении. Используя Handle свойство делает такую часть окон приложения, так, чтобы они были минимизированы, восстановлены, включены и отключены с приложением.

Если я фокусирую на словах "дескриптор окна основного бланка заявки на участие", и я беру это для значения дескриптора окна основного бланка заявки на участие, то я могу выдержать сравнение:

  • "дескриптор окна основного бланка заявки на участие", с
  • дескриптор окна MainForm из Application

но они не то же:

Application.MainForm.Handle: 11473728
Application.Handle: 11079574

Таким образом, что Application.Handle?

  • Куда это прибывает из?
  • Какой дескриптор окна Windows® - это?
  • Если это - дескриптор окна Windows® Application MainForm, затем, почему они не соответствуют?
  • Если это не дескриптор окна Application MainForm, затем, что это?
  • Что еще более важно: Почему это - окончательный родительский владелец каждой формы?
  • И самый важный: Почему все выходит из строя, если я пытаюсь иметь форму быть непорожденным не находящийся в собственности (так я, это может появиться на TaskBar), или попытайтесь использовать что-то как IProgressDialog?

Действительно то, что я спрашиваю: Что является объяснением дизайна, которое подает Заявку. Дескриптор существует? Если я могу понять, почему, как должен стать очевидным.


Обновление, Понимающее через игру двадцати вопросов:

В разговоре о решении того, чтобы заставлять окно появиться на панели задач путем создания ее владельца null, Peter Ниже в 2000 сказанного:

Это может вызвать некоторые проблемы с модальными формами, показанными от вторичных форм.

Если пользователь переключается далеко от приложения, в то время как модальная форма произошла, и затем обратно к форме, которая показала его, модальная форма может скрыться под формой. Возможно иметь дело с этим путем проверки, что модальная форма порождается [так; он значил принадлежавший] для формы, которая показала его (использование params.WndParent как выше)

Но это не возможно со стандартными диалоговыми окнами от Dialogs единица и исключения, для которых нужно больше усилия заставить их работать правильно (в основном обработка Application.OnActivate, поиск модальных форм, порожденных к Приложению через 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, Mike Edenfield говорит, что родительское окно отправляет другое окно их минимизировать, максимизировать и восстановить сообщения:

Это добавит кнопку панели задач для Вашей формы, но существует несколько других незначительных деталей для обработки. Наиболее очевидно, Ваша форма все еще получает, минимизируют/максимизируют, который отправляется в родительскую форму (основной бланк заявки на участие). Для предотвращения этого можно установить обработчика сообщений для 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; 

Обратите внимание, что этот обработчик входит в РОДИТЕЛЬСКУЮ форму той, которая Вы хотите вести себя независимо> остальная часть приложения, чтобы не передавать минимизировать сообщение. Можно добавить подобный> код для SC_MAXIMIZE, SC_RESTORE, и т.д.

Как получается, что минимизируют/максимизируют/восстанавливают сообщения для моих окон Windows®, не идут в мое окно? Это вызвано тем, что сообщения, предназначенные для окна, отправляются Windows® владельцу окна? И в этом случае все формы в приложении Delphi "принадлежат" Application? Делает это не означает что создание пустого указателя владельца:

procedure TForm2.CreateParams(var Params: TCreateParams);
begin
   inherited;
   Params.WndParent := 0; //NULL
end;

удалит Application и это - окно Handle от вмешательства с моей формой, и Windows должен еще раз отправить мне мои сообщения mimimize/maximize/restore?


Возможно, если мы выдержали сравнение и контрастировали теперь, "нормальное" Приложение Windows делает вещи, с тем, как Borland первоначально разработала приложения Delphi, чтобы сделать вещи - относительно этого Application возразите и это - основной цикл.

  • чем решение было Application объектное решение?
  • Какое изменение было внесено с более поздними версиями Delphi так, чтобы эти те же проблемы не существовали?
  • Изменение в более поздних версиях Delphi не представляют другие проблемы, что inital Проектирование приложений так старалось решать?
  • Как те более новые приложения могут все еще функционировать без Приложения, вмешивающегося в них?

Очевидно, Borland осознала дефект в их начальном дизайне. Каков был их начальный дизайн, какую проблему он решал, каков дефект, какова была модернизация, и как он решает проблему?

48
задан Ian Boyd 20 August 2018 в 17:27
поделиться

3 ответа

Причина, по которой окно приложения имеет неприятную историю. При разработке Delphi 1 мы знали, что хотим использовать модель пользовательского интерфейса «SDI» (окна разбросаны по всему рабочему столу) для IDE. Мы также знали, что Windows - отстой (и до сих пор) от этой модели. Однако мы также заметили, что Visual Basic в то время использовал эту модель, и, похоже, она работала хорошо. При дальнейшем исследовании мы обнаружили, что VB использовал специальное «скрытое» парковочное окно, которое использовалось как «владелец» (Windows иногда размывает понятие родителя и владельца, но различие похоже на VCL) для всех других видимых окон. .

Таким образом мы решили «проблему», когда окна, содержащие главное меню, редко когда-либо фокусировались, поэтому обработка Alt-F для меню «Файл» просто не работала. Используя это центральное парковочное окно в качестве посредника, мы могли бы легче отслеживать и перенаправлять сообщения в соответствующие окна.

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

Это следствие использования этой модели.Мы могли бы проделать всю эту работу вручную, чтобы все было в порядке, но философия дизайна заключалась в том, чтобы не изобретать заново Windows, а использовать ее там, где это возможно. Вот почему TButton или TEdit на самом деле на самом деле являются классом и стилем окна "User" BUTTON и EDIT соответственно.

По мере развития Windows эта модель «SDI» начала терять популярность. Фактически, сама Windows стала «враждебно относиться» к такому стилю приложений. Начиная с Windows Vista и до 7, пользовательская оболочка, похоже, плохо работает с приложением, использующим окно парковки. Итак, мы решили перетасовать вещи в VCL, чтобы убрать окно парковки и перенести его функцию в основную форму. Это вызвало несколько проблем типа «курица и яйцо», когда нам нужно, чтобы окно парковки было доступно достаточно рано при инициализации приложения, чтобы другие окна могли «присоединиться» к нему, но сама основная форма может быть построена недостаточно скоро. TApplication пришлось преодолеть несколько препятствий, чтобы заставить это работать, и было несколько тонких крайних случаев, которые вызывали проблемы, но большинство проблем уже решено. Однако для любого приложения, которое вы продвигаете вперед, оно будет по-прежнему использовать старую модель окна парковки.

50
ответ дан 26 November 2019 в 18:57
поделиться

Все VCL-приложения имеют "скрытое" окно верхнего уровня, называемое Приложением. Оно создается автоматически при запуске приложения. Среди прочего, это обработчик сообщений главных окон для VCL - отсюда и Application.ProcessMessages.

Скрытие окна верхнего уровня приложения вызывает некоторые странные вещи, например, неполное системное меню, которое отображается в панели задач, и некорректные эскизные окна в Vista. Более поздние версии Delphi исправляют это.

Однако не все окна должны иметь его в качестве родительского, Windows, как правило, работает лучше, если это так. Однако, любая форма, созданная с помощью Application.CreateForm, будет иметь ее в качестве родительской, а также будет принадлежать объекту Application. Так как они принадлежат, они будут освобождены после того, как Приложение будет освобождено. Это происходит за кулисами в Forms.DoneApplication

.
12
ответ дан 26 November 2019 в 18:57
поделиться

Из исходного кода в forms.pas (Delphi 2009) видно, что они создают «главное» окно в приложениях с графическим интерфейсом Win32, чтобы разрешить вызов

  • TApplication.Minimize
  • TApplication.Restore
  • и т. Д.

Похоже, что сообщения, переданные в Application.Handle , пересылаются соответствующим образом в MainForm , если это существует. Это позволит приложению реагировать на сворачивание и т. Д., Если главное окно не было создано. Изменив исходный код проекта, вы можете создать приложение delphi без главного окна.

В этом случае методы TApplication будут работать, даже если вы не создали главное окно. Не уверен, что я понимаю все цели, но у меня нет времени, чтобы пройти весь код TApplication.

По вашим вопросам:

  • Откуда это? Это дескриптор окна, созданного в TApplication.Создать

  • Что это за дескриптор окна? Поддельное окно, которое требуется каждому приложению gui delphi как часть абстракции TApplication

  • Это дескриптор окна главной формы приложения Нет

  • Если его не дескриптор основной формы приложения, тогда что это такое? См. выше

  • , что более важно: почему он является конечным родительским элементом каждой формы? если вы правы, что это конечный родительский элемент, я предполагаю, что он так потому, что это упрощает поиск всех форм в вашем приложении (перечисление дочерних элементов этой «основной» формы).

  • и самое главное: почему все идет наперекосяк, если я пытаюсь оставить форму без родительской , я думаю, потому что скрытая «основная» форма получает системные сообщения, которые она должна передать своим children и / или основную форму, но не может найти форму без родителей.

Во всяком случае, это мое мнение. Вы, вероятно, сможете узнать больше, просмотрев объявление и код TApplication в forms.pas . Суть в том, что я вижу, это удобная абстракция.

С уважением,

Дон

8
ответ дан 26 November 2019 в 18:57
поделиться
Другие вопросы по тегам:

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