Вывод текста является одной из основных задач, которую приходится решать в программе при организации вывода данных. Речь пойдет о выводе текста с использованием Windows API функций. Данная статья, безусловно не претендует на полноту обзора этой тематики, но о некоторых "подводных камнях" я все же расскажу.
Функции, которые позволяют это выполнять, весьма разнообразны, и использовать их, как Вы уже поняли, можно в разных ситуациях и случаях, и собственно говоря, именно Вам и решать, какие использовать. Кроме функций, которые непосредственно выводят текст, также существует внушительный список "подсобных" функций.
Давайте глянем на tCanvas. В этом классе реализовано только две функции TextOut и TextRect. Когда задача стоит просто в выводе текста на цветном фоне (например, combo box цветов), то функций этого класса предостаточно, и в большинстве случаев я ими и пользуюсь. Но давайте заглянем за ширму. Функция TextOut использует одноименную функцию Windows, а TextRect использует функцию ExtTextOut, т.е. если на прямую вызывать функции Windows, можно получить тот же результат. Кроме того, в этих функциях есть передаваемые параметры, которые класс прячет, использование которых в определенных ситуациях не может быть не нужным и полезным. Формат функций я буду приводить из модуля windows.pas поставляемый с Delphi 3.
function TextOut(DC: HDC; X, Y: Integer; Str: PChar; Count:
Integer): BOOL;
Справочную информацию о передаваемых параметрах Вы сможете посмотреть в файле справки, но давайте я первый раз все же расскажу. Все GDI функции вывода имеют параметр DC - контекст устройства, на который нужно нарисовать. Естественно, Canvas подставляет туда Canvas.Handle. Если Вы хотите нарисовать на чем-то другом, то должны самостоятельно получить контекст устройства функциями, типа GetDC. Не забывайте (!) освобождать ресурсы функцией ReleaseDC.
X, Y - привязочные координаты, относительно которых происходит прорисовка. По умолчанию, привязка выполнена к левому верхнему углу. Я конечно немного не правильно выразился - в Windows принято понятие "выравнивание", а не "привязка". Оно настраивается через функцию SetTextAlign, но о ней чуть позже.
Str - переменная, которая содержит выводимый текст, а Count - длина этого текста. В качестве переменной Str можно использовать переменную, типа array [0..n] of Chat; можно передавать просто текст: 'Пример текста'. Если текст находится у Вас в переменной типа string то нужно произвести приведение типов: PChar(VarString).
function ExtTextOut(DC: HDC; X, Y: Integer; Options: Longint;
Rect: PRect; Str: PChar; Count: Longint; Dx: PInteger): BOOL;
Как видно уже с самого названия и предаваемых параметров, функция имеет гораздо больше возможностей, нежели предыдущая. Прежде всего, текст выводится в прямоугольнике, т.е. как бы сперва выводится прямоугольник, а затем в нем текст, но гораздо быстрее, чем это производилось бы двумя функциями.
Если значение Options будет содержать ETO_CLIPPED, то текст будет виден только в указанном прямоугольнике. Заметьте, что в функцию передается PRect. Это означает, что параметр может быть пустым, т.е. nil. В этом случае, функция будет работать аналогично TextOut. Если вы используете переменную r:tRect, то в функцию должны передать @r.
Выравнивание также, устанавливается предварительно при помощи SetTextAlign.
Наиболее интересен параметр DX. Это ссылка на массив, типа array [0..n] of integer, где каждый элемент является шириной символа. Настоящая ширина может отличатся от указанного значения. Это можно использовать, например, для имитации моноширного шрифта, или для сжатия текста таким образом, чтоб он помещался в отводимую область.
function DrawText(hDC: HDC; lpString: PChar; nCount: Integer;
var lpRect: TRect; uFormat: UINT): Integer;
В отличии от предыдущих функций, функция DrawText не имеет параметров X, Y и использует для руководства координат параметр lpRect. Заметим, что этот параметр является переменной, т.к. функция может модифицировать значения, если ее вызвать с параметром uFormat равным DT_CALCRECT, при этом прорисовка не будет осуществлятся. Параметр uFormat может включать в себя все значения выравнивания по этому предварительной глобальной настройки при помощи SetTextAlign не требуется.
По умолчанию текст, который не вместится в lpRect будет обрезаться. Чтобы этого не происходило, в параметре uFormat используйте DT_NOCLIP.
Используйте DT_WORDBREAK, если необходимо отобразить текст в несколько строк. Без этого параметра, даже если в строке есть символ #13 (перевод строки), все равно текст будет выводится в одну строку. При использовании значения DT_CALCRECT и DT_WORDBREAK изменятся будет lpRect.bottom, без DT_WORDBREAK - lpRect.right.
По-прежнему есть проблема с вертикальным выравниванием по центру (DT_VCENTER). Оно работает только для однострочного текста, т.е. для многострочного текста сперва придется вычислить lpRect, а затем изменив lpRect.top и lpRect.bottom, добиться желаемого результата.
- Назад
- Вперёд >>
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!