- •Оглавление
- •Глава 1 Введение 7
- •Глава 2 Основные понятия 10
- •Глава 3 Рисование текста 42
- •Глава 4. Главное о графике 65
- •Глава 5 Клавиатура 180
- •Глава 6 Мышь 214
- •Глава 7 Таймер 233
- •Глава 8 Дочерние окна управления 247
- •Глава 1 Введение
- •Основные правила
- •1.2 Краткая история Windows
- •Глава 2 Основные понятия
- •2.1 Отличительная особенность Windows
- •2.1.1 Графический интерфейс пользователя
- •2.1.2 Концепции и обоснование gui
- •2.1.3 Содержимое интерфейса пользователя
- •2.1.4 Преимущество многозадачности
- •2.1.5 Управление памятью
- •2.1.6 Независимость графического интерфейса от оборудования
- •2.1.7 Соглашения операционной системы Windows
- •2.1.8 Вызовы функций
- •2.1.9 Объектно-ориентированное программирование
- •2.1.10 Архитектура, управляемая событиями
- •2.1.11 Оконная процедура
- •2.2 Ваша первая программа для Windows
- •2.2.1 Что в этой программе неправильно?
- •2.2.2 Файлы hellowin
- •2.2.3 Файл исходного текста программы на языке с
- •2.2.4 Вызовы функций Windows
- •2.2.5 Идентификаторы, написанные прописными буквами
- •2.2.6 Новые типы данных
- •2.2.7 Описатели
- •2.2.8 Венгерская нотация
- •2.2.9 Точка входа программы
- •2.2.10 Регистрация класса окна
- •2.2.11 Создание окна
- •2.2.12 Отображение окна
- •2.2.13 Цикл обработки сообщений
- •2.2.14 Оконная процедура
- •2.2.15 Обработка сообщений
- •2.2.15 Воспроизведение звукового файла
- •2.2.16 Сообщение wm_paint
- •2.2.17 Сообщение wm_destroy
- •2.3 Сложности программирования для Windows
- •2.3.1 Функции обратного вызова
- •2.3.2 Синхронные и асинхронные сообщения
- •Глава 3 Рисование текста
- •3.1 Рисование и обновление
- •3.1.1 Сообщение wm_paint
- •3.1.2 Действительные и недействительные прямоугольники
- •3.2 Введение в графический интерфейс устройства (gdi)
- •3.2.1 Контекст устройства
- •3.2.2 Получение описателя контекста устройства. Первый метод
- •3.2.3 Структура информации о рисовании
- •3.2.4 Получение описателя контекста устройства. Второй метод
- •3.2.5 Функция TextOut. Подробности
- •3.2.6 Системный шрифт
- •3.2.7 Размер символа
- •3.2.8 Метрические параметры текста. Подробности
- •3.2.9 Форматирование текста
- •3.2.10 Соединим все вместе
- •3.2.11 Оконная процедура программы sysmets1
- •3.2.12 Не хватает места!
- •3.2.13 Размер рабочей области
- •3.3 Полосы прокрутки
- •3.3.1 Диапазон и положение полос прокрутки
- •3.3.2 Сообщения полос прокрутки
- •3.3.3 Прокрутка в программе sysmets2
- •3.3.4 Структурирование вашей программы для рисования
- •Глава 4. Главное о графике
- •4.1 Концепция gdi
- •4.2 Структура gdi
- •4.2.1 Типы функций
- •4.2.2 Примитивы gdi
- •4.2.3 Другие аспекты
- •4.3 Контекст устройства
- •4.3.1 Получение описателя контекста устройства
- •4.3.3 Получение информации из контекста устройства
- •4.3.4 Размер устройства
- •4.3.5 О цветах
- •4.3.6 Атрибуты контекста устройства
- •4.3.7 Сохранение контекста устройства
- •4.4 Рисование отрезков
- •4.4.1 Ограничивающий прямоугольник
- •4.4.2 Сплайны Безье
- •4.4.3 Использование стандартных перьев
- •4.4.4 Создание, выбор и удаление перьев
- •4.4.5 Закрашивание пустот
- •4.4.6 Режимы рисования
- •4.5 Рисование закрашенных областей
- •4.5.1 Функция Polygon и режим закрашивания многоугольника
- •4.5.2 Закрашивание внутренней области
- •4.6 Режим отображения
- •4.6.1 Координаты устройства (физические координаты) и логические координаты
- •4.6.2 Системы координат устройства
- •4.6.3 Область вывода и окно
- •4.6.4 Работа в режиме mm_text
- •4.6.5 Метрические режимы отображения
- •4.6.6 Ваши собственные режимы отображения
- •Режим отображения mm_isotropic
- •Mm_anisotropic: растягивание изображения
- •4.6.7 Программа whatsize
- •4.7 Прямоугольники, регионы и отсечение
- •4.7.1 Работа с прямоугольниками
- •4.7.2 Случайные прямоугольники
- •4.7.3 Создание и рисование регионов
- •4.7.4 Отсечения: прямоугольники и регионы
- •4.7.5 Программа cover
- •4.8 Пути
- •4.8.1 Создание и воспроизведение путей
- •4.8.2 Расширенные перья
- •4.9 Битовые образы
- •4.9.1 Цвета и битовые образы
- •4.9.2 Битовые образы, не зависящие от устройства (dib)
- •4.9.3 Файл dib
- •4.9.4 Упакованный формат хранения dib
- •4.9.5 Отображение dib
- •4.9.6 Преобразование dib в объекты "битовые образы"
- •4.10 Битовый образ — объект gdi
- •4.10.1 Создание битовых образов в программе
- •4.10.2 Формат монохромного битового образа
- •4.10.3 Формат цветного битового образа
- •4.10.4 Контекст памяти
- •4.10.5 Запись пикселей на устройство отображения
- •Функция PatBlt
- •Координаты Blt
- •4.10.6 Перенос битов с помощью функции BitBlt
- •4.10.7 Функция DrawBitmap
- •4.10.8 Использование других rop кодов
- •4.10.9 Дополнительные сведения о контексте памяти
- •4.10.10 Преобразования цветов
- •4.10.11 Преобразования режимов отображения
- •4.10.12 Растяжение битовых образов с помощью функции StretchBlt
- •4.10.13 Кисти и битовые образы
- •4.11 Метафайлы
- •4.11.1 Простое использование метафайлов памяти
- •4.11.2 Сохранение метафайлов на диске
- •4.12 Расширенные метафайлы
- •4.12.1 Делаем это лучше
- •4.12.2 Базовая процедура
- •4.12.3 Заглянем внутрь
- •4.12.4 Вывод точных изображений
- •4.13 Текст и шрифты
- •4.13.1 Вывод простого текста
- •4.13.2 Атрибуты контекста устройства и текст
- •4.13.3 Использование стандартных шрифтов
- •4.13.4 Типы шрифтов
- •4.13.5 Шрифты TrueType
- •4.13.6 Шрифт ezfont
- •4.13.7 Внутренняя работа
- •4.13.8 Форматирование простого текста
- •4.13.9 Работа с абзацами
- •Глава 5 Клавиатура
- •5.1 Клавиатура. Основные понятия
- •5.1.1 Игнорирование клавиатуры
- •5.1.2 Фокус ввода
- •5.1.3 Аппаратные и символьные сообщения
- •5.2 Аппаратные сообщения
- •5.2.1 Системные и несистемные аппаратные сообщения клавиатуры
- •5.2.2 Переменная lParam
- •Счетчик повторений
- •Скан-код oem
- •Флаг расширенной клавиатуры
- •Код контекста
- •Флаг предыдущего состояния клавиши
- •Флаг состояния клавиши
- •5.2.3 Виртуальные коды клавиш
- •5.2.4 Состояние клавиш сдвига и клавиш-переключателей
- •5.2.5 Использование сообщений клавиатуры
- •5.4 Символьные сообщения
- •5.4.1 Сообщения wm_char
- •5.4.2 Сообщения немых символов
- •5.6 Каретка (не курсор)
- •5.6.1 Функции работы с кареткой
- •5.6.2 Программа typer
- •5.7 Наборы символов Windows
- •5.7.1 Набор символов oem
- •Поддержка языков различных стран в dos
- •5.7.2 Набор символов ansi
- •5.7.3 Наборы символов oem, ansi и шрифты
- •5.8 Решение проблемы с использованием системы unicode
- •5.8.2 Unicode и библиотека с
- •5.8.3 Типы данных, определенные в Windows для Unicode
- •5.8.4 Unicode- и ansi-функции в Windows
- •5.8.5 Строковые функции Windows
- •5.8.6 Создание программ, способных использовать и ansi, и Unicode
- •5.8.7 Ресурсы
- •5.8.8 Текстовые файлы
- •5.8.9 Перекодировка строк из Unicode в ansi и обратно
- •Глава 6 Мышь
- •6.1 Базовые знания о мыши
- •6.1.1 Несколько кратких определений
- •6.2 Сообщения мыши, связанные с рабочей областью окна
- •6.2.1 Простой пример обработки сообщений мыши
- •6.2.3 Двойные щелчки клавиш мыши
- •6.3 Сообщения мыши нерабочей области
- •6.3.1 Сообщение теста попадания
- •6.3.2 Сообщения порождают сообщения
- •6.4 Тестирование попадания в ваших программах
- •6.4.1 Гипотетический пример
- •6.4.2 Пример программы
- •6.4.3 Эмуляция мыши с помощью клавиатуры
- •6.4.4 Добавление интерфейса клавиатуры к программе checker
- •6.4.5 Использование дочерних окон для тестирования попадания
- •6.4.6 Дочерние окна в программе checker
- •6.5 Захват мыши
- •6.5.1 Рисование прямоугольника
- •6.5.2 Решение проблемы — захват
- •6.5.3 Программа blokout2
- •Глава 7 Таймер
- •7.1 Основы использования таймера
- •7.1.1 Система и таймер
- •7.1.2 Таймерные сообщения не являются асинхронными
- •7.2 Использование таймера: три способа
- •7.2.1 Первый способ
- •Что делать, если таймер недоступен
- •Пример программы
- •7.2.2 Второй способ
- •Пример программы
- •7.2.3 Третий способ
- •7.3 Использование таймера для часов
- •7.3.1 Позиционирование и изменение размеров всплывающего окна
- •7.3.2 Получение даты и времени
- •7.3.3 Обеспечение международной поддержки
- •7.3.4 Создание аналоговых часов
- •7.4 Стандартное время Windows
- •7.5 Анимация
- •Глава 8 Дочерние окна управления
- •8.1 Класс кнопок
- •8.1.1 Создание дочерних окон
- •8.1.2 Сообщения дочерних окон родительскому окну
- •8.1.3 Сообщения родительского окна дочерним окнам
- •8.1.4 Нажимаемые кнопки
- •8.1.5 Флажки
- •8.1.6 Переключатели
- •8.1.7 Окна группы
- •8.1.8 Изменение текста кнопки
- •8.1.9 Видимые и доступные кнопки
- •8.1.10 Кнопки и фокус ввода
- •8.2 Дочерние окна управления и цвета
- •8.2.1 Системные цвета
- •8.2.2 Цвета кнопок
- •8.2.3 Сообщение wm_ctlcolorbtn
- •8.2.4 Кнопки, определяемые пользователем
- •8.3 Класс статических дочерних окон
- •8.4 Класс полос прокрутки
- •8.4.1 Программа colors1
- •8.4.2 Интерфейс клавиатуры, поддерживаемый автоматически
- •8.4.3 Введение новой оконной процедуры
- •8.4.5 Закрашивание фона
- •8.4.5 Окрашивание полос прокрутки и статического текста
- •8.5 Класс редактирования
- •8.5.1 Стили класса редактирования
- •8.5.2 Коды уведомления управляющих окон редактирования
- •8.5.3 Использование управляющих окон редактирования
- •8.5.4 Сообщения управляющему окну редактирования
- •8.6 Класс окна списка
- •8.6.1 Стили окна списка
- •8.6.2 Добавление строк в окно списка
- •8.6.3 Выбор и извлечение элементов списка
- •8.6.4 Получение сообщений от окон списка
- •8.6.5 Простое приложение, использующее окно списка
- •8.6.6 Список файлов
- •Использование атрибутов файлов
- •Упорядочивание списков файлов
- •8.6.7 Утилита Head для Windows
5.4.1 Сообщения wm_char
Если вашей Windows-программе необходимо обрабатывать символы клавиатуры (например, в программах обработки текстов или коммуникационных программах), то она будет обрабатывать сообщения WM_CHAR.
Вероятно, вы захотите как-то по-особому обрабатывать клавиши <Backspace>, <Tab> и <Enter> (и, может быть, клавишу <Linefeed>), но все остальные символы вы будете обрабатывать похожим образом:
case WM_CHAR:
switch(wParam)
{
case '\b': // забой(Backspace)
[другие строки программы]
break;
case '\t': // табуляция(Tab)
[другие строки программы]
break;
case '\n': // перевод строки(Linefeed)
[другие строки программы]
break;
case '\r': // возврат каретки(Enter)
[другие строки программы]
break;
default: // символьный код
[другие строки программы]
break;
}
return 0;
Этот фрагмент программы фактически идентичен обработке символов клавиатуры в обычных программах MS_DOS.
5.4.2 Сообщения немых символов
Программы для Windows обычно могут игнорировать сообщения WM_DEADCHAR и WM_SYSDEADCHAR. На некоторых, не американских клавиатурах, некоторые клавиши определяются добавлением диакритического знака к букве. Они называются "немыми клавишами" (dead keys), поскольку эти клавиши сами по себе не определяют символов. Например, при инсталляции немецкой клавиатуры, клавиша, находящаяся там же, где в американской клавиатуре находится клавиша <+/=>, становится немой клавишей для указания высокого звука (), при ненажатой клавише сдвига, и низкого звука (`), при нажатой клавише сдвига.
Если пользователь нажимает немую клавишу, оконная процедура получает сообщение WM_DEADCHAR с параметром wParam равным коду ASCII самого диакритического знака. Когда затем пользователь нажимает клавишу буквы (например, клавишу <А>), оконная процедура получает сообщение WM_CHAR, где параметр wParam равен коду ASCII буквы с диакритическим знаком. Таким образом, ваша программа не должна обрабатывать сообщение WM_DEADCHAR, поскольку сообщение WM_CHAR и так дает программе всю необходимую информацию. Windows имеет даже встроенную систему отслеживания ошибок: если за немой клавишей следует буква, у которой не может быть диакритического знака (например буква s), то оконная процедура получает два сообщения WM_CHAR подряд — первое с wParam равным коду ASCII самого диакритического знака (такое же значение wParam, как было передано с сообщением WM_DEADCHAR) и второе wParam равным коду ASCII буквы s.
5.6 Каретка (не курсор)
Когда вы в программе набираете текст, обычно маленький символ подчеркивания или маленький четырехугольник показывает вам место, где следующий набираемый вами символ появится на экране. Вы можете считать, что это курсор (cursor), но, если вы программируете для Windows, необходимо отказаться от такого представления. В Windows это называется "каретка" (caret). Слово же "курсор" относится к битовому образу, отражающему положение мыши на экране.
5.6.1 Функции работы с кареткой
Здесь перечислены пять основных функций работы с кареткой:
CreateCaret — создает связанную с окном каретку.
SetCaretPos — устанавливает положение каретки в окне.
ShowCaret — показывает каретку.
HideCaret — прячет каретку.
DestroyCaret — удаляет каретку.
Кроме этих, еще имеется функция получения положения каретки (GetCaretPos) и функции установки и получения частоты мигания каретки (GetCaretBlinkTime) и (SetCaretBlinkTime).
Каретка — это обычно горизонтальная черточка или прямоугольник, имеющие размер символа, или вертикальная черточка. Вертикальная черточка рекомендуется при использовании пропорционального шрифта, такого как задаваемый по умолчанию системный шрифт Windows. Поскольку размер символов пропорционального шрифта не фиксирован, горизонтальной черточке и прямоугольнику невозможно задать размер символа.
Вы не можете просто создать каретку при обработке сообщения WM_CREATE и удалить ее при обработке сообщения WM_DESTROY. Каретка — это то, что называется "общесистемным ресурсом" (systemwide resource). Это означает, что в системе имеется только одна каретка. И, как результат, программа при необходимости вывода каретки на экран своего окна "заимствует" ее у системы.
Серьезно ли это необычное ограничение? Конечно, нет. Подумайте: появление каретки в окне имеет смысл только в том случае, если окно имеет фокус ввода. Каретка показывает пользователю, что он может вводить в программу текст. В каждый конкретный момент времени только одно окно имеет фокус ввода, поэтому для всей системы и нужна только одна каретка.
Обрабатывая сообщения WM_SETFOCUS и WM_KILLFOCUS, программа может определить, имеет ли она фокус ввода. Оконная процедура получает сообщение WM_SETFOCUS, когда получает фокус ввода, а сообщение WM_KILLFOCUS, когда теряет фокус ввода. Эти сообщения приходят попарно: оконная процедура получает сообщение WM_SETFOCUS всегда до того, как получит сообщение WM_KILLFOCUS, и она всегда получает одинаковое количество сообщений WM_SETFOCUS и WM_KILLFOCUS за время существования окна.
Основное правило использования каретки выглядит просто: оконная процедура вызывает функцию CreateCaret при обработке сообщения WM_SETFOCUS и функцию DestroyCaret при обработке сообщения WM_KILLFOCUS.
Имеется несколько других правил: каретка создается скрытой. После вызова функции CreateCaret, оконная процедура должна вызвать функцию ShowCaret, чтобы сделать каретку видимой. В дополнение к этому, оконная процедура, когда она рисует в своем окне при обработке сообщения, отличного от WM_PAINT, должна скрыть каретку, вызвав функцию HideCaret. После того как оконная процедура закончит рисовать в своем окне, она вызывает функцию ShowCaret, чтобы снова вывести каретку на экран. Функция HideCaret имеет дополнительный эффект: если вы несколько раз вызываете HideCaret, не вызывая при этом ShowCaret, то чтобы каретка снова стала видимой, вам придется такое же количество раз вызвать функцию ShowCaret.