- •Содержание
- •Глава 1 README.TXT
- •Вызов, брошенный программистам
- •Основные правила
- •Краткая история Windows
- •Краткая история этой книги
- •Начнем
- •Глава 2 Hello, Windows 95
- •Отличительная особенность Windows
- •Графический интерфейс пользователя
- •Концепции и обоснование GUI
- •Содержимое интерфейса пользователя
- •Преимущество многозадачности
- •Управление памятью
- •Независимость графического интерфейса от оборудования
- •Соглашения операционной системы Windows
- •Вызовы функций
- •Объектно-ориентированное программирование
- •Архитектура, управляемая событиями
- •Оконная процедура
- •Ваша первая программа для Windows
- •Что в этой программе неправильно?
- •Файлы HELLOWIN
- •Make-файл
- •Вызовы функций Windows
- •Идентификаторы, написанные прописными буквами
- •Новые типы данных
- •Описатели
- •Венгерская нотация
- •Точка входа программы
- •Регистрация класса окна
- •Создание окна
- •Отображение окна
- •Цикл обработки сообщений
- •Оконная процедура
- •Обработка сообщений
- •Воспроизведение звукового файла
- •Сообщение WM_PAINT
- •Сообщение WM_DESTROY
- •Сложности программирования для Windows
- •Не вызывай меня, я вызову тебя
- •Синхронные и асинхронные сообщения
- •Думайте о ближнем
- •Кривая обучения
- •Глава 3 Рисование текста
- •Рисование и обновление
- •Сообщение WM_PAINT
- •Действительные и недействительные прямоугольники
- •Введение в графический интерфейс устройства (GDI)
- •Контекст устройства
- •Структура информации о рисовании
- •Получение описателя контекста устройства. Второй метод
- •Функция TextOut. Подробности
- •Системный шрифт
- •Размер символа
- •Метрические параметры текста. Подробности
- •Форматирование текста
- •Соединим все вместе
- •Не хватает места!
- •Размер рабочей области
- •Полосы прокрутки
- •Диапазон и положение полос прокрутки
- •Сообщения полос прокрутки
- •Прокрутка в программе SYSMETS
- •Структурирование вашей программы для рисования
- •Создание улучшенной прокрутки
- •Мне не нравится пользоваться мышью
- •Глава 4 Главное о графике
- •Концепция GDI
- •Структура GDI
- •Типы функций
- •Примитивы GDI
- •Другие аспекты
- •Контекст устройства
- •Получение описателя контекста устройства
- •Программа DEVCAPS1
- •Размер устройства
- •О цветах
- •Атрибуты контекста устройства
- •Сохранение контекста устройства
- •Рисование отрезков
- •Ограничивающий прямоугольник
- •Сплайны Безье
- •Использование стандартных перьев
- •Создание, выбор и удаление перьев
- •Закрашивание пустот
- •Режимы рисования
- •Рисование закрашенных областей
- •Функция Polygon и режим закрашивания многоугольника
- •Закрашивание внутренней области
- •Режим отображения
- •Координаты устройства (физические координаты) и логические координаты
- •Системы координат устройства
- •Область вывода и окно
- •Работа в режиме MM_TEXT
- •Метрические режимы отображения
- •Ваши собственные режимы отображения
- •Программа WHATSIZE
- •Прямоугольники, регионы и отсечение
- •Работа с прямоугольниками
- •Случайные прямоугольники
- •Создание и рисование регионов
- •Отсечения: прямоугольники и регионы
- •Программа CLOVER
- •Пути
- •Создание и воспроизведение путей
- •Расширенные перья
- •Bits and Blts
- •Цвета и битовые образы
- •Файл DIB
- •Упакованный формат хранения DIB
- •Отображение DIB
- •Преобразование DIB в объекты "битовые образы"
- •Битовый образ — объект GDI
- •Создание битовых образов в программе
- •Формат монохромного битового образа
- •Формат цветного битового образа
- •Контекст памяти
- •Мощная функция BitBlt
- •Перенос битов с помощью функции BitBlt
- •Функция DrawBitmap
- •Использование других ROP кодов
- •Дополнительные сведения о контексте памяти
- •Растяжение битовых образов с помощью функции StretchBlt
- •Кисти и битовые образы
- •Метафайлы
- •Простое использование метафайлов памяти
- •Сохранение метафайлов на диске
- •Расширенные метафайлы
- •Делаем это лучше
- •Базовая процедура
- •Заглянем внутрь
- •Вывод точных изображений
- •Текст и шрифты
- •Вывод простого текста
- •Атрибуты контекста устройства и текст
- •Использование стандартных шрифтов
- •Типы шрифтов
- •Шрифты TrueType
- •Система EZFONT
- •Внутренняя работа
- •Форматирование простого текста
- •Работа с абзацами
- •Глава 5 Клавиатура
- •Клавиатура. Основные понятия
- •Игнорирование клавиатуры
- •Фокус ввода
- •Аппаратные и символьные сообщения
- •Аппаратные сообщения
- •Системные и несистемные аппаратные сообщения клавиатуры
- •Переменная lParam
- •Виртуальные коды клавиш
- •Использование сообщений клавиатуры
- •Модернизация SYSMETS: добавление интерфейса клавиатуры
- •Логика обработки сообщений WM_KEYDOWN
- •Посылка асинхронных сообщений
- •Символьные сообщения
- •Сообщения WM_CHAR
- •Сообщения немых символов
- •Каретка (не курсор)
- •Функции работы с кареткой
- •Программа TYPER
- •Наборы символов Windows
- •Набор символов OEM
- •Набор символов ANSI
- •Наборы символов OEM, ANSI и шрифты
- •Международные интересы
- •Работа с набором символов
- •Связь с MS-DOS
- •Использование цифровой клавиатуры
- •Решение проблемы с использованием системы UNICODE в Windows NT
- •Глава 6 Мышь
- •Базовые знания о мыши
- •Несколько кратких определений
- •Сообщения мыши, связанные с рабочей областью окна
- •Простой пример обработки сообщений мыши
- •Обработка клавиш <Shift>
- •Сообщения мыши нерабочей области
- •Сообщение теста попадания
- •Сообщения порождают сообщения
- •Тестирование попадания в ваших программах
- •Гипотетический пример
- •Пример программы
- •Эмуляция мыши с помощью клавиатуры
- •Добавление интерфейса клавиатуры к программе CHECKER
- •Использование дочерних окон для тестирования попадания
- •Дочерние окна в программе CHECKER
- •Захват мыши
- •Рисование прямоугольника
- •Решение проблемы — захват
- •Программа BLOKOUT2
- •Глава 7 Таймер
- •Основы использования таймера
- •Система и таймер
- •Таймерные сообщения не являются асинхронными
- •Использование таймера: три способа
- •Первый способ
- •Второй способ
- •Третий способ
- •Использование таймера для часов
- •Позиционирование и изменение размеров всплывающего окна
- •Получение даты и времени
- •Обеспечение международной поддержки
- •Создание аналоговых часов
- •Стандартное время Windows
- •Анимация
- •Класс кнопок
- •Создание дочерних окон
- •Сообщения дочерних окон родительскому окну
- •Сообщения родительского окна дочерним окнам
- •Нажимаемые кнопки
- •Флажки
- •Переключатели
- •Окна группы
- •Изменение текста кнопки
- •Видимые и доступные кнопки
- •Кнопки и фокус ввода
- •Дочерние окна управления и цвета
- •Системные цвета
- •Цвета кнопок
- •Сообщение WM_CTLCOLORBTN
- •Кнопки, определяемые пользователем
- •Класс статических дочерних окон
- •Класс полос прокрутки
- •Программа COLORS1
- •Интерфейс клавиатуры, поддерживаемый автоматически
- •Введение новой оконной процедуры
- •Закрашивание фона
- •Окрашивание полос прокрутки и статического текста
- •Класс редактирования
- •Стили класса редактирования
- •Коды уведомления управляющих окон редактирования
- •Использование управляющих окон редактирования
- •Сообщения управляющему окну редактирования
- •Класс окна списка
- •Стили окна списка
- •Добавление строк в окно списка
- •Выбор и извлечение элементов списка
- •Получение сообщений от окон списка
- •Простое приложение, использующее окно списка
- •Список файлов
- •Утилита Head для Windows
- •Компиляция ресурсов
- •Значки и курсоры
- •Редактор изображений
- •Получение описателя значков
- •Использование значков в вашей программе
- •Использование альтернативных курсоров
- •Битовые образы: картинки в пикселях
- •Использование битовых образов и кистей
- •Символьные строки
- •Использование ресурсов-символьных строк
- •Меню
- •Структура меню
- •Шаблон меню
- •Ссылки на меню в вашей программе
- •Меню и сообщения
- •Образец программы
- •Этикет при организации меню
- •Сложный способ определения меню
- •Третий подход к определению меню
- •Независимые всплывающие меню
- •Использование системного меню
- •Изменение меню
- •Другие команды меню
- •Использование в меню битовых образов
- •Два способа создания битовых образов для меню
- •Контекст памяти
- •Создание битового образа, содержащего текст
- •Масштабирование битовых образов
- •Соберем все вместе
- •Добавление интерфейса клавиатуры
- •Быстрые клавиши
- •Зачем нужны быстрые клавиши?
- •Некоторые правила назначения быстрых клавиш
- •Таблица быстрых клавиш
- •Преобразование нажатий клавиш клавиатуры
- •Получение сообщений быстрых клавиш
- •Программа POPPAD, имеющая меню и быстрые клавиши
- •Разрешение пунктов меню
- •Обработка опций меню
- •Глава 11 Окна диалога
- •Модальные окна диалога
- •Создание окна диалога About
- •Шаблон окна диалога
- •Диалоговая процедура
- •Вызов окна диалога
- •Дополнительная информация о стиле окна диалога
- •Дополнительная информация об определении дочерних окон элементов управления
- •Более сложное окно диалога
- •Работа с дочерними элементами управления окна диалога
- •Кнопки OK и Cancel
- •Позиции табуляции и группы
- •Рисование в окне диалога
- •Использование с окном диалога других функций
- •Определение собственных окон управления
- •Окна сообщений
- •Информация во всплывающих окнах
- •Немодальные окна диалога
- •Различия между модальными и немодальными окнами диалога
- •Новая программа COLORS
- •Программа HEXCALC: обычное окно или окно диалога?
- •Творческое использование идентификаторов дочерних окон элементов управления
- •Диалоговые окна общего пользования
- •Модернизированная программа POPPAD
- •Изменение шрифта
- •Поиск и замена
- •Программа для Windows, содержащая всего один вызов функции
- •Основы элементов управления общего пользования
- •Инициализация библиотеки
- •Создание элементов управления общего пользования
- •Стили элементов управления общего пользования
- •Уведомляющие сообщения от элементов управления общего пользования
- •Элементы управления главного окна
- •Панели инструментов
- •Создание панели инструментов
- •Строка состояния
- •Программа GADGETS
- •Наборы страниц свойств
- •Создание набора страниц свойств
- •Процедуры диалогового окна страницы свойств
- •Программа PROPERTY
Глава 10 Меню и быстрые |
10 |
|
|
клавиши |
|
У американцев есть известная юмореска о магазинчике по продаже сыра. Дело было так: некий малый заходит в сырную лавку и просит сыр определенного сорта. Естественно, такого в лавке не оказывается. Тогда он просит сыр другого сорта, потом еще одного и т. д. (всего он успел спросить о 40 сортах), а в ответ повторяется: нет, нет, нет. В конце концов дело заканчивается стрельбой.
При наличии в магазинчике меню, этого неприятного инцидента можно было бы избежать. Меню представляет собой список доступных опций. Голодному меню говорит о том, чем его может накормить кухня, а, применительно к Windows, меню говорит пользователю о том, какие действия с данным приложением он может выполнить.
Меню — это, вероятно, наиболее важная часть пользовательского интерфейса, который предлагают программы для Windows, а добавление меню к вашей программе — это относительно простая задача программирования для Windows. Вы просто определяете структуру меню в вашем описании ресурсов и присваиваете каждому пункту меню уникальный идентификатор. Вы определяете имя меню в структуре класса окна. Когда пользователь выбирает пункт меню, Windows посылает вашей программе сообщение WM_COMMAND, содержащее этот идентификатор. Мы не собираемся останавливаться на этом простом примере. Одной из самых интересных вещей, которую вы можете сделать с помощью меню, является отображение битовых образов, вместо символьных строк, в качестве пунктов меню. Поэтому, давайте подробно рассмотрим, как это сделать.
В этой главе рассказывается также о "быстрых клавишах" (keyboard accelerators). Это комбинации клавиш, которые используются в основном для дублирования функций меню.
Меню
Строка меню выводится на экране непосредственно под строкой заголовка. Эта строка иногда называется главным меню (main menu) или меню верхнего уровня (top-level menu) программы. Выбор элемента главного меню обычно приводит к вызову другого меню, появляющегося под главным, и которое обычно называют всплывающим меню (popup menu) или подменю (submenu). Вы также можете определить несколько уровней вложенности всплывающих меню: т. е. определенный пункт всплывающего меню может вызвать появление другого всплывающего меню. Иногда, с целью увеличения информативности, вызов каких-то пунктов меню приводит к появлению окон диалога. (Об окнах диалога рассказывается в следующей главе.) В большинстве родительских окон, в левой части строки заголовка, имеется маленький значок программы. Щелчок на этом значке приводит к появлению системного меню, которое фактически является всплывающим меню другого типа.
Пункты всплывающих меню могут быть помечены (checked), при этом слева от текста элемента меню Windows ставится специальная метка или "галочка". Галочки позволяют пользователю узнать о том, какие опции программы выбраны из этого меню. Эти опции могут быть взаимоисключающими. Пункты главного меню помечены быть не могут.
Пункты меню в главном и всплывающих меню могут быть "разрешены" (enabled), "запрещены" (disabled) или "недоступны" (grayed). Слова "активно" (active) и "неактивно" (inactive) иногда используются, как синонимы слов "разрешено" и "запрещено". Пункты меню, помеченные как разрешенные или запрещенные, для пользователя выглядят одинаково, а недоступный пункт меню выводится на экран в сером цвете.
С точки зрения пользователя все пункты меню, разрешенные, запрещенные и недоступные, могут быть выбраны. (Отличие только в том, что при выборе запрещенных или недоступных пунктов меню с приложением ничего не происходит.) Пользователь может щелкнуть клавишей мыши на запрещенном пункте меню, или переместить к
314
запрещенному пункту меню подсветку, или переключиться на пункт меню с помощью буквенной клавиши, соответствующей этому пункту. Однако, с позиции вашей программы разрешенные, запрещенные и недоступные пункты меню функционируют по-разному. Сообщения WM_COMMAND Windows посылает в программу только для разрешенных пунктов меню. Используйте запрещенные и недоступные пункты меню только для тех опций, которые в данный момент не могут быть выбраны. Для того чтобы пользователь знал, какие опции не могут быть выполнены, делайте их недоступными.
Структура меню
Если вы создаете или изменяете меню программы, полезно разделять главное меню и все всплывающие меню. У главного меню имеется описатель меню, у каждого всплывающего меню внутри главного меню имеется собственный описатель меню, и у системного меню (тоже являющегося всплывающим меню) тоже имеется описатель меню.
Каждый пункт меню определяется тремя характеристиками. Первая характеристика определяет то, что будет отображено в меню. Это либо строка текста, либо битовый образ. Вторая характеристика определяет либо идентификатор, который Windows посылает вашей программе в сообщении WM_COMMAND, либо всплывающее меню, которое Windows выводит на экран, когда пользователь выбирает данный пункт меню. Третья характеристика описывает атрибут пункта меню, включая то, является ли данный пункт запрещенным, недоступным или помеченным.
Шаблон меню
Меню можно создать тремя разными способами. Наиболее обычным (и самым простым) является определение меню в файле описания ресурсов в форме шаблона меню, например:
MyMenu MENU
{
[список элементов меню]
}
MyMenu — это имя меню. Вы ссылаетесь на это имя в структуре класса окна. Обычно имя меню такое же, как имя приложения.
Внутри квадратных скобок можно использовать либо инструкцию MENUITEM, либо POPUP. Инструкция MENUITEM имеет следующий формат:
MENUITEM "&Text", id [, признаки]
Формат инструкции POPUP:
POPUP "&Text" [, признаки]
{
[список элементов меню]
}
Вместо фигурных скобок можно использовать ключевые слова BEGIN и END. Текст, выводимый для каждого пункта меню должен быть заключен в парные кавычки. Амперсант (&) вызывает подчеркивание следующего за ним символа при выводе на экран. Windows ищет этот же символ, когда пользователь выбирает элемент меню с использованием клавиши <Alt>. Если не включить амперсант в текст, то в тексте меню не будет подчеркнутых символов, и Windows будет использовать первую букву текста при поиске.
Признаками в операторах MENUITEM и POPUP, которые появляются в списке главного меню, являются следующие:
•GRAYED — Данный пункт меню недоступен и не генерирует сообщений WM_COMMAND. Текст изображается недоступным (серым цветом).
•INACTIVE — Данный пункт меню неактивен и не генерирует сообщений WM_COMMAND. Текст изображается обычным образом.
•MENUBREAK — Данный пункт меню, а также все последующие появляются на экране в новой строке меню.
•HELP — Данный пункт меню, а также все последующие появляются на экране, выравненными по правому краю.
Признаки могут комбинироваться с помощью символа поразрядной операции OR языка С (|), но опции GRAYED и INACTIVE нельзя использовать вместе. Опция MENUBREAK не используется в главном меню, поскольку Windows автоматически создает новую строку главного меню, если окно слишком узкое для размещения всех пунктов меню в одну строку.
315
Следующие за инструкцией POPUP в главном меню квадратные скобки (или ключевые слова BEGIN и END) ограничивают список пунктов всплывающего меню. При определении всплывающего меню допускаются следующие инструкции:
MENUITEM "text", id [, признаки]
а также:
MENUITEM SEPARATOR
а также:
POPUP "text" [, признаки]
MENUITEM SEPARATOR рисует во всплывающем меню горизонтальную черту. Эта черта часто используется для разделения групп, связанных по смыслу и назначению опций.
Для пунктов всплывающего меню в строке символов можно использовать символ табуляции \t для разделения текста по столбцам. Текст, следующий за символом \t располагается в новом столбце, с достаточным отступом вправо для размещения в первом столбце всплывающего меню самой длинной строки текста. То, как это работает, мы рассмотрим при обсуждении быстрых клавиш ближе к окончанию этой главы. Символ \а выравнивает следующий за ним текст по правому краю. Признаками в инструкциях MENUITEM, относящихся к всплывающим меню, являются следующие:
•CHECKED — Слева от текста появляется метка ("галочка").
•GRAYED — Данный пункт меню недоступен и не генерирует сообщений WM_COMMAND. Текст изображается недоступным (серым цветом).
•INACTIVE — Данный пункт меню неактивен и не генерирует сообщений WM_COMMAND. Текст изображается обычным образом.
•MENUBREAK — Данный пункт меню, а также все последующие появляются на экране в новом столбце.
•MENUBARBREAK — Данный пункт меню, а также все последующие появляются на экране в новом столбце. Столбцы разделяются между собой вертикальной чертой.
Опции GRAYED и INACTIVE нельзя использовать вместе. Опции MENUBREAK и MENUBARBREAK нельзя использовать вместе. Если число пунктов всплывающего меню больше, чем можно разместить в одном столбце, необходимо использовать либо MENUBREAK, либо MENUBARBREAK.
Значения идентификаторов в инструкциях MENUITEM — это числа, которые Windows посылает оконной процедуре в сообщениях меню. Значение идентификатора должно быть уникальным в рамках меню. Вместо чисел может оказаться удобнее использовать идентификаторы, определенные в заголовочном файле. По договоренности эти идентификаторы начинаются с символов IDM (ID for a menu, идентификатор меню).
Ссылки на меню в вашей программе
Во многих приложениях Windows в описании ресурсов имеется только одно меню. Ссылка в программе на это меню имеет место в определении класса окна:
wndclass.lpszMenuName = "MyMenu";
Часто программисты используют строку имени программы в качестве имени меню, имени класса окна, имени значка программы. Однако, вместо имени для меню можно использовать число (или идентификатор). Тогда описание ресурса выглядело бы так:
45 MENU
{
[определение меню]
}
В этом случае, оператор присваивания для поля lpszMenuName структуры класса окна может быть либо такой:
wndclass.lpszMenuName = MAKEINTRESOURCE(45);
либо такой:
wndclass.lpszMenuName = "#45";
Хотя задание имени меню в классе окна является наиболее обычным способом ссылки на ресурс меню, существуют альтернативные варианты. В приложении для Windows ресурс меню можно загрузить в память с помощью функции LoadMenu, которая аналогична функциям LoadIcon и LoadCursor, описанным в главе 9. Если в описании ресурса меню используете имя, то возвращаемым значением функции LoadMenu является описатель меню:
hMenu = LoadMenu(hInstance, "MyMenu");
316
При использовании числа функция LoadMenu принимает либо такой вид:
hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(45));
либо такой:
hMenu = LoadMenu(hInstance, "#45");
Затем этот описатель меню можно указать в качестве девятого параметра функции CreateWindow:
hwnd = CreateWindow("MyClass", "Window Caption", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL,
hMenu,
hInstance,
NULL);
В этом случае меню, указанное при вызове функции CreateWindow, перекрывает любое меню, заданное в классе окна. Меню, задаваемое в классе окна, можно считать заданным по умолчанию меню для окон, созданных на основе данного класса окна, если девятый параметр функции CreateWindow установлен в NULL. Поэтому можно использовать разные меню для различных окон, созданных на основе одного и того же класса окна.
Можно также указать NULL для меню при регистрации класса окна и NULL для меню при вызове функции CreateWindow, а затем присоединить меню к окну следующим образом:
SetMenu(hwnd, hMenu);
Такая форма позволяет динамически изменять меню окна. В программе NOPOPUPS, которая приведена далее в этой главе, показан пример, иллюстрирующий этот прием.
Любое меню, связанное с окном, удаляется при удалении окна. Любое несвязанное с окном меню перед завершением работы программы должно быть явно удалено при помощи вызова функции DestroyMenu.
Меню и сообщения
Когда пользователь выбирает пункт меню, Windows посылает оконной процедуре несколько различных сообщений. Большинство из этих сообщений могут игнорироваться программой, и просто передаваться DefWindowProc. Одним из таких сообщений является сообщение WM_INITMENU, которое имеет следующие параметры:
wParam |
lParam |
Описатель главного меню |
0 |
Значением параметра wParam является описатель главного меню, даже если пользователь выбирает пункт системного меню. В программах для Windows сообщение WM_INITMENU обычно игнорируется. Хотя это сообщение существует для того, чтобы дать вам возможность изменить меню перед тем, как будет выбран пункт меню, возможно, что любые изменения главного меню в этот момент могут привести пользователя в замешательство.
Кроме того, программа получает сообщения WM_MENUSELECT. Если пользователь перемещает курсор мыши по пунктам меню, программа может получить множество сообщений WM_MENUSELECT. Как будет рассказано в главе 12, это полезно при использовании строки состояния, содержащей полное описание опции меню. Данное сообщение имеет следующие параметры:
Младшее слово (LOWORD) |
Старшее слово |
lParam |
wParam |
(HIWORD) wParam |
|
Выбранный пункт: |
Флаги выбора |
Описатель меню, |
идентификатор меню или |
|
содержащего |
описатель всплывающего меню |
|
выбранный пункт |
Сообщение WM_MENUSELECT — это сообщение для отслеживания перемещения по меню. Младшее слово параметра wParam говорит о том, какой пункт меню выбран (подсвечен) в данный момент. В старшем слове параметра wParam могут быть комбинации из следующих флагов выбора: MF_GRAYED, MF_DISABLED, MF_CHECKED, MF_BITMAP, MF_POPUP, MF_HELP, MF_SYSMENU и MF_MOUSESELECT. Сообщение
WM_MENUSELECT может понадобиться для того, чтобы изменить что-нибудь в рабочей области окна на основе информации о перемещении подсветки по пунктам меню. В большинстве программ это сообщение передается в
DefWindowProc.
317
Когда Windows готова вывести на экран всплывающее меню, она посылает оконной процедуре сообщение WM_INITMENUPOPUP со следующими параметрами:
wParam |
Младшее слово |
Старшее слово |
|
(LOWORD) lParam |
(HIWORD) lParam |
Описатель всплывающего |
Индекс всплывающего |
Для системного меню 1, в |
меню |
меню |
противном случае 0 |
Это сообщение важно, если необходимо разрешать или запрещать пункты меню перед их выводом на экран. Например, предположим, что программа с помощью команды Paste всплывающего меню может копировать текст из буфера обмена. При получении для этого всплывающего меню сообщения WM_INITMENUPOPUP необходимо определить, имеется ли текст в буфере обмена. Если нет, то необходимо сделать этот пункт меню Paste недоступным. Мы рассмотрим такой пример в программе POPPAD, представленной далее в этой главе.
Самым важным сообщением меню является WM_COMMAND. Это сообщение показывает, что пользователь выбрал разрешенный пункт меню окна. Из главы 8 вы помните, что сообщения WM_COMMAND также посылаются дочерними окнами управления. Если оказывается, что для меню и дочерних окон управления используются одни и те же идентификаторы, то различить их можно с помощью значения параметра lParam, который для пункта меню будет равен 0:
|
Младшее слово |
Старшее слово |
lParam |
|
(LOWORD) wParam |
(HIWORD) wParam |
|
Меню: |
Идентификатор меню |
0 |
0 |
Элемент |
Идентификатор |
Код уведомления |
Описатель |
управления: |
элемента управления |
|
дочернего окна |
Сообщение WM_SYSCOMMAND похоже на сообщение WM_COMMAND за исключением того, что сообщение WM_SYSCOMMAND сигнализирует, что пользователь выбрал разрешенный пункт системного меню:
Младшее слово |
Старшее слово |
lParam |
(LOWORD) wParam |
(HIWORD) wParam |
|
Системное Идентификатор меню |
0 |
0 (Если сообщение |
меню: |
|
WM_SYSCOMMAND |
|
|
является результатом щелчка |
|
|
мыши, тогда старшее и |
|
|
младшее слово lParam |
|
|
являются, соответственно, |
|
|
экранными координатами X и |
|
|
Y курсора мыши.) |
Идентификатор меню показывает, какой пункт системного меню выбран. Для предопределенных пунктов системного меню, четыре младших разряда должны быть замаскированы. Результирующая величина будет одной из следующих: SC_SIZE, SC_MOVE, SC_MINIMIZE, SC_MAXIMIZE, SC_NEXTWINDOW, SC_PREVWINDOW, SC_CLOSE, SC_VSCROLL, SC_HSCROLL, SC_ARRANGE, SC_RESTORE и SC_TASKLIST. Кроме того, младшее слово параметра wParam может быть SC_MOUSEMENU или SC_KEYMENU.
Если вы добавите к системному меню новые пункты, то младшее слово параметра wParam станет идентификатором, который вы определите. Для избежания конфликта с предопределенными идентификаторами меню, используйте значения меньше чем 0xF000. Важно, чтобы обычные сообщения WM_SYSCOMMAND передавались в DefWindowProc. Если этого не сделать, то обычные команды системного меню будут отключены.
Последним сообщением, которое мы обсудим, является сообщение WM_MENUCHAR, которое, в действительности, не является собственно сообщением меню. Windows посылает это сообщение оконной процедуре в одном из двух случаев: если пользователь нажимает комбинацию клавиши <Alt> и символьной клавиши, несоответствующей пунктам меню, или при выводе на экран всплывающего меню, если пользователь нажимает символьную клавишу, не соответствующую пункту всплывающего меню. Параметры сообщения WM_MENUCHAR являются следующими:
Младшее слово (LOWORD) |
Старшее слово |
lParam |
wParam |
(HIWORD) wParam |
|
Код ASCII |
Код выбора |
Описатель меню |
Код выбора равен:
•0 — всплывающее меню не отображается.
•MF_POPUP — отображается всплывающее меню.
•MF_SYSMENU — отображается системное меню.