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



 

Часть 5

Глава 4. Добавление меню
Большинство приложений Windows имеют в своем головном окне меню для предоставления пользователю выбора одного из нескольких вариантов действий, например File|Save (сохранение файла), File|Open (открытие файла) и Help (подсказка). В данном разделе вы доба
вите стандартное меню к MyProgram.
В среде работы с окнами выбор варианта из меню относится к той же категории, что и нажатие кнопки на мыши: оба эти случая относятся к событиям, инициируемым пользователем. Реакция на выбор варианта из меню будет аналогична реакциям на другие события. В д
анном разделе рассматриваются все этапы, которые нужно пройти для реализации мен в приложении:
1. Разработать меню, как ресурс меню.
2. Загрузить ресурс меню в объект головного окна.
3. Определить реакции на выбор вариантов из меню.
4. Задать файл ресурса в программе.
Ресурсы меню
В некотором месте приложения с меню должна находиться его спецификация, содержащая текст вариантов меню и структуру элементов верхнего уровня и их подэлементов. Это имеет место для всех приложений ObjectWindows, но данная спецификация не является частью 
исходного кода программы на языке Pascal. Она является частью отдельной спецификации, называемой ресурсом. Windows хранит ресурсы компактным и эффективным способом. Вы будете использовать Инструментальные Средства Ресурсов для диалоговой разработки меню 
и других ресурсов, таких, как блоки диалога, пиктограммы и побитовые распределения памяти.
Приложение получает доступ к присоединенным к нему ресурсам через задание ID ресурса. ID является целым числом, например 100, или целой константой, например MyMenu. Приложение различает выбор одного меню от другого по ID меню, связанным с каждым элементо
м меню.
Для продолжения работы с MyProgram нужно использовать редактор ресурса или компилятор ресурса для создания ресурса и записи его в файл COOKBOOK.RES . Исходный формат для файла ресурса содержится в файле COOKBOOK.RC . Можно также воспользоваться файлом CO
OKBOOK.RES, имеющемся на дистрибутивных дисках. Как только файл .RES создан, следует его использовать с помощью директивы компилятора $R :
     {$R COOKBOOK.RES}
На Рис.4.1 показано появление этого меню (ID ресурса 100), включая Help (ID меню 901) и выбор файла. Последний имеет подэлементы меню New, Open, Save и SaveAs (ID меню 101, 102, 103 и 104 соответственно). Меню верхнего уровня, которое имеет подэлементы, 
как например File, не имеют собственного ID. Их выбор не вызывает никаких действий, кроме появления их подэлементов. Если элемент верхнего уровня не имеет подэлементов, как например Help, то он имеет ID меню и его выбор может вызвать некоторые действия.
Рис.4.1. MyProgram с ресурсом меню
Меню разрабатывается вне программы ObjectWindows и работа с ним очень проста, поэтому нет необходимости делать из меню объект. Вместо этого сделаем его атрибутом головного окна, аналогичным его заголовку. На следующем шаге меню будет присоединено к голов
ному окну.
Шаг 7: Меню для головного окна
Как это было заявлено ранее, меню приложения не есть отдельный объект, которым владеет головное окно. Это вообще не объект, а атрибут головного окна. Оно и хранится в поле Menu в Attr, поле объекта окна, которое хранит запись атрибутов создания окна. Для
 установки атрибута меню, кроме всего прочего, нужно переопределить конструктор Init для вашего типа окна TMyWindow.
Хранимый в COOKBOOK.RES ресурс меню имеет ID 100. Получим этот ресурс вызовом функции Windows LoadMenu:
          LoadMenu(HInstance, PChar(100));
PChar(100) преобразует число 100 в строковый тип с именем PChar, который является указателем на массив символов. Функции Windows, которые принимают строки в качестве аргументов, требуют от них типа PChar. Для получения доступа к PChar, должна быть устано
влена директива компилятора $X+ (что является установкой по умолчанию).
В качестве альтернативы ресурс меню может иметь символьный идентификатор, например 'SAMPLE_MENU'. В данном случае ресурс меню загружается следующим образом:
          LoadMenu (HInstance, 'SAMPLE_MENU');
Вот как должен выглядеть TMyWindow.Init . Обратите внимание на то, что в самом начале вызывается TWindow.Init для выполнения инициализации, которая требуется для всех объектов окна:
constructor TMyWindow.Init(AParent: PWindowsObject; ATitle: PChar);
begin
 TWindow.Init(AParent, ATitle);
 Attr.Menu:=LoadMenu(HInstance, PCahr(100));
 ButtonDown:=False;
 PenSize:=1;
 ThePen:=CreatePen(ps_Solid, PenSize, 0);
 Points:=New(PCollection, Init(50, 50));
end;
Теперь при выводе на экран головного окна, оно будет иметь  операционное меню, как это показано на Рис.4.1. Для того, чтобы теперь за вызовом разделов меню стояли бы какие-нибудь действия, нужно закончить этапы перехвата и реакции на сообщения меню.
Перехват сообщения меню
Когда пользователь делает выбор из меню то окно, в котором это меню показано, принимает командное сообщение Windows. Для обработки одного из этих сообщений определим метод для типа объекта TMyWindow, использующий специальное расширение:
procedure FileNew(var Msg: TMessage); virtual cm_First + 101;
где cm_First есть определенная в ObjectWindows константа, задающая начала диапазона констант для команд, а 101 это требуемый ID меню. Не следует путать этот индекс динамического метода, основанный на cm_First, с реакцией на сообщения Windows, которая осн
ована на смещении wm_First. Этот специальный случай имеет место только для меню и акселераторов. 
Диапазоны сообщений и смещения более подробно рассмотрены в Главе 7.
Чтобы улучшить восприятие кода, заменим ID меню на константы, которые вы определяете в начале программы:
          const
               cm_New = 101;
               cm_Open = 102;
               cm_Save = 103;
               cm_SaveAs = 104;
               cm_Help = 901;
Теперь вы можете определить все методы реакции на командные сообщения:
procedure FileNew(var Msg: TMessage); virtual cm_First+cm_New;
procedure FileOpen(var Msg: TMessage); virtual cm_First+cm_Open;
procedure FileSave(var Msg: TMessage); virtual cm_First+cm_Save;
procedure FileSaveAs(var Msg: TMessage); virtual cm_First + 
     cm_SaveAs;
procedure Have(var Msg: TMessage); virtual cm_First + cm_Help;
Реакция на сообщение меню
У нас теперь есть метод, который будет вызываться при выборе любого варианта из меню. Например, в случае выбора Help, будет вызываться ваш метод Help. Например, будет выводиться блок сообщения:
procedure TMyWindow.Help(var Msg: TMessage);
begin
 MessageBox(HWindow, 'Feature not implemented.', 'Help', mb_OK);
end;
На Рис.4.2 показана реакция MyProgram на выбор Help.
Рис.4.2. MyProgram с системой Help
В данный момент можно отреагировать на выбор варианта File|New из меню достаточно интересно, очистив экран. Добавим следующий метод FileNew:
procedure TMyWindow.FileNew(var Msg: TMessage);
begin
 Points^.FreeAll;
 InvalidateRect(HWindow, nil, True);
end;
Этот метод удаляет все записанные точки и форсирует перерисовку экрана. Поскольку в данном случае точек для перерисовки нет, экран становится пустым.
Для FileOpen, FileSave и FileSaveAs напишем пока временные методы-заглушки, аналогичные Help. Позднее мы перепишем эти методы таким образом, чтобы они выполняли полезные действия.
Полный исходный код для MyProgram на данном этапе ее разработки находится в файле STEP7.PAS .
Присоединение ресурсов к исполняемому файлу
После компиляции вашей программы ObjectWindows, но до ее запуска,нужно присоединить ресурсы меню. С использованием директивы компилятора $R это делается автоматически в конце компиляции и компоновки. Заданный в директиве файл ресурса добавляется в конец 
скомпилированного исполняемого файла.
Ресурсы могут быть добавлены или удалены из существующих исполняемых файлов, и существующие ресурсы могут быть модифицированы. Информация о том, как это сделать, содержится в "Инструментальные средства работы с ресурсами Whitewater".


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