- •Оглавление
- •Глава 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
4.4.2 Сплайны Безье
Слово "сплайн" раньше относилось к гибкому куску дерева, резины или металла, который использовали для рисования кривых на листе бумаги. У нас такой прибор назывался лекалом. Например, если вы имели несколько отстоящих друг от друга точек, и вы хотели соединить их с помощью кривой (для интерполяции или экстраполяции), вы должны были, во-первых, отметить эти точки на чертежной бумаге, затем "привязать" сплайн к точкам и карандашом нарисовать кривую по сплайну так, как он был изогнут вокруг точек. (Пожалуйста, не смейтесь. Кажется, что так могло быть только в 19 веке, но хорошо известно, что механические сплайны использовались страховыми служащими, рассчитывавшими вероятность страхового случая, еще 30 лет назад.)
В наше время, конечно, сплайны — это математические выражения. Они имеют самые разные применения.
Сплайны Безье — одни из самых популярных в программировании компьютерной графики. Это сравнительно недавнее усовершенствование в арсенале графических средств, доступных на уровне операционной системы, и оно пришло с неожиданной стороны. В шестидесятых годах автомобильная компания Renault переходила от ручного проектирования кузовов автомобилей (что требовало много глины) к компьютерному. Требовался математический аппарат, и Пьер Безье предложил набор формул, оказавшихся очень полезными в этой работе.
С тех пор двумерная форма сплайна Безье показала себя как самая удобная кривая (после прямых линий и эллипсов) в компьютерной графике. Например, в языке PostScript сплайны Безье используются для всех кривых — эллиптические линии аппроксимируются из сплайнов Безье. Кривые Безье также используются для описания контуров символов различных шрифтов языка PostScript. (TrueType используют более простые и быстрые формы сплайнов.)
Простой двумерный сплайн Безье определяется четырьмя точками — двумя конечными и двумя контрольными. Концы кривой привязаны к двум конечным точкам. Контрольные точки выступают в роли магнитов для оттягивания кривой от прямой, соединяющей две крайние точки. Это лучше всего иллюстрируется интерактивной программой BEZIER.
Поскольку эта программа использует логику обработки мыши (об этом пойдет речь в главе 6), здесь не будут объясняться принципы ее функционирования (это было бы преждевременным). Вместо этого, поэкспериментируйте со сплайнами Безье. В этой программе две крайние точки установлены на половине высоты и на 1/4 и 3/4 ширины рабочей зоны окна. Двумя контрольными точками можно манипулировать: первой — нажатием левой кнопки мыши и перемещением мыши, второй — нажатием правой кнопки мыши и перемещением.
Кроме самого сплайна Безье программа также отображает слева прямую линию из первой контрольной точки в первую крайнюю точку (или начальную точку) и прямую линию из второй контрольной точки в конечную точку справа.
Сплайны Безье считаются полезными для компьютерного проектирования благодаря следующим характеристикам.
Во-первых, немного попрактиковавшись, вы можете легко манипулировать кривой для получения нужной формы.
Во-вторых, сплайны Безье очень легко управляются. В некоторых формах сплайнов кривая не может быть проведена через все определяющие точки. Сплайны Безье всегда "привязаны" к двум конечным точкам. (Это первое допущение, которое берет начало в формулах Безье.) Кроме того, существуют сплайны с бесконечными кривыми, которые имеют свои особенности. В компьютерном проектировании редко встречаются подобные типы сплайнов. Как правило, кривые Безье всегда ограничены четырехэлементной ломаной, называемой "выпуклым корпусом" (convex hull), которая получается соединением конечных и контрольных точек.
В-третьих, в сплайнах Безье существует связь между конечными и контрольными точками. Кривая всегда является касательной к прямой, соединяющей начальную точку и первую контрольную точку, и направленной в ту же сторону. (Это иллюстрируется программой BEZIER.) Кривая также является касательной к прямой, соединяющей конечную точку и вторую контрольную точку, и направленной в ту же сторону. Это еще два допущения на основе формул Безье.
В-четвертых, сплайны Безье в основном хорошо смотрятся. Понятно, что это критерий субъективный, но так считают многие.
До появления Windows 95 сплайны Безье создавались с помощью функции Polyline. Вам следовало также знать параметрические уравнения, описывающие сплайны Безье. Начальная точка (x0,y0), конечная точка (x3, y3). Две контрольные точки (x1, y1) и (x2, y2). Кривая, отображаемая в интервале t от 0 до 1 описывалась так:
x(t) = (1—t)3x0 + 3t(1—t)2x1 + 3t2(1—t)x2 +t3x3
y(t) = (1—t)3y0 + 3t(1—t)2y1 + 3t2(1—t)y2 +t3y3
Начиная с Windows 95 эти формулы знать не нужно. Для того, чтобы нарисовать одну или более связанных сплайнов Безье, используйте:
PolyBezier(hdc, pt, iCount);
Или
PolyBezierTo(hdc, pt, iCount);
В обоих случаях pt — массив структур типа POINT. В функции PolyBezier первые четыре точки идут в таком порядке: начальная точка, первая контрольная точка, вторая контрольная точка, конечная точка кривой Безье.
Каждая следующая кривая Безье требует три новых точки, поскольку начальная точка следующей кривой есть конечная точка предыдущей и т. д. Параметр iCount всегда равен единице плюс умноженному на три числу связанных кривых, которые вы хотите отобразить.
Функция PoliBezierTo использует текущее положение пера как начальную точку. Первый и все последующие сплайны требуют только три точки. Когда функция возвращает управление, текущая позиция пера устанавливается в конечную точку последней кривой.
Одно предупреждение: когда вы рисуете набор связанных сплайнов Безье, в точке связи будет плавный переход, только если вторая контрольная точка первой кривой Безье, конечная точка первой кривой (она же начальная точка второй кривой) и первая контрольная точка второй кривой лежат на одной прямой.