Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming_Windows_95_Part_I.pdf
Скачиваний:
96
Добавлен:
05.06.2014
Размер:
4.61 Mб
Скачать

154

надо знать правильный относительный размер образа. Некоторые изображения метафайлов могут иметь смысл только при конкретных физических размерах.

Как мы уже видели, последний параметр функции PlayEnhMetaFile — структура типа RECT, сообщающая GDI, где вы хотите нарисовать изображение в приемном контексте устройства. GDI растягивает образ так, чтобы он занял полностью указанный прямоугольник. Точный вывод изображений метафайлов — в заданных метрических размерах или с соответствующим относительным размером, требует использования информации о размерах из заголовка метафайла и точной установки размеров прямоугольника.

Это кажется достаточно сложным, но еще неизвестно, что может получиться при выводе изображения на принтер. Поэтому эту работу отложим до главы 15.

Текст и шрифты

Первая задача, которую мы решали в этой книге, используя программирование под Windows, была задача отображения простой строки текста в центре окна. В предыдущей главе мы пошли дальше и рассмотрели отображение на экране текста, состоящего из нескольких строк, и его прокрутку в окне. Теперь наступило время рассмотреть механизм отображения текста на экране более детально. Обсуждение задач, связанных с текстом, будет продолжено также в следующих главах. В главе 11 мы увидим, как использование библиотеки диалоговых окон общего пользования (Common Dialog Box library) значительно упрощает программы, давая пользователю возможность выбирать шрифты. В главе 15 мы исследуем проблемы отображения текста на экране в таком же виде, как на бумаге.

Вывод простого текста

Давайте сначала рассмотрим существующие в Windows для вывода текста различные функции, атрибуты контекста устройства, которые определяют вид текста, а также использование стандартных (stock) шрифтов.

Наиболее часто используемой функцией вывода текста является функция, которая использовалась в программе

SYSMETS в главе 3:

TextOut(hdc, xStart, yStart, pString, iCount);

Параметры xStart и yStart определяют начальную позицию строки в логических координатах. Обычно это точка, в которую Windows помещает верхний левый угол первого символа. TextOut требует также в качестве параметра дальний указатель на символьную строку и длину строки. Эта функция не распознает текстовые строки по NULL символу.

Смысл параметров xStart и yStart функции TextOut может быть изменен с помощью функции SetTextAlign. Флаги TA_LEFT, TA_RIGHT и TA_CENTER влияют на использование xStart при позиционировании строки по горизонтали. По умолчанию установлен флаг TA_LEFT. Если вы установите флаг TA_RIGHT при вызове функции SetTextAlign, то последующие вызовы функции TextOut устанавливают правую границу последнего символа строки в xStart. При заданном флаге TA_CENTER в xStart устанавливается середина строки.

Аналогично, флаги TA_TOP, TA_BOTTOM и TA_BASELINE влияют на вертикальное позиционирование строки. По умолчанию установлен флаг TA_TOP, который означает, что строка позиционируется таким образом, что yStart определяет вершину символов в строке. Использование флага TA_BOTTOM означает, что строка позиционируется над yStart. Вы можете использовать флаг TA_BASELINE для размещения строки таким образом, чтобы положение базовой линии определялось значением yStart. Базовая линия — это линия, ниже которой располагаются "хвостики" некоторых строчных букв (например, р, q, у).

Если вы вызываете SetTextAlign с флагом TA_UPDATECP, Windows игнорирует параметры xStart и yStart функции TextOut и вместо них использует текущее положение пера, ранее установленное функциями MoveToEx, LineTo или какой-либо другой функцией, изменяющей текущее положение пера. Флаг TA_UPDATECP также заставляет функцию TextOut изменить значение текущего положения пера на конец строки (при установленном флаге TA_LEFT) или на начало строки (при установленном флаге TA_RIGHT). Это используется для отображения строки текста с помощью последовательных вызовов функции TextOut. Когда горизонтальное позиционирование осуществляется при установленном флаге TA_CENTER, текущее положение пера не меняется после вызова функции TextOut.

Теперь давайте вспомним, как осуществлялся вывод на экран текста в виде столбцов в ряде программ SYSMETS в главе 3. Тогда каждый новый вызов функции TextOut использовался для отображения на экране одного столбца. В качестве альтернативы можно использовать функцию TabbedTextOut:

TabbedTextOut(hdc, xStart, yStart, pString, iCount,

iNumTabs, piTabStops, xTabOrigin);

155

Если строка символов содержит символы табуляции (‘\t’ или 0х09), то функция TabbedTextOut будет при выводе заменять символы табуляции числом пробелов, соответствующих списку целых параметров, которые вы передаете в функцию.

Первые пять параметров функции TabbedTextOut такие же, как у функции TextOut. Шестой параметр — число позиций табуляции, седьмой параметр — массив позиций табуляции, заданных в пикселях. Например, если средняя ширина символа 8 пикселей, и вы хотите установить позиции табуляции через каждые 5 символов, то этот список будет содержать числа 40, 80, 120 и т. д., в порядке возрастания.

Если шестой и седьмой параметры имеют значения 0 или NULL, то позиции табуляции устанавливаются через равные промежутки, равные восьмикратной средней ширине символов. Если шестой параметр равен 1, то седьмой параметр указывает на простое целое, которое каждый раз прибавляется для определения следующей позиции табуляции. (Например, если шестой параметр равен 1, а седьмой параметр является указателем на переменную, содержащую число 30, то позиции табуляции будут установлены так: 30, 60, 90, ... пикселей.) Последний параметр задает логическую координату по горизонтали точки отсчета позиций табуляции. Точка отсчета может совпадать с начальной позицией строки или отличаться от нее.

Примером другой расширенной функции вывода текста является функция ExtTextOut (приставка Ext означает расширенная):

ExtTextOut(hdc, xStart, yStart, iOptions, &rect, pString, iCount, pxDistance);

Пятый параметр этой функции является указателем на прямоугольную структуру. Эта структура является прямоугольником отсечения (если параметр iOptions имеет значение ETO_CLIPPED) или прямоугольником фона, который должен быть закрашен текущим цветом фона (если параметр iOptions имеет значение ETO_OPAQUE). Вы можете задавать обе опции или ни одной.

Последний параметр является массивом целых величин, задающих интервалы между соседними символами строки. Это позволяет программно сжимать или растягивать межсимвольный интервал, что иногда требуется для того, чтобы разместить отдельное слово в узком столбце. Если этот параметр имеет значение NULL, то устанавливается значение межсимвольного интервала по умолчанию.

Одной из функций вывода текста более высокого уровня является функция DrawText, которую мы использовали в программе HELLOWIN в главе 2. Вместо указания координат начальной позиции вы задаете структуру типа RECT, определяющую прямоугольник, в котором вы хотите разместить текст:

DrawText(hdc, pString, iCount, &rect, iFormat);

Так же, как и другие функции вывода текста, функция DrawText требует задания в качестве параметров дальнего указателя на символьную строку и длину строки. Однако, при использовании функции DrawText для вывода строки, оканчивающейся символом NULL, вы можете задать значение параметра iCount равным —1. В этом случае Windows вычислит длину строки.

Если параметр iFormat имеет значение 0, то Windows интерпретирует текст как ряд строк, разделенных символами возврата каретки (‘\r’ или 0х0D) или символами конца строки (‘\n’ или 0х0А). Вывод текста производится, начиная с верхнего левого угла прямоугольника. Возврат каретки или конец строки интерпретируется как символ "новая строка" (newline). В соответствии с этим Windows прерывает вывод текущей строки и начинает новую строку. Вывод новой строки начинается под предыдущей строкой от левого края прямоугольника с интервалом равным высоте символа в строке (без учета величины пространства, заданного в шрифте в качестве межстрочного интервала (external leading)). Любой текст, в том числе и части букв, которые при отображении на экране попадают правее или ниже границ прямоугольника, отсекаются.

Вы можете изменить действие функции DrawText по умолчанию, задав значение параметра iFormat, как комбинацию одного или нескольких флагов. Флаг DT_LEFT (установлен по умолчанию) задает выравнивание выводимого текста влево, флаг DT_RIGHT — выравнивание вправо, флаг DT_CENTER — выравнивание по центру относительно левой и правой сторон прямоугольника. Поскольку флаг DT_LEFT имеет значение 0, вы можете не задавать его значение в явном виде, если хотите, чтобы весь выводимый текст был выровнен влево.

Если вы не хотите, чтобы символы возврата каретки и символы конца строки интерпретировались как символы начала новой строки, вы можете включить идентификатор DT_SINGLELINE. В этом случае Windows интерпретирует символы возврата каретки и конца строки как отображаемые символы, а не как управляющие символы. Если вы используете идентификатор DT_SINGLELINE, вам необходимо также задать положение строки по вертикали: вверху прямоугольника (флаг DT_TOP, включен по умолчанию), внизу прямоугольника (флаг DT_BOTTOM) или посередине между верхней и нижней границами прямоугольника вывода (флаг

DT_VCENTER).

Когда на экран выводится текст, состоящий из нескольких строк, Windows в обычном режиме заканчивает строки, только встретив символ возврата каретки или символ конца строки. Однако, если строка оказывается длиннее, чем ширина прямоугольника вывода, вы можете использовать флаг DT_WORDBREAK. В этом случае Windows будет

156

обрывать строки в конце слов внутри строки. При выводе любого текста (состоящего из одной строки или многострочного) Windows отсекает ту часть текста, которая попадает за пределы прямоугольника вывода. Вы можете избежать этой ситуации, включив флаг DT_NOCLIP, который также ускоряет выполнение функции. Когда Windows осуществляет вывод на экран текста, состоящего из нескольких строк, то межстрочный интервал обычно выбирается равным высоте символа без учета величины пространства, заданного в шрифте, как межстрочный интервал. Если вы хотите, чтобы величина этого пространства была включена в межстрочный интервал, то вы можете использовать флаг DT_EXTERNALLEADING.

Если текст содержит символы табуляции (‘\t’ или 0х09), вам необходимо включить флаг DT_EXPANDTABS. По умолчанию позиции табуляции установлены через каждые восемь символьных позиций. Вы можете задать разные позиции табуляции, используя флаг DT_TABSTOP. В этом случае старший байт параметра iFormat содержит число символьных позиций для каждой новой позиции табуляции. Однако, здесь рекомендуется избегать использования флага DT_TABSTOP, поскольку старший байт параметра iFormat используется также для некоторых других флагов.

Атрибуты контекста устройства и текст

Некоторые атрибуты контекста устройства влияют на вид выводимого текста. В контексте устройства по умолчанию для текста задан черный цвет, но вы можете изменить его с помощью функции:

SetTextColor(hdc, rgbColor);

Так же, как для цвета пера и цвета штриховой кисти, Windows преобразует значение параметра rgbColor в чистый цвет. Вы можете определить цвет выводимого текста, вызывая функцию GetTextColor.

Пространство между строками текста закрашивается на основании установленных режима фона и цвета фона. Вы можете изменить режим фона, используя функцию:

SetBkMode(hdc, iMode);

где параметр iMode имеет значение OPAQUE или TRANSPARENT. По умолчанию режим фона установлен равным OPAQUE. Это означает, что Windows закрашивает пространство между строками текста цветом фона. Вы можете изменить цвет фона с помощью функции:

SetBkColor(hdc, rgbColor);

Значение параметра rgbColor преобразуется в значение чистого цвета. По умолчанию задан белый цвет фона. Если режим фона имеет значение TRANSPARENT, то Windows игнорирует цвет фона и не закрашивает пространство между строками. Windows также использует режим фона и цвет фона для закрашивания пространства между точечными и штриховыми линиями, а также пространства между штрихами штриховых кистей, как уже обсуждалось ранее.

Многие программы под Windows задают кисть WHITE_BRUSH, которую Windows использует для закрашивания фона окна. Кисть определяется в структуре класса окна. Кроме того, можно сделать цвет окна вашей программы совпадающим с системными цветами, которые пользователь может установить в программе Control Panel (панель управления). В этом случае вы задаете цвет фона в структуре WNDCLASS таким образом:

wndclass.hbrBackground =(HBRUSH)(COLOR_WINDOW + 1);

Когда вы хотите вывести текст в рабочей области, вы можете установить цвет текста и цвет фона, используя текущие системные цвета:

SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));

SetBkColor(hdc, GetSysColor(COLOR_WINDOW));

Можно сделать так, чтобы ваша программа отслеживала изменение системных цветов:

case WM_SYSCOLORCHANGE : InvalidateRect(hwnd, NULL, TRUE); break;

Другим атрибутом контекста устройства, определяющим вид текста, является межсимвольный интервал. По умолчанию он установлен в 0, что означает отсутствие интервала между соседними символами. Вы можете задать межсимвольный интервал, используя функцию:

SetTextCharacterExtra(hdc, iExtra);

Значение параметра iExtra задается в логических единицах. Windows преобразует его до ближайшего значения в пикселях, которое может быть и 0. Если вы зададите значение параметра iExtra отрицательным (например, чтобы прижать символы ближе друг к другу), Windows использует абсолютное значение заданного числа: вы не можете сделать эту величину меньше 0. Вы можете получить текущее значение межсимвольного интервала, используя

157

функцию GetTextCharacterExtra. Windows предварительно преобразует возвращаемое значение межсимвольного интервала из пикселей в логические единицы.

Использование стандартных шрифтов

Когда вы вызываете одну из функций вывода текста TextOut, TabbedTextOut, ExtTextOut или DrawText, Windows использует шрифт, выбранный в момент вызова функции в контексте устройства. Шрифт определяет особенности изображения символов и размер. Простейший путь выводить текст различными шрифтами состоит в использовании стандартных шрифтов, поддерживаемых Windows. Однако, их список достаточно ограничен.

Вы можете получить описатель стандартного шрифта, вызывая функцию:

hFont = GetStockObject(iFont);

где параметр iFont — один из нескольких идентификаторов, только два из которых обычно используются. Вы можете затем выбрать шрифт в контекст устройства:

SelectObject(hdc, hFont);

Вы можете осуществить это и за один шаг:

SelectObject(hdc, GetStockObject(iFont));

Функция GetStockObject — это та же самая функция, которую мы использовали ранее для получения стандартных перьев и кистей; функцию SelectObject мы использовали при выборе перьев, кистей, битовых образов и регионов в контекст устройства.

Шрифт, выбранный в контекст устройства по умолчанию, называется системным шрифтом и определяется параметром SYSTEM_FONT функции GetStockObject. Это пропорциональный шрифт, состоящий из ANSI символов, который Windows использует для вывода текста в меню, диалоговых окнах, окнах подсказок и в строках заголовков окон. Задание параметра SYSTEM_FIXED_FONT функции GetStockObject (которое было сделано в программе WHATSIZE ранее в этой главе) дает вам описатель шрифта фиксированной ширины (fixed-pitch), совместимого с системным шрифтом, который использовался в более ранних (до 3.0) версиях Windows. Это очень удобно, когда все символы шрифта имеют одинаковую ширину.

Когда вы выбираете новый шрифт в контекст устройства, вы должны вычислить высоту символа шрифта и среднюю ширину символа, используя функцию GetTextMetrics. Если вы выбираете пропорциональный шрифт, то вы должны помнить, что средняя ширина символа — это действительно среднее значение, т. е. некоторые символы более широкие, а некоторые более узкие. Далее в этой главе мы рассмотрим, как определить общую ширину строки, состоящую из символов различной ширины.

Несмотря на то, что функция GetStockObject несомненно предлагает простейший доступ к различным шрифтам, вы не имеете возможности управлять шрифтами, которые предлагает вам Windows. Вскоре вы увидите, каким образом вы можете точно задать желаемый вид и размер символов.

Типы шрифтов

Windows поддерживает две больших категории шрифтов — " шрифты GDI " и "шрифты устройства" (device fonts). Шрифты GDI хранятся в файлах на вашем жестком диске. Шрифты устройства соответствуют конкретному устройству вывода. Например, большинство принтеров имеет набор встроенных шрифтов устройства.

Шрифты GDI могут быть одного из трех типов — растровые шрифты, векторные шрифты и шрифты типа True Type.

Растровый шрифт иногда называют шрифтом битовых шаблонов, т. к. в файле растрового шрифта каждый символ хранится в виде битового шаблона. Каждый растровый шрифт разработан для определенного относительного размера пикселя дисплея и размера символа. Windows может создавать символы больших размеров из растровых шрифтов GDI, просто дублируя строки или колонки пикселей. Однако, это может быть сделано только целое количество раз и до определенного предела. По этой причине растровые шрифты GDI называют "немасштабируемыми" (nonscalable) шрифтами. Они не могут быть растянуты или сжаты до произвольного размера. Основными преимуществами растровых шрифтов являются их быстрое отображение на экране и четкость (т. к. они были разработаны вручную, чтобы текст выглядел максимально разборчиво).

В более ранних версиях (до 3.1) Windows поддерживала, кроме шрифтов GDI, еще и векторные шрифты. Векторные шрифты определены как набор соединенных друг с другом отрезков прямых (connect-the-dots). Векторные шрифты легко масштабируются в широких пределах, т. е. один и тот же шрифт может быть использован в графических устройствах вывода с любой разрешающей способностью, и эти шрифты могут быть увеличены или уменьшены до любого размера. Однако, эти шрифты имеют более низкую скорость отображения, плохую четкость при маленьких размерах, а при использовании больших размеров символы выглядят очень

Соседние файлы в предмете Операционные системы