Система координат и режим отображения
При выводе текста из программы MS-DOS вы пользовались простой системой координат, начало которой находилось в левом верхнем углу экрана. Ось x была направлена слева направо, ось y - сверху вниз. Так как в текстовом режиме на экране обычно помещаются 25 строк по 80 символов, возможные значения для x находились в пределах от 0 до 79, а для y - от 0 до 24.
При необходимости вывода текста из программы MS-DOS в графическом режиме вы должны были учитывать, что видеоконтроллер может работать в различных режимах с разным разрешением, например 640 x 480 в одном из режимов VGA или 1024 x 1200 в одном из режимов SVGA. Для каждого типа видеоконтроллера и для каждого видеорежима ваша программа при выводе текста должна была использовать отдельный набор шрифтов.
Приложение Windows может работать не только с физической, но и с логической системой координат. Вы можете произвольно определить положение начала координат в окне, задать свой собственный масштаб для координатных осей, определяя экранные координаты в миллиметрах или дюймах. Логическая система координат во многих случаях позволяет вам создавать приложения, независимые от конкретного типа видеоконтроллера или другого устройства графического вывода.
В процессе вывода изображения функции графического интерфейса GDI преобразуют логические координаты в физические. Для определения способа такого преобразования используется атрибут с названием режим отображения (mapping mode), который хранится в контексте устройства вывода.
Контекст устройства - это структура данных, связанная с тем или иным устройством ввода/вывода. Контекст устройства определяет различные параметры, используемые при работе с устройством, аналогично контексту отображения. В этом контексте хранится режим отображения, то есть указывается способ, с помощью которого логические координаты отображаются в физические.
Для указания режима отображения в файле windows.h определены символьные константы с префиксом MM_ (от Mapping Mode - режим отображения). При создании контекста устройства по умолчанию устанавливается режим отображения, обозначаемый как MM_TEXT.
При выводе текста мы будем использовать именно этот режим отображения.
В режиме отображения MM_TEXT используются логическая система координат, полностью эквивалентная физической. Логическое начало координат (0, 0) соответствует физическому началу координат устройства (0, 0). Каждая единица по оси x или y соответствует одному пикселу экрана.
В нашем примере мы вывели строку текста, использовав логические координаты (10, 20):
TextOut(hdc, 10, 20, "Сообщение WM_PAINT", 18);
При использовании режима отображения MM_TEXT в качестве начала координат берется верхняя левая точка устройства вывода. В нашем случае устройством вывода является главное окно приложения, поэтому начало координат (0, 0) находится в верхнем левом углу главного окна приложения. Текст будет выведен начиная с точки (10, 20) в логической системе координат, связанной с главным окном приложения.
Однако как будет расположен текст относительно точки (10, 20)?
Если очертить строку текста воображаемым прямоугольником, то по умолчанию в точке (10, 20) будет находиться верхний левый угол этого прямоугольника (рис. 2.1).
Рис. 2.1. Координаты текстовой строки
В контексте отображения можно задать так называемый режим выравнивания текста (text alignment mode). По умолчанию используется выравнивание на левую границу, причем координаты вывода текста указывают верхнюю границу воображаемого прямоугольника, охватывающего текст.
При помощи функции SetTextAlign можно изменить режим выравнивания. Приведем прототип функции:
UINT WINAPI SetTextAlign(HDC hdc, UINT fuAlign);
Функция SetTextAlign возвращает старое значение режима выравнивания. Ключевое слово WINAPI определено в файле windows.h следующим образом:
#define WINAPI _far _pascal
Как и все функции программного интерфейса Windows версии 3.1 для компьютеров с процессорами фирмы Intel, функция SetTextAlign использует при передаче параметров соглашение языка Паскаль и является дальней функцией.
Первый параметр функции (hdc) указывает идентификатор контекста отображения, для которого надо изменить выравнивание.
Это тот самый идентификатор, который возвращается функцией BeginPaint при обработке сообщения WM_PAINT.
Второй параметр (fuAlign) указывает новый режим выравнивания и задается при помощи трех групп флагов. Символические имена флагов определены в файле windows.h и начинаются с префикса TA_.
Первая группа флагов отвечает за выравнивание текстовой строки по горизонтали:
Флаг | Описание |
TA_LEFT | Выравнивание по левой границе. Координаты соответствуют левой границе воображаемого прямоугольника, охватывающего текст (используется по умолчанию) |
TA_CENTER | Выравнивание по центру. Координаты соответствуют центру воображаемого прямоугольника, охватывающего текст |
TA_RIGHT | Выравнивание по правой границе |
Флаг | Описание |
TA_TOP | Выравнивание по верхней границе. Координаты соответствуют верхней границе воображаемого прямоугольника, охватывающего текст (используется по умолчанию) |
TA_BASELINE | Выравнивание по базовой линии выбранного шрифта |
TA_BOTTOM | Выравнивание по нижней границе |
Флаг | Описание |
TA_NOUPDATECP | Не изменять значение текущей позиции вывода текста (используется по умолчанию) |
TA_UPDATECP | После использования функций TextOut и ExtTextOut вычислить новое значение текущей позиции вывода текста |
Из каждой группы флагов можно использовать только один, например:
SetTextAlign(hdc, TA_CENTER | TA_BASELINE | TA_UPDATECP);
Если задан режим выравнивания TA_UPDATECP, функция TextOut начинает вывод текста с текущей позиции, игнорируя параметры, определяющие расположение текста в окне.
В любой момент времени вы можете определить текущий режим выравнивания, вызвав функцию GetTextAlign:
UINT GetTextAlign(hdc);
Эта функция возвращает текущий режим отображения для контекста, указанного функции в качестве параметра.
Небольшое замечание относительно типа данных UINT. Для операционной системы Windows этот тип данных определен следующим образом:
typedef unsigned int UINT;
Однако не следует думать, что для операционной системы Windows NT будет использовано такое же определение. Поэтому для беззнаковых данных размером в одно машинное слово следует пользоваться типом UINT, но не unsigned int. При этом у вас будет меньше проблем с переносом ваших приложений в другую среду, отличную от Windows версии 3.1.