Программирование для IBM OS/2© Александр Фролов, Григорий ФроловТом 4, М.: Диалог-МИФИ, 1993, 286 стр. 2.1. Иерархия окон и родственные связиВ предыдущей главе мы привели исходные тексты простейшего приложения Presentation Manager, создающего единственное окно. При этом мы сделали оговорку, что на самом деле при этом создается много окон и среди них, в частности, имеется окно Client Window , которое можно использовать для отображения какой-либо информации. Теперь мы рассмотрим иерархию и взаимосвязь окон Presentation Manager более детально. Родительские и дочерние окнаКаждое окно, создаваемое приложением, имеет родительское окно . При этом само оно по отношению к родительскому является дочерним. Родительское окно может иметь несколько дочерних окон, которые при этом называются окнами-братьями (или окнами-сестрами, если вам так больше нравится). Обратное неверно, т. е. у каждого дочернего окна может быть только одно родительское окно. На рис. 2.1 показана ситуация, когда одно родительское окно имеет три дочерних окна.
Рис. 2.1. Родительское и дочерние окна Каждое дочернее окно , в свою очередь, может выступать в роли родительского окна, создавая свои дочерние окна. Важной особенностью дочерних окон является то, что они всегда располагаются внутри своего родительского окна. Если пользователь попытается переместить дочернее окно за пределы родительского (например, при помощи мыши), будет нарисована только часть дочернего окна. В том случае, когда в одном родительском окне создано несколько дочерних окон, они могут перекрывать друг друга. Если пользователь перемещает родительское окно, то дочернее окно будет перемещаться вместе с ним. Когда пользователь изменяет размеры родительского окна, дочернее окно может отображаться не полностью. Если же пользователь минимизирует родительское окно, дочернее окно исчезает с поверхности экрана. При минимизации дочернего окна оно отображается в родительском окне в виде пиктограммы. При уничтожении родительского окна все его дочерние окна уничтожаются автоматически, поэтому вам не нужно об этом беспокоиться. Окно рабочего столаКакое окно является "основателем рода", т. е. родительским для всех остальных окон в Presentation Manager? Окна всех приложений располагаются в окне, представляющем собой поверхность рабочего стола Workplace Shell . Это окно, которое называется Desktop Window , создается автоматически при запуске операционной системы. Однако окно Desktop Window само по себе является дочерним по отношению к другому окну - окну Object Window . Это окно не отображается и используется системой Presentation Manager для собственных нужд. На рис. 2.2 показано, как соотносятся между собой окна Object Window , Desktop Window и окна Frame Window , создаваемые для каждого приложения.
Рис. 2.2. Взаимосвязь основных окон Presentation Manager Окно Desktop Window имеет идентификатор HWND_DESKTOP , который мы уже использовали в нашем первом приложении. Вы можете ссылаться на окно и другим способом, получив его идентификатор с помощью функции WinQueryObjectWindow , как это показано ниже: hwndDesktopWnd = WinQueryDesktopWindow(hab, NULL); На окно Object Window при необходимости можно ссылаться при помощи идентификатора HWND_OBJECT . Второй способ получения этого идентификатора основан на использовании функции WinQueryObjectWindow : hwndObjectWnd = WinQueryObjectWindow (HWND_DESKTOP); Окно Frame WindowКаждое приложение обычно создает окно Frame Window , которое всегда располагается на поверхности окна Desktop Window . При этом окно Desktop Window является родительским (Parent Window) для окна Frame Window. Соответственно, окно Frame Window по отношению к окну Desktop Window будет дочерним (Child Window). Когда вы создаете стандартное окно Frame Window , у
него обычно имеется несколько дочерних окон,
таких как системное меню, заголовок, окно Client Window
и т. д. Полный список этих окон вместе с их
идентификаторами приведен ниже.
Напомним, что при создании окна функцией WinCreateStdWindow при помощи флагов с префиксом имени FCF_ вы указываете, какие из перечисленных выше дочерних окон нужно создать. Если вам будет нужно определить идентификатор одного из перечисленных выше органов управления, вы можете воспользоваться функцией WinWindowFromID , передав ей в качестве первого параметра идентификатор окна Frame Window , а в качестве второго - идентификатор соответствующего дочернего окна, например: hwndMenu = WinWindowFromID (hwndFrameWindow, FID_MENU ); Функции для просмотра дерева оконВ составе программного интерфейса Presentation Manager имеются функции, позволяющие проследить "семейные отношения" между окнами. При помощи этих функций зная идентификатор дочернего окна, вы можете определить идентификатор родительского окна и наоборот, зная идентификатор родительского окна, определить идентификаторы всех его дочерних окон. Например, функция WinQueryWindow позволяет определить идентификатор родительского окна, если идентификатор дочернего окна передается ей в качестве первого параметра, а константа QW_PARENT - в качестве второго. С помощью функций WinBeginEnumWindows и WinGetNextWindow можно определить идентификаторы всех дочерних окон любого родительского окна. Более подробно мы рассмотрим функции, предназначенные для просмотра дерева окон позже, когда в этом возникнет необходимость. Отношения собственностиПомимо родственных связей, между окнами существуют отношения собственности. Одно окно может владеть другими. При этом окно-владелец получает извещающие сообщения от тех окон, которыми оно владеет. Как правило, дочернее окно является также и окном-владельцем. Подробнее об извещающих сообщениях мы расскажем в разделах, посвященных органам управления. Заметим только, что вы можете сменить владельца окна при помощи функции WinSetOwner : BOOL WinSetParent( HWND hwnd, // идентификатор окна HWND hwndNewParent, // новое родительское окно BOOL fRedraw); // флаг перерисовки Эта функция устанавливает для окна с идентификатором hwnd новое родительское окно hwndNewParent. Если при этом значение флага fRedraw будет равно TRUE, выполняется перерисовка окна, если FALSE - перерисовка окна не выполняется. Удочерение окнаПри необходимости вы можете назначить для дочернего окна нового родителя, вызвав функцию WinSetParent . |