Win32 Window Owner vs Window Parent?

В чем разница между родителем окна и владельцем окна в программировании Win32? Я думал, что разобрался, потом наткнулся на этот код:

SetWindowLong(handle, GWL_HWNDPARENT, foo);

Это фактически устанавливает владельца окна, а не родителя - несмотря на то, что используется GWL_HWNDPARENT. Взаимозаменяемы ли термины «родитель / владелец», или есть разница?


person Jon Tackabury    schedule 03.02.2009    source источник
comment
Подробное объяснение на msdn   -  person Danra    schedule 01.07.2010
comment
Раймонд Чен написал статью о Окно может иметь родитель или владелец, но не оба вместе.   -  person Uli Gerhardt    schedule 16.03.2011
comment
Обновленный URL-адрес статьи Рэймонда Чена: devblogs.microsoft.com/oldnewthing/20100315- 00 /? P = 14613   -  person Darrin Cullop    schedule 06.05.2020
comment
Пожалуйста, отмените принятый ответ. Это неверно.   -  person IInspectable    schedule 27.01.2021


Ответы (4)


Владелец - это окно *, отвечающее за элемент управления или диалоговое окно (например, отвечающее за создание / уничтожение окна).

Родительское окно является следующим по старшинству окном * для элемента управления или диалогового окна в цепочке окон, но фактически не несет за него ответственности (не обязательно заботится о его жизненном цикле и т. Д.). Родитель окна также может быть его владельцем.

* Окно против окна: Окно - это фактическое окно, отображаемое на экране; window - это любой объект с HWND (включая кнопки, панели и т. д.).

person TheSmurf    schedule 03.02.2009
comment
Спасибо также за подсказку "окно против окна" - иногда эти вещи немного сбивают с толку, когда вы пытаетесь обсудить с другими людьми. - person Jon Tackabury; 03.02.2009
comment
Это не так. Окно может иметь родителя или владельца, но не обоих одновременно. - person Raymond Chen; 02.10.2011
comment
Раймонд, я думаю, что отчасти путаница заключается в том, что Spy ++ и GetAncestor (GA_PARENT) возвращают «следующее окно на один уровень выше в дереве HWND» даже для HWND верхнего уровня, так что в разговорной речи у них есть «родитель», даже если это не отслеживается таким образом внутри компании. Есть два основных способа взглянуть на дерево HWND; наивное представление `` единое дерево с корнями на рабочем столе '', которое вы видите в Spy ++ / GetAncestor / EnumChildWindows / GetWindow (GA_FIRST / NEXT), а затем есть представление `` внутренне ориентированное '', где каждый HWND имеет один слот, который либо родитель, либо владелец, в зависимости от на WS_CHILD. - person BrendanMcK; 02.10.2011
comment
да. К сожалению, люди склонны небрежно использовать терминологию, что только усугубляет путаницу. (А внутри на самом деле есть два слота, но дизайн API продуман и представляет их как один параметр, который выбирает между двумя слотами в зависимости от контекста.) - person Raymond Chen; 02.10.2011

Владение - это связь между двумя окнами верхнего уровня, в то время как Родитель - это связь между верхним уровнем и WS_CHILD или WS_CHILD и другим WS_CHILD.

Родителем кнопки является форма, в которой она находится, а окно сообщения принадлежит форме, которая его показывала.

Прочтите эту статью Win32 Window Hierarchy and Styles, чтобы получить более четкое представление понимание Владения, Родительства, ZOrder, SetWindowLong, GetWindow и всех других неприятных моментов API Win32 для создания взаимосвязей между окнами.

РЕДАКТИРОВАТЬ: похоже, что Microsoft удалила этот контент, вот еще один разумный сводка о правах собственности / воспитании.

person Maurice Flanagan    schedule 05.03.2009
comment
Ба, MS удалила это содержание. :( - person Dave Markle; 02.01.2011

Сообщение в блоге Чена стоит прочитать. Ключевым моментом для меня является то, что стиль WS_CHILD должен использоваться в дочернем окне. Вы можете попытаться создать дочернее окно и передать родительский дескриптор в CreateWindow (), но если у вас не установлен стиль WS_CHILD, два окна будут иметь отношения владельца, а не отношения родитель / потомок.

person osullivj    schedule 18.01.2015

Это супер просто: неверный код. Конец истории прямо здесь.

Да, некоторые окна могут положительно отреагировать на такой вызов - кто-то, не знающий ничего лучше, возможно, реализовал поддержку для него. Приведенная документация (и это старая документация) - Вы не должны вызывать SetWindowLong с индексом GWL_HWNDPARENT для изменения родителя дочернего окна. Вместо этого используйте функцию SetParent.

Итак, все, что нужно сделать: вы нашли код с ошибками, изменили его на SetParent или провели рефакторинг, чтобы сделать что-то еще, и продолжаете?

person Kuba hasn't forgotten Monica    schedule 30.06.2020