ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



 

Часть 15

Глава 13. Объекты MDI
Интерфейс нескольких документов (MDI) это стандарт интерфейса для приложений Windows, которые позволяют пользователю одновременно работать с несколькими открытыми документами. Документ, в этом смысле, это обычно связанная с файлом задача, например, редак
тирование текстового файла или работа с файлом электронной таблицы. В приложениях MDI пользователь может, например, иметь несколько открытых файлов в одном приложении. Возможно, что вы уже использовали приложения MDI: Microsoft Exsel, Менеджер программ W
indows, Менеджер файлов Windows. Стандарт MDI является также частью спецификации Общего Доступа Пользователя фирмы IBM.
Компоненты приложения MDI
Имеются определенные компоненты, которые присутствуют в каждом приложении MDI. Чаще всего головное окно вызывает окно-рамку. В области клиента окна-рамки есть невидимое окно, окно клиента MDI, которое содержит дочернее окно, вызывающее дочерние окна MDI.
 Это очень важно, т.к. обработка дочерних окон MDI происходит скрытно от пользователя.
Рис.13.1. Компоненты примера приложения MDI
Окно-рамка также имеет меню, часто окно с меткой, которое контролирует дочерние окна MDI своими элементами: Title, Cascade, Arrange и Close All. Мы будем называть это меню "меню дочерних окон". Каждое открытое дочернее окно MDI автоматически добавляется 
в конец этого меню. В этом меню отмечено текущее выбранное окно.
Каждое дочернее окно MDI имеет некоторые характеристики перекрытого окна. Его можно максимизировать до полного размера окна клиента MDI или минимизировать до пиктограммы, которая помещается к нижней границе окна-рамки. Дочернее окно MDI никогда не выходи
т за границы ее окна-рамки. Дочернее окно MDI не может иметь меню, поэтому все ее функции реализуются меню окна-рамки. Заголовок каждого дочернего окна MDI часто есть имя открытого файла, связанного с этим окном, хотя его поведение заранее неизвестно и о
пределяется управлением программы. Можно рассматривать приложение MDI как мини-сеанс Windows, когда несколько приложений представлены окнами или пиктограммами.
Каждое окно MDI является объектом
ObjectWindows определяет типы для представления окон рамок и клиентов MDI. Это соответственно TMDIWindow и TMDIClient. TMDIWindow происходит от TWindow, но TMDIClient есть управление и происходит от TControl. В приложении MDI ObjectWindows, окно-рамка вл
адеет своим окном клиента MDI и хранит его в поле ClientWnd. Окно-рамка также содержит каждое из его дочерних окон MDI в его связанном списке ChildList. Дочерние окна MDI являются экземплярами типа объекта, происходящего от написанного вами TWindow.
Методы TMDIWindow занимаются в основном конструированием и управлением дочерних окон MDI, окном клиента MDI и обработкой выборов меню. Главная работа TMDIClient происходит скрытно от пользователя и состоит в управлении дочерними окнами MDI. При разработк
е приложений MDI вы в общем случае будете производить новые типы для ваших рамок и дочерних окон соответственно от TMDIWindow и TWindow.
Конструирование окон MDI
Имеется ряд специальных вопросов конструирования окон приложения MDI. Полное описание конструирования окон содержится в Главе 10, "Объекты окна".
Конструирование окон-рамок MDI
Окно-рамка приложения MDI также является головным окном, поэтому оно конструируется в методе InitMainWindow его типа приложения. Однако, в отличие от TWindow, конструктор Init в TMDIWindow не берет родительского окна (окно-рамка, будучи головным окном, н
е имеет родительского окна), но берет один дополнительный параметр, регулятор меню. Когда вы имели дело с головными окнами не MDI, производными от TWindow, вы определяли Init для установки Attr.Menu на имеющийся регулятор меню. Однако, для окон-рамок MDI
 нужно иметь меню, поэтому TMDIWindow.Init требует аргумента меню и устанавливает Attr.Menu для вас.
Меню окна-рамки должно включать включать меню дочернего окна стиля MDI. Это будет меню, в которое будет добавляться заголовок дочернего окна MDI во время работы приложения. Окно-рамка должно знать, какой элемент меню верхнего уровня есть меню его дочерне
го окна. Объект TMDIWindow хранит целое значение позиции в поле объекта ChildMenuPos. TMDIWindow.Init первоначально устанавливает ChildMennuPos в ноль, указывая крайний левый элемент меню верхнего уровня. Однако, вы можете переопределить Init для вашего 
производного от TMDIWindow типа для установки позиции ChildMenuPos:
constructor MyMDIWindow.Init(ATitle: PChar; AMenu: HMenu);
begin
 TMDIWindow.Init(ATitle, AMenu);
 ChildMenuPos:=1;
end;
TMDIWindow.Init также вызывает InitClientWindow для конструирования объекта TMDIClient, который будет служит его окном клиента MDI. TMDIWindow.SetupWindow создает окно клиента MDI.
Конструирование дочерних окон MDI
TMDIWindow определяет автоматический метод реакции CreateChild, который вызывается при выборе из меню варианта, результатом которого будет команда с ID Create_Child. Обычно этот вариант меню называется New или Create. Как это определено в TMDIWindow, Cre
ateChild конструирует и создает дочернее окно MDI типа TWindow вызовом TMDIWindow.InitChild. Для задания корректного типа дочернего окна (производного от TWindow), переопределим InitChild для вашего типа окна-рамки MDI:
function MyMDIWindow.InitChild: PWindowsObject;
begin
 InitChild:=New(PMyChild, Init(@Self, 'New Child Window'));
end;
Однако, может потребоваться, чтобы ваша окно-рамка воспроизводило только одно дочернее окно MDI при своем первом появлении. Для этого первого дочернего окна вы можете явно задать его размер. В отличие от других дочерних окон, дочерние окна MDI должны быт
ь сконструированы и созданы в методе SetupWindow окна-рамки MDI, а не в Init. Вы также должны явно создать дочернее окно:
procedure MyMDIWindow.SetupWindow;
var
 ARect: TRect;
 NewChild: PMyChild;
begin
 TMDIWindow.SetupWindow;
 NewChild:=PMyChild(InitChild);
 GetClientRect(HWindow, ARect);
 with NewChild^.Attr, ARect do
 begin
  W:=(right*4) div 5;
  H:=(bottom*3) div 5;
  Title:='Child #1';
 end;
 Application^.MakeWindow(NewChild);
end;
В некоторых приложениях вам может потребоваться создать дочернее окно MDI в ответ на более чем один выбор в меню. Например, варианты меню New и Open в редакторе файла могут приводить к возникновению нового дочернего окна с заголовком в виде имени файла.
Обработка сообщений в приложении MDI
Как и для обычных родительских и дочерних окон, основанные на командах и дочерних ID сообщения Windows сначала поступают в дочерние окна для их восприятия и обработки. Затем сообщения поступают в родительское окно. Однако, в случае приложения MDI сообщен
ия поступают к текущему дочернему окну MDI, затем к окну клиента MDI, и, наконец, к окну-рамке MDI (которое является родительским окном для всех дочерних окон MDI). Следовательно, меню окна-рамки можно использовать для управления работой в текущем активн
ом дочернем окне MDI. Затем шанс отреагировать получают окно клиента и окно-рамка.
Управление дочерним окном MDI
Тип окна MDI в ObjectWindows содержит методы манипулирования дочерними окнами MDI приложения MDI. Хотя большая часть скрытой работы делается и TMDIClient, доступ к данным и функциям происходит через метод TMDIWindow.
Активизация дочернего окна
Пользователь приложения MDI может свободно активизировать любое открытое или минимизировать дочернее окно MDI. Однако, вам может потребоваться предпринять некоторые действия, когда пользователь дезактивирует одно дочернее окно активизацией другого. Напри
мер, меню окна-рамки может отражать текущее состояние активного дочернего окна, выделяя его цветом. Каждый раз, когда дочернее окно становится активным или неактивным, оно получает сообщение Windows wm_MDIActivate. Определив метод реакции на это сообщени
е для дочернего окна, вы можете отслеживать, какое дочернее окно активно и соответственно реагировать.
Меню дочернего окна
TMDIWindow определяет методы реакции на сообщения Windows, которые автоматически реагируют на выбор варианта стандартного меню MDI: Title, Cascade, Arrange Icon и Close All. Эти методы ожидают основанных на командах сообщений с заранее определенными конс
тантами ID меню. Обязательно используйте эти ID при построении ресурса меню дочернего окна:
     Таблица 13.1. Стандартные методы, команды и действия MDI
----------------------------------------------------------------
Действие       Константа ID меню        Метод TMDIWindow
----------------------------------------------------------------
Tile           cm_TileChildren          CM_TileChildren          
Cascade        cm_CascadeChildren       CM_CascadeChildren
Arrange Icons  cm_ArrangeChildIcons     CM_ArrangeChildIcons
Close All      cm_CloseChildren         CM_CloseChildren    
----------------------------------------------------------------
Методы реакции TMDIWindows, подобные CMTileChildren, вызывают другие методы TMDIWindows, подобные CMChildren. Эти методы вызывают методы TMDIClient с тем же именем, например, TMDIClient^.TileChildren. Для переопределения любого из этих автоматических хар
актеров поведения нужно переписать TMDIWindow.TileChildren или другой метод TMDIWindow. Для дочерних окон MDI не подходит реагировать на основанные на командах сообщения, генерируемые меню дочернего окна. 
Пример приложения MDI
Программа MDITest создает приложение MDI, показанное на Рис.13.1.
Полный текст файла MDITEST.PAS содержится на ваших дистрибутивных дискетах.



Яндекс цитирования