Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный практикум «Основы разработки приложений Windows» книга 1.DOC
Скачиваний:
117
Добавлен:
10.05.2014
Размер:
721.41 Кб
Скачать

Описание меню в файле ресурсов

Состав, или сценарий меню описывается с помощью соответствующих ключевых слов и предложений языка описания ресурсов. Сценарий меню начинается с ключевого слова MENU, которое может быть написано как прописными, так и строчными буквами, и за которым следует перечень элементов линейки меню, заключенный в“операторные скобки”– операторыBEGINиEND– или просто в фигурные скобки{...}. Ключевое словоMENUпредваряется произвольным именем (у нас это имяMain), которое выступает как идентификатор всей линейки меню и будет использовано далее в тексте программы.

Каждый элемент перечня начинается с ключевого слова POPUP, за которым следует название этого элемента. Обычно элементы линейки меню называют просто меню. Если в программе предусмотрено, как это обычно и делается, управление меню не только мышью, но и клавиатурой (нажатием комбинаций клавиш Alt+буква), то“горячую”букву имени элемента меню следует предварить знаком амперсанта (&). В нашей программе линейка меню имеет единственное меню"Фон"; управление меню от клавиатуры в программе не предусмотрено.

Вслед за предложением POPUPследует перечень пунктов, или команд этого меню, который появится на экране при открывании меню. Перечень заключается в операторные скобки{...}. Каждый пункт начинается ключевым словомMENUITEM, за которым указывается название данной команды и ее идентификатор. Идентификаторы обычно имеют символическую форму. У нас это обозначенияMIBLUE, MIGREENиMIEXIT, которым с помощью директивы препроцессора#define были присвоены произвольные значения 100, 101 и 102. В дальнейшем при выборе той или иной команды меню система Windows передаст в приложение в сообщенииWMCOMMANDидентификатор выбранной команды, что позволит программе определить, какая именно команда (пункт меню) была выбрана пользователем.

Заметьте, что идентификатор (в виде имени Main) имеет также вся линейка меню, в то время как элементы меню (в нашем случае меню"Фон") идентификатора не имеют. Это происходит потому, что элементы меню обслуживаются системой Windows, а не прикладной программой. Мы не выполняем никаких действий при щелчке мышью по элементу"Фон"; система сама открывает его меню. Команды же меню обслуживаются приложением, и, чтобы их можно было различить, им присваиваются идентификаторы.

Предложение

MENUITEM SEPARATOR

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

Сообщение wmcommand

Для того,чтобы меню, описанное в файле ресурсов, появилось в главном окне приложения, достаточно при регистрации класса окна заполнить в структурной переменной типаWNDCLASS элементwc.lpszMenuName:

wc.lpszMenuName="Main";

Для того же, чтобы программа отзывалась на выбор пользователем тех или иных пунктов меню, необходимо включить в оконную функцию обработку сообщения WMCOMMAND. Это сообщение поступает в приложение при выборе пользователем команды меню, причем второй по порядку параметр (id), передаваемый макросомHANDLEMSGв прикладную функциюOnCommand() обработки этого сообщения, соответствует идентификатору выбранной команды меню. Таким образом, алгоритм функцииOnCommand()вполне очевиден – при поступлении идентификатора со значениемMIBLUEзакрасить главное окно приложения синим цветом, при поступленииMIGREEN – зеленым, если жеid имеет значениеMIEXIT– завершить приложение.

Для завершения приложения достаточно вызвать функцию Des­troyWindow(), в качестве параметра которой следует указать дескриптор главного окна, полученный как аргумент функцииOnCommand(). ФункцияDestroyWindow()уничтожает окно и посылает в приложение сообщениеWMDESTROY, что приводит к завершению приложения.

С перекраской фона окна дело обстоит сложнее. Как уже говорилось, рисовать что-либо в окне, в частности, перекрашивать его фон, можно только в функции OnPaint(), вызываемой в ответ на приход в приложение сообщенияWMPAINT. Лишь в этом случае при затирании окна изображение в нем будет восстанавливаться. Однако при выборе того или иного пункта меню мы попадаем не в функциюOnPaint(), а в функциюOnCommand(). Для передачи в функциюOnPaint() информации о выбранном пункте меню и, соответственно, цвете фона, можно использовать переключатель в виде глобальной переменной (в нашем случаеsw), которой в функцииOnCommand() присваивается, в зависимости от выбранного пункта меню, то или иное значение (у нас 1 или 2). В функции жеOnPaint()это значение анализируется операторомif (или конструкциейswitch-case) и выполняются необходимые действия по перекраске фона.

Однако выбор пункта меню не приведет к посылке в приложение сообщения WMPAINT. Получится, что переключательsw мы установим, но изображение в окне не изменится. Для того, чтобы после установки переключателя заставить Windows перекрасить окно, следует воспользоваться специальной функцией Windows Inva­lidateRect(), которая объявляет окно (или задаваемую часть окна) затертым. Windows, получив информацию о затирании окна, немедленно посылает в приложение сообщениеWMPAINT, что приводит к вызову функцииOnPaint() и действительному перерисовыванию содержимого окна.

Через второй параметр функции InvalidateRect() передаются координаты той области окна, которую мы желаем перерисовать. Поскольку в данном случае требуется перерисовать все окно, в качестве второго параметра указываетсяNULL.Третий параметр функцииInvalidateRect() задает режим стирания предыдущего изображения. Если значение этого параметра равноTRUE, старое изображение стирается, еслиFALSE – остается. В случае перерисовки фона окна значение этого параметра не отражается на результате, однако при управлении посредством меню вывода в окно тех или иных фигур (например, различных графиков) старое изображение, как правило, следует стирать, т. е. в качестве третьего параметра функцииInvalidateRect() указывать TRUE.

Перекраска фона окна осуществляется посредством вызова функции Windows FillRect(). В качестве второго параметра этой функции следует передать информацию о координатах закрашиваемого прямоугольника. Эту информацию (в виде адреса структуры типаRECT) можно извлечь из структурной переменнойps, заполняемой функциейBeginPaint().