Московский инженерно-физический институт

Вид материалаПрактикум

Содержание


Сообщение WMCOMMAND
Программное создание меню
Подобный материал:
1   ...   7   8   9   10   11   12   13   14   ...   24

Сообщение WMCOMMAND


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

wc.lpszMenuName="Main";

Для того же, чтобы программа отзывалась на выбор пользователем тех или иных пунктов меню, необходимо включить в оконную функцию обработку сообщения WMCOMMAND. Это сообщение поступает в приложение при выборе пользователем команды меню, причем второй по порядку параметр (id), передаваемый макросом HANDLEMSG в прикладную функцию OnCommand() обработки этого сообщения, соответствует идентификатору выбранной команды меню. Таким образом, алгоритм функции OnCommand() вполне очевиден – при поступлении идентификатора со значением MIBLUE закрасить главное окно приложения синим цветом, при поступлении MIGREEN – зеленым, если же id имеет значение MIEXIT – завершить приложение.

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

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

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

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

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

Программное создание меню


Как уже отмечалось, меню чаще всего описывается в файле ресурсов, так как в этом случае облегчается задача изменения его состава или поясняющих надписей. Однако в некоторых случаях может оказаться более удобным создать меню программно, без помощи файла ресурсов. Программное создание меню включает в себя следующие действия:
  • создание линейки меню приложения (пока пустой) функцией CreateMenu() с получением дескриптора этого меню;
  • создание всплывающего меню для помещения в него требуемого набора пунктов (но пока тоже пустого и даже без названия) функцией CreatePopupMenu() с получением дескриптора всплывающего меню;
  • заполнение всплывающего меню конкретными пунктами функцией AppendMenu(). В качестве второго параметра этой функции указывается константа MFSTRING (или MF­SE­PARATOR для разделительной линии), в качестве третьего – символическое обозначение идентификатора данного пункта меню, которое должно быть определено в файле .H, а в качестве последнего, четвертого параметра – адрес строки текста, представляющей собой название данного пункта меню (для разделительной линии этому параметру дается значение NULL);
  • включение всплывающего меню в линейку меню и задание его имени той же функцией AppendMenu(), в качестве второго параметра которой следует указать константу MF­POPUP, в качестве третьего – дескриптор всплывающего меню, преобразованный в тип UINT, а в качестве четвертого – адрес строки с названием всего всплывающего меню;
  • присоединение всего меню к главному окну приложения функцией SetMenu().

Все эти действия удобнее всего выполнить в функции OnCreate(); там же можно объявить символьные строки с названиями пунктов меню. На рис. 3.4 показано меню из программы 3-1 с комментариями, поясняющими использованную в этом разделе терминологию.



Рис. 3.4. Меню, созданное программно