- •Содержание
- •Глава 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
43
(invalid rectangle); иногда — "недействительного региона" (invalid region). Если еще один регион рабочей области становится недействительным перед обработкой сообщения WM_PAINT, Windows рассчитывает новый недействительный регион, который содержит оба эти региона и запоминает эту новую информацию в структуре информации о рисовании. Windows не помещает в очередь сообщений сразу несколько сообщений WM_PAINT.
Оконная процедура, вызывая функцию InvalidateRect, может задать недействительный прямоугольник в своей рабочей области. Если в очереди сообщений уже содержится сообщение WM_PAINT, Windows рассчитывает новый недействительный прямоугольник. В противном случае Windows помещает новое сообщение WM_PAINT в очередь сообщений. При принятии сообщения WM_PAINT (как мы позже увидим в этой главе), оконная процедура может получить координаты недействительного прямоугольника. Она также может получить эти координаты в любое другое время, вызвав функцию GetUpdateRect.
После того как оконная процедура вызывает функцию BeginPaint при обработке сообщения WM_PAINT, вся рабочая область становится действительной. Программа, вызвав функцию ValidateRect, также может сделать действительной любую прямоугольную зону в рабочей области. Если этот вызов делает действительной всю рабочую область, тогда любое сообщение WM_PAINT, имеющееся в это время в очереди сообщений, удаляется из нее и не обрабатывается.
Введение в графический интерфейс устройства (GDI)
Для рисования в рабочей области вашего окна, вы используете функции графического интерфейса устройства. (Обзор GDI ждет нас в следующей главе). В Windows имеется несколько функций GDI для вывода строк текста в рабочей области окна. В главе 2 вы уже встречались с функцией DrawText, но гораздо более популярной функцией является TextOut. Формат этой функции следующий:
TextOut(hdc, x, y, psString, iLength);
Функция TextOut выводит на экран строку символов. Параметр psString — это указатель на строку символов, а iLength — длина строки символов. Параметры x и y определяют начальную позицию строки символов в рамках рабочей области. (Более подробно об этом будет рассказано в дальнейшем.) Параметр hdc — это "описатель контекста устройства" (handle to a device context), являющийся важной частью GDI. Практически каждой функции GDI в качестве первого параметра необходим этот описатель.
Контекст устройства
Вспомните, описатель — это просто число, которое Windows использует для внутренней ссылки на объект. Вы получаете описатель от Windows и затем используете этот описатель в разных функциях. Описатель контекста устройства — это паспорт вашего окна для функций GDI. Этот описатель дает вам полную свободу при рисовании в рабочей области вашего окна, и вы можете сделать ее такой, как пожелаете.
Контекст устройства фактически является структурой данных, которая внутренне поддерживается GDI. Контекст устройства связан с конкретным устройством вывода информации, таким как принтер, плоттер или дисплей. Что касается дисплея, то в данном случае контекст устройства обычно связан с конкретным окном на экране.
Некоторые значения в контексте устройства являются графическими "атрибутами" (attributes). Эти атрибуты определяют некоторые особенности работы функций рисования GDI. Например, для функции TextOut эти атрибуты контекста устройства задают цвет текста, цвет фона для текста, процедуру преобразования координат x и y, передаваемых функции TextOut в координаты рабочей области, а также шрифт, используемый для вывода текста.
Когда программе необходимо начать рисование, она должна получить описатель контекста устройства. После окончания рисования программа должна освободить описатель. Когда программа освободит описатель, он становится недействительным и не должен далее использоваться. Во время обработки каждого отдельного сообщения программа должна получить и освободить описатель. За исключением описателя контекста устройства, созданного функцией CreateDC (эта функция не будет рассматриваться в данной главе), вам не следует хранить описатель контекста устройства в промежутке между обработкой различных сообщений.
В приложениях для Windows при подготовке процесса рисования на экране, обычно используются два метода получения описателя контекста устройства.
Получение описателя контекста устройства. Первый метод
Этот метод используется при обработке сообщений WM_PAINT. Применяются две функции: BeginPaint и EndPaint. Для этих двух функций требуется описатель окна (передаваемый в оконную процедуру в качестве параметра) и адрес переменной типа структуры PAINTSTRUCT. Программисты, пишущие программы для Windows, обычно называют эту структурную переменную ps и определяют ее внутри оконной процедуры следующим образом:
44
PAINTSTRUCT ps;
Во время обработки сообщения WM_PAINT оконная процедура сначала вызывает BeginPaint для заполнения полей структуры ps. Возвращаемым значением функции BeginPaint является описатель контекста устройства. Обычно он передается переменной с именем hdc. Эта переменная определяется в оконной процедуре следующим образом:
HDC hdc;
Тип данных HDC определяется как 32-разрядное беззнаковое целое. Затем программа может использовать функции GDI, например TextOut. Вызов функции EndPaint освобождает описатель контекста устройства.
Типовой процесс обработки сообщения WM_PAINT выглядит следующим образом:
case WM_PAINT:
hdc=BeginPaint(hwnd, &ps);
[использование функций GDI]
EndPaint(hwnd, &ps); return 0;
При обработке сообщения WM_PAINT в оконной процедуре функции BeginPaint и EndPaint должны обязательно вызываться парой. Если в оконной процедуре сообщения WM_PAINT не обрабатываются, то они должны передаваться в DefWindowProc (процедура обработки сообщений по умолчанию), реализованной в Windows.
DefWindowProc обрабатывает сообщения WM_PAINT следующим образом:
case WM_PAINT: BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); return 0;
Следующие одна за другой функции BeginPaint и EndPaint просто превращают ранее недействительный регион в действительный. Но нельзя делать следующее:
case WM_PAINT: |
// ОШИБКА!!! |
return 0; |
Windows помещает сообщение WM_PAINT в очередь сообщений, поскольку часть рабочей области окна недействительна (требует перерисовки). До тех пор пока вы не вызовете функции BeginPaint и EndPaint (или ValidateRect), Windows не сделает эту область действительной. Вместо этого Windows снова отправит вам сообщение WM_PAINT. И снова, и снова, и снова ...
Структура информации о рисовании
Ранее уже говорилось о структуре информации о рисовании, которая поддерживается в Windows для каждого окна. Это PAINTSTRUCT. Структура определяется так:
typedef struct tagPAINTSTRUCT
{
HDC |
hdc; |
BOOL |
fErase; |
RECT |
rcPaint; |
BOOL |
fRestore; |
BOOL |
fIncUpdate; |
BYTE |
rgbReserved[32]; |
} PAINTSTRUCT; |
|
Windows заполняет поля этой структуры, когда ваша программа вызывает BeginPaint. Вам в программе можно использовать только первые три поля структуры. Остальные используются Windows.
Поле hdc — это описатель контекста устройства. Возвращаемым значением функции BeginPaint также является описатель контекста устройства, и такая избыточность характерна для Windows.
В подавляющем большинстве случаев, в поле fErase установлен флаг TRUE (т. е., ненулевое значение), означающий, что Windows обновит фон недействительного прямоугольника. Windows перерисует фон, используя кисть, заданную в поле hbrBackground структуры WNDCLASSEX, которую вы использовали при регистрации класса окна во время инициализации WinMain. Многие программы для Windows используют белую кисть:
wndclass.hbrBackground =(HBRUSH) GetStockObject(WHITE_BRUSH);
Однако, если вы, вызывая функцию InvalidateRect, делаете недействительным прямоугольник рабочей зоны вашей программы, то последний параметр этой функции определяет, хотите ли вы стирать фон. Если этот параметр равен FALSE (т. е. 0), Windows не будет стирать фон и поле fErase также будет равно FALSE.
45
Поле rcPaint структуры PAINTSTRUCT — это структура типа RECT. Как вы знаете из главы 2, структура RECT определяет прямоугольник. В ней имеется четыре поля: left, top, right и bottom. Поле rcPaint структуры PAINTSTRUCT определяет границы недействительного прямоугольника, как показано на рис. 3.1. Значения заданы в пикселях относительно левого верхнего угла рабочей области. Недействительный прямоугольник — это та область, которую вы хотите перерисовать. Хотя программа для Windows может просто перерисовать всю рабочую область окна при получении сообщения WM_PAINT, перерисовка только той области окна, которая задана этим прямоугольником, экономит время.
0 |
left |
right |
0
top
Invalid rectangle
(недействительный
прямоугольник)
bottom
Client area
(рабочая область)
Рис. 3.1 Границы недействительного прямоугольника
Прямоугольник rcPaint в PAINTSTRUCT — это не только недействительный прямоугольник, это также и "отсекающий" (clipping) прямоугольник. Это означает, что Windows рисует только внутри отсекающего прямоугольника. (Или точнее, если недействительная зона не является прямоугольником, Windows рисует только внутри этой зоны.) Когда вы используете описатель контекста устройства из структуры PAINTSTRUCT, Windows не будет рисовать вне прямоугольника rcPaint.
Чтобы при обработке сообщения WM_PAINT рисовать вне прямоугольника rcPaint, вы можете сделать вызов:
InvalidateRect(hWnd, NULL, TRUE);
перед вызовом BeginPaint. Это сделает недействительной всю рабочую область и обновит ее фон. Если же значение последнего параметра будет равно FALSE, то фон обновляться не будет. Все что там было, останется неизменным.
В программе HELLOWIN из главы 2 мы не думали о недействительных или отсекающих прямоугольниках при обработке сообщения WM_PAINT. Если оказывалось, что область вывода текста на экран находится внутри недействительного прямоугольника, то функция DrawText перерисовывала ее. Если при обработке вызова DrawText Windows не находит такие области, на экран ничего не выводится. Но такой поиск требует времени. Программист, заботящийся об эффективности и быстродействии, захочет при обработке сообщений WM_PAINT использовать размеры недействительного прямоугольника, чтобы не обращаться лишний раз к вызовам GDI.
Получение описателя контекста устройства. Второй метод
Вы также можете получить описатель контекста устройства, если хотите рисовать в рабочей области при обработке отличных от WM_PAINT сообщений, или если вам необходим описатель контекста устройства для других целей, например, для получения информации о самом контексте устройства. Вызывайте GetDC для получения описателя контекста устройства и ReleaseDC, если он вам больше не нужен:
hdc=GetDC(hwnd);
[использование функций GDI]
ReleaseDC(hwnd, hdc);
46
Также как BeginPaint и EndPaint, функции GetDC и ReleaseDC следует вызывать парой. Если вы при обработке сообщения вызываете GetDC, то перед выходом из оконной процедуры необходимо вызвать ReleaseDC. Не вызывайте GetDC при обработке одного сообщения, а ReleaseDC при обработке другого.
В отличии от описателя контекста устройства, полученного из структуры PAINTSTRUCT, в описателе контекста устройства, возвращаемом функцией GetDC, определен отсекающий прямоугольник, равный всей рабочей области. Вы можете рисовать в любом месте рабочей области, а не только в недействительном прямоугольнике (если недействительный прямоугольник вообще определен). В отличии от BeginPaint, GetDC не делает действительными какие-либо недействительные зоны.
Как правило, вы будете использовать вызовы функций GetDC и ReleaseDC в ответ на сообщения от клавиатуры (например, в программах текстовых редакторов) или на сообщения от манипулятора мышь (например, в программах рисования). Они позволяют обновлять рабочую область непосредственно в ответ на пользовательский ввод информации с клавиатуры или с помощью мыши, при этом специально делать недействительной часть окна для выдачи сообщений WM_PAINT. Однако, в ваших программах должно содержаться достаточно информации для обновления экрана в любой момент, когда вы получаете сообщение WM_PAINT.
Функция TextOut. Подробности
Когда вы получаете описатель контекста устройства, Windows заполняет внутреннюю структуру контекста устройства задаваемыми по умолчанию значениями. Как вы увидите в следующих главах, эти задаваемые по умолчанию значения можно изменить с помощью функций GDI. Из тех функций GDI, которые нас интересуют прямо сейчас, рассмотрим TextOut:
TextOut(hdc, x, y, psString, iLength);
Давайте исследуем эту функцию более подробно.
Первый параметр — это описатель контекста устройства, являющийся возвращаемым значением либо функции GetDC, либо функции BeginPaint, полученный при обработке сообщения WM_PAINT.
Атрибуты контекста устройства управляют характеристиками выводимого на экран текста. Например, один атрибут контекста устройства задает цвет текста. Цвет, задаваемый по умолчанию — черный. Контекст устройства по умолчанию также определяет цвет фона — белый. Когда программа выводит текст на экран, Windows использует этот цвет фона для заполнения прямоугольной зоны вокруг каждого символа, эта зона называется знакоместом (character box).
Цвет фона текста не является цветом фона, который вы установили при определении класса окна. Фон в классе окна — это кисть, являющаяся шаблоном, которая может иметь, а может и не иметь чистый (без полутонов) цвет, и которую Windows использует для закрашивания рабочей области. Фон в классе окна не имеет отношения к структуре контекста устройства. При определении структуры класса окна в большинстве приложений Windows используется кисть WHITE_BRUSH, поэтому задаваемый по умолчанию в контексте устройства цвет фона оказывается таким же, как и цвет кисти, используемой Windows для закрашивания фона рабочей области.
Параметр psString — это указатель на символьную строку, а iLength — длина строки, т. е., число символов в строке. Строка не должна содержать никаких управляющих символов ASCII, таких как возврат каретки, перевод строки, табуляция или забой. Windows выводит такие управляющие символы в виде прямоугольников или закрашенных блоков. TextOut не определяет конца строки по нулевому символу, и поэтому для задания ее длины необходим параметр iLength.
Значения x и y в TextOut определяют точку начала строки текста внутри рабочей области. Значение x в горизонтальном направлении, значение y в вертикальном. Левый верхний угол первого символа строки имеет координаты
(x, y). В контексте устройства по умолчанию исходной точкой отсчета (когда x и y равны 0) является левый верхний угол рабочей области. Если x и y в TextOut равны 0, строка текста начнет выводиться, начиная с левого верхнего угла рабочей области.
Координаты GDI в документации упоминаются как "логические координаты" (logical coordinates). Что именно это означает, мы более подробно изучим в следующей главе. Сейчас достаточно знать, что в Windows имеются различные "режимы отображения" (mapping mode), которые определяют, как логические координаты, заданные в функциях GDI, преобразуются в реальные физические координаты дисплея. Режим отображения определяется в контексте устройства. Задаваемый по умолчанию режим отображения называется MM_TEXT (идентификатор, заданный в заголовочных файлах Windows). В режиме отображения MM_TEXT логические единицы соответствуют физическим единицам, каковыми являются пиксели, задаваемые относительно левого верхнего угла рабочей области. Значения по координате x увеличиваются при движении вправо по рабочей области, а по y — при движении вниз. (См. рис. 3.2.) Система координат режима MM_TEXT эквивалентна системе координат, которую Windows использует для определения недействительного прямоугольника в структуре PAINTSTRUCT. Это очень удобно. (Однако это не относится к другим режимам отображения).