- •Содержание
- •Глава 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
344
Запомните, что битовые образы являются объектами GDI и должны быть явно удалены при завершении программы. В программе GRAFMENU эта задача решается после выхода из цикла обработки сообщений:
DeleteObject(hBitmapHelp);
DeleteObject(hBitmapEdit);
DeleteObject(hBitmapFile);
DeleteObject(hBitmapFont);
for(i = 0; i < 3; i++) DeleteObject(hBitmapPopFont[i]);
Взаключении раздела приведем несколько общих замечаний:
•Высоту панели главного меню Windows изменяет таким образом, чтобы туда уместился самый высокий битовый образ. Другие битовые образы (или символьные строки) выравниваются по верхней границе панели меню. Размер панели меню, полученный от функции:
GetSystemMetrics(SM_CYMENU)
изменяется, поскольку в меню добавлены битовые образы.
•При работе с программой GRAFMENU, можно использовать метки пунктов всплывающих меню, заданных в виде битовых образов, но метки при этом имеют обычный размер. Если это вам не нравится, то можно создать свои метки и использовать функцию SetMenuItemBitmaps.
•Другим подходом к использованию в меню не текста (или текста, набранного не системным шрифтом) является меню, отображаемое владельцем (owner-draw).
Добавление интерфейса клавиатуры
Теперь появилась новая проблема. Если в меню содержится текст, Windows автоматически добавляет интерфейс клавиатуры. Пункт меню можно выбрать с помощью клавиши <Alt> в комбинации с буквой символьной строки. Но после того как в меню помещен битовый образ, интерфейс клавиатуры отключается.
Это как раз тот самый случай, когда в дело вступает сообщение WM_MENUCHAR. Windows посылает это сообщение оконной процедуре, когда нажимается клавиша <Alt> в комбинации с такой буквой символьной строки, которая не соответствует ни одному пункту меню. Необходимо отслеживать сообщения WM_MENUCHAR и проверять младшее слово параметра wParam (ASCII-код символа нажатой клавиши). Если он соответствует пункту меню, то необходимо возвратить обратно в Windows длинное целое, где старшее слово устанавливается в 2, а младшее слово устанавливается равным индексу того пункта меню, который мы хотим связать с этой клавишей. Остальное выполняет Windows.
Быстрые клавиши
Если выразиться максимально кратко, то быстрые клавиши (keyboard accelerators) — это комбинации клавиш, которые генерируют сообщения WM_COMMAND (в некоторых случаях WM_SYSCOMMAND). Чаще всего быстрые клавиши используются в программах для дублирования действий обычных опций меню. (Однако быстрые клавиши могут выполнять и такие функции, которых нет в меню.) Например, в некоторых программах для Windows имеется меню Edit, которое включает в себя опцию Delete; в этих программах для этой опции быстрой клавишей обычно является клавиша <Del>. Пользователь может выбрать из меню опцию Delete, нажимая <Alt>-комбинацию, или может просто нажать быструю клавишу <Del>. Когда оконная процедура получает сообщение WM_COMMAND, то ей не нужно определять, что именно, меню или быстрая клавиша, использовались.
Зачем нужны быстрые клавиши?
Вы можете спросить: "Зачем нужны быстрые клавиши?" Почему нельзя просто отслеживать сообщения WM_KEYDOWN или WM_CHAR и самому дублировать функции меню? В чем преимущество быстрых клавиш? Для простого приложения, имеющего одно окно, несомненно, можно отслеживать сообщения клавиатуры, но, используя быстрые клавиши, вы получаете определенные преимущества: вам не нужно дублировать логику меню и быстрых клавиш.
Для многооконных приложений с множеством оконных процедур быстрые клавиши очень важны. Как известно, Windows посылает сообщения клавиатуры оконной процедуре того окна, которое в данный момент имеет фокус ввода. Однако, в случае быстрых клавиш Windows посылает сообщение WM_COMMAND той оконной процедуре, чей описатель задан в функции TranslateAccelerator. Как правило, это будет оконная процедура главного окна вашей программы, т. е. того окна, в котором имеется меню. Следовательно, нет необходимости дублировать логику действия быстрых клавиш в каждой оконной процедуре.
345
Это преимущество становится особенно важным при использовании немодальных окон диалога (которые будут рассмотрены в следующей главе) или дочерних окон, расположенных в рабочей области вашего главного окна. Если при наличии нескольких окон для перемещения между окнами назначается определенная быстрая клавиша, то только одна оконная процедура должна включать в себя эту логику. Дочерние окна не получают от быстрых клавиш сообщений WM_COMMAND.
Некоторые правила назначения быстрых клавиш
Теоретически можно определить быструю клавиши почти для каждой виртуальной или символьной клавиши в сочетании с клавишами <Shift>, <Ctrl> или <Alt>. Однако надо попытаться добиться какого-то соответствия с другими приложениями и избегать применения тех клавиш, которые использует Windows. Нежелательно назначать быстрыми клавишами клавиши <Tab>, <Enter>, <Esc>, <Spacebar>, поскольку они часто используются для системных функций.
Наиболее часто с быстрыми клавишами работают в меню Edit. Рекомендуемые быстрые клавиши для этих пунктов меню различаются у версий Windows 3.0 и Windows 3.1, поэтому следует обеспечить поддержку как старых, так и новых быстрых клавиш, показанных в следующей таблице:
Функция |
Быстрые клавиши старые |
Быстрые клавиши новые |
Undo (отменить) |
<Alt>+<Backspace> |
<Ctrl>+<Z> |
Cut (вырезать) |
<Shift>+<Del> |
<Ctrl>+<X> |
Copy (копировать) |
<Ctrl>+<Ins> |
<Ctrl>+<C> |
Paste (вставить) |
<Shift>+<Ins> |
<Ctrl>+<V> |
Delete или Clear |
<Del> |
<Del> |
(удалить или очистить) |
|
|
Другой известной быстрой клавишей является клавиша <F1> для вызова подсказки. Избегайте применения клавиш <F4>, <F5> и <F6>, поскольку они часто используются для специальных функций многооконного интерфейса приложений (Multiple Document Interface, MDI), о котором рассказывается в главе 18.
Таблица быстрых клавиш
Быстрые клавиши определяются в файле описания ресурсов (файл с расширением .RC). Здесь показана общая форма определения:
MyAccelerators ACCELERATORS
{
[определения быстрых клавиш]
}
Эта таблица быстрых клавиш называется MyAccelerators. В таблицу ACCELERATORS не включаются опции загрузки и памяти. В файле описания ресурсов можно иметь несколько таблиц ACCELERATORS.
Для каждой определяемой быстрой клавиши необходима отдельная строка таблицы. Имеется четыре типа определений быстрых клавиш:
"char", |
id |
[,<SHIFT>] [,CONTROL] [,<ALT>] |
"^char", |
id |
[,<SHIFT>] [,CONTROL] [,<ALT>] |
nCode, |
id, ASCII |
[,<SHIFT>] [,CONTROL] [,<ALT>] |
nCode, |
id, VIRTKEY |
[,<SHIFT>] [,CONTROL] [,<ALT>] |
Вэтих примерах "char" означает один символ, заключенный в кавычки, а "^char" — это символ ^ и один символ, заключенный в кавычки. Число id выполняет ту же функцию, что и идентификатор меню в определении меню. Это значение, которое Windows посылает вашей оконной процедуре в сообщении WM_COMMAND для идентификации быстрой клавиши. Обычно эти идентификаторы определяются в заголовочном файле. Быстрые клавиши почти всегда служат для выбора опций из всплывающих меню. Если быстрая клавиша дублирует команду меню, используйте один и тот же идентификатор для меню и для быстрой клавиши. Если быстрая клавиша не дублирует команду меню, используйте уникальный идентификатор.
Впервом типе определения идентификатора быстрая клавиша — это чувствительный к регистру символ в кавычках:
"char", |
id |
[,<SHIFT>] [,CONTROL] [,<ALT>] |
Если вы хотите использовать эту клавишу в сочетании с одной или более клавишами <Shift>, <Ctrl> и <Alt>, просто добавьте SHIFT, CONTROL и/или ALT.
В определении второго типа быстрая клавиша — это символ в сочетании с клавишей <Ctrl>:
"^char", |
id |
[,<SHIFT>] [,CONTROL] [,<ALT>] |
346
Этот тип определения эквивалентен первому, если бы в нем за символом было бы указано ключевое слово
CONTROL.
В определениях третьего и четвертого типов вместо символа в кавычках используется число (nCode):
nCode, |
id, |
ASCII |
[,<SHIFT>] |
[,CONTROL] |
[,<ALT>] |
nCode, |
id, |
VIRTKEY |
[,<SHIFT>] |
[,CONTROL] |
[,<ALT>] |
Это число интерпретируется либо как чувствительный к регистру ASCII-код символа, либо как код виртуальной клавиши, в зависимости от наличия ключевого слова ASCII или VIRTKEY.
Наиболее часто используются определения быстрых клавиш второго и четвертого типа. В определении второго типа буквенная клавиша используется в сочетании с клавишей <Ctrl>. Например, здесь определяется быстрая клавиша <Ctrl>+<A>:
"^A", id
Определение четвертого типа используется для виртуальных кодов клавиш, таких как функциональные клавиши. Для комбинации <Ctrl>+<F9> используется следующее определение:
VK_F9, wid, VIRTKEY, CONTROL
Идентификатор VK_F9 определяется в заголовочных файлах Windows в качестве виртуального кода клавиши <F9>, поэтому, вы должны включить в программу в начале файла описания ресурсов инструкцию:
#include <windows.h>
Приведенные выше определения первого и третьего типов применяются редко. Если вы хотите их использовать, внимательно контролируйте чувствительность к регистру. Windows осуществляет чувствительный к регистру контроль совпадения "char" или nCode, основываясь на нажатой клавише. Если вы добавляете ключевое слово SHIFT, Windows контролирует, нажата или нет клавиша <Shift>. Эта ситуация иногда приводит к неожиданному результату. Например, если "char" — это "А", то быстрая клавиша срабатывает, если нажата клавиша <А> или при нажатой клавише <Shift> или при включенном режиме Caps Lock. Если вы используете "А" с ключевым словом SHIFT, то быстрая клавиша активизируется, если нажата клавиша <А> при нажатой клавише <Shift>, но не должна вызываться при включенном режиме Caps Lock. Точно также "а" — сама по себе является быстрой клавишей для клавиши <А> нижнего регистра или для клавиши <А> с нажатой клавишей <Shift> и включенном режиме Caps Lock. Но "а" с ключевым словом SHIFT является быстрой клавишей только в одном случае, если клавиша <Shift> нажата, а Caps Lock включен.
При определении быстрых клавиш для пунктов меню необходимо включить описание комбинации быстрых клавиш в текст соответствующего пункта меню. Символ табуляции (\t) разделяет текст и описание быстрой клавиши так, чтобы описание быстрых клавиш располагалось во втором столбце. При наличии слов Shift, Ctrl или Alt после них пишется знак плюс и собственно клавиша. Например:
•F6
•Shift+F6
•Ctrl+F6
Загрузка таблицы быстрых клавиш
Внутри программы для загрузки таблицы быстрых клавиш в память и получения ее описателя используется функция LoadAccelerators. Инструкция с функцией LoadAccelerators очень похожа на аналогичные инструкции с
LoadIcon, LoadCursor, LoadBitmap и LoadMenu.
Сначала таблица быстрых клавиш определяется как имеющая тип HACCEL:
HACCEL hAccel;
Затем производится загрузка таблицы:
hAccel = LoadAccelerators(hInstance, "MyAccelerators");
Как и в случаях со значками, курсорами, битовыми образами и меню, вместо имени таблицы быстрых клавиш можно вставить число, которое затем будет использоваться в инструкции, содержащей функцию LoadAccelerators и макрос MAKEINTRESOURCE. Вместо макроса перед числом можно ставить символ #, тогда весь параметр заключается в кавычки.
Преобразование нажатий клавиш клавиатуры
Мы не будем менять те три строки программы, которые являются общими почти для всех программ Windows, уже приведенных в этой книге. Данная инструкция — стандартный цикл обработки сообщений:
347
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Далее приводятся те изменения, которые необходимы, чтобы использовать таблицу быстрых клавиш:
while(GetMessage(&msg, NULL, 0, 0))
{
if(!TranslateAccelerator(hwnd, hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Функция TranslateAccelerator определяет, является ли сообщение, хранящееся в структуре msg, сообщением клавиатуры. Если да, функция ищет соответствия в таблице быстрых клавиш, описателем которой является hAccel. Если соответствие находится, она вызывает оконную процедуру окна, описателем которого является hwnd. Если быстрая клавиша соответствует пункту системного меню, то отправляемым сообщением является
WM_SYSCOMMAND. В противном случае — WM_COMMAND.
Возвращаемое значение функции TranslateAccelerator не равно нулю, если сообщение уже было преобразовано (и уже отправлено в оконную процедуру), и равно 0, если нет. Если возвращаемое значение функции
TranslateAccelerator не равно нулю, то нет необходимости вызывать функции TranslateMessage и DispatchMessage,
и поэтому управление вновь передается функции GetMessage.
Параметр hwnd функции TranslateAccelerator кажется несколько излишним, поскольку он не требуется в трех остальных функциях цикла обработки сообщений. Более того, в самой структуре сообщения (переменная структуры msg) имеется член с именем hwnd, который является описателем окна. Отличия обусловлены следующим:
Поля структуры msg заполняются при вызове функции GetMessage. Если второй параметр функции GetMessage равен NULL, то функция извлекает сообщения всех окон, принадлежащих приложению. При возвращении из функции GetMessage, число hwnd структуры msg является описателем того окна, которое получит сообщение. Однако, когда функция TranslateAccelerator преобразует сообщение клавиатуры в сообщение WM_COMMAND или WM_SYSCOMMAND, она заменяет описатель окна msg.hwnd описателем hwnd, заданным в качестве первого параметра функции. Таким образом, Windows посылает все сообщения быстрых клавиш одной оконной процедуре, даже если в данный момент фокус ввода имеет другое окно приложения. Функция TranslateAccelerator не преобразует сообщения клавиатуры, когда модальное окно диалога или окно сообщений имеет фокус ввода, поскольку сообщения для этих окон не проходят через цикл обработки сообщений программы.
В некоторых случаях, когда какое-то другое окно вашей программы (например, немодальное окно диалога) имеет фокус ввода, нажатия быстрых клавиш можно не преобразовывать. В следующей главе вы узнаете, как работать в такой ситуации.
Получение сообщений быстрых клавиш
Если быстрая клавиша связана с пунктом системного меню, функция TranslateAccelerator посылает оконной процедуре сообщение WM_SYSCOMMAND. В противном случае функция TranslateAccelerator посылает оконной процедуре сообщение WM_COMMAND. В следующей таблице показаны типы сообщений WM_COMMAND, которые можно получить для быстрых клавиш, команд меню и дочерних окон управления:
|
Младшее слово |
Старшее слово |
lParam |
|
(LOWORD) |
(HIWORD) (wParam) |
|
|
(wParam) |
|
|
Быстрая |
Идентификатор быстрой |
1 |
0 |
клавиша: |
клавиши |
|
|
Меню: |
Идентификатор меню |
0 |
0 |
Элемент |
Идентификатор |
Код уведомления |
Описатель |
управления: |
элемента управления |
|
дочернего окна |
Кроме этого, если быстрая клавиша соответствует пункту меню, оконная процедура получает сообщения
WM_INITMENU, WM_INITMENUPOPUP и WM_MENUSELECT точно также, как при выборе опции меню.
Обычно, в программах при обработке сообщений WM_INITMENUPOPUP делают разрешенными и запрещенными пункты всплывающих меню. При работе с быстрыми клавишами эта возможность по-прежнему имеется. Однако