Чтение онлайн

на главную

Жанры

О чём не пишут в книгах по Delphi

Григорьев Антон Борисович

Шрифт:

В оригинале параметры-массивы функции

PolyPolygon
объявлены как указатели на типы элементов массива. В модуле
Windows
при импорте этой функции, как это часто бывает в подобных случаях, эти параметры стали нетипизированными параметрами-переменными. В нашем случае массивы объявлены как локальные типизированные константы. По сути, в этом случае они являются глобальными переменными с локальной областью видимости, т.е., как обычные глобальные переменные, хранятся в сегменте данных и существуют на протяжении всего времени работы программы, но компилятор разрешает использовать их только внутри той процедуры, в которой они объявлены. И, несмотря на то, что по сути такие "константы" являются переменными, компилятор их рассматривает как константы и запрещает подставлять там, где
требуются параметры-переменные. Поэтому приходится "обманывать" компилятор, получая указатель на эти константы, а затем разыменовывая его. Если бы наши массивы хранились в обычных переменных, нужды прибегать к такому приему не было бы.

Нетрудно убедиться, что первые четыре элемента массива

Pts
содержат координаты вершин внешнего квадрата рамки, последние четыре — внутреннего квадрата.
Массив
Cnt, соответственно, содержит два элемента, оба из которых имеют значение 4. Это означает, что в нашей фигуре два замкнутых контура, и оба содержат по четыре вершины. Порядок следования вершин во внешнем квадрате — по часовой стрелке, во внутреннем — против. Это имеет значение, если выбран режим заливки
WINDING
, тогда направления обхода контуров должны быть противоположными, иначе отверстие тоже окажется закрашенным. Для режима заливки
ALTERNATE
направление обхода контуров не имеет значения.

Далее программа

GDIDraw
демонстрирует работу функции
InvertRect
, которая инвертирует цвета в заданной прямоугольной области контекста устройства. Для того чтобы это было нагляднее, мы сначала выведем на форму загруженный в
OnCreate
рисунок (только на этот раз без региона отсечения) и инвертируем область, частично пересекающуюся с областью рисунка (листинг 1.37).

Листинг 1.37. Пример использования функции
InvertRect

// Следующая группа команд выводит рисунок и конвертирует

// его часть

Canvas.Draw(300, 220, FBitmap);

// Функция InvertRect делает указанный прямоугольник

// "негативом".

InvertRect(Canvas.Handle, Rect(320, 240, 620, 340));

Ещё одна забавная функция GDI, которая почему-то не нашла отражения в классе

TCanvas
— это
GrayString
. Она предназначена для вывода "серого" текста, т.е. текста, который по яркости находится посредине между черным и белым. Обычно для этого просто устанавливается цвет
RGB(128, 128, 128)
, но некоторые черно-белые устройства не поддерживают полутона (это касается, прежде всего, старых моделей принтеров) — именно на них и ориентирована функция
GrayString
. Она позволяет рисовать серый текст произвольным образом с помощью функции обратного вызова, но эту функцию можно не указывать, и тогда рисование осуществляется функцией
TextOut
. Но при этом текст выводится через промежуточную растровую картинку в памяти, что обеспечивает полупрозрачность текста, т.к. закрашиваются не все пикселы, а только половина в шахматном порядке. На черно-белых принтерах с большим разрешением это действительно выглядит как серый текст, на экране же можно получать "полупрозрачные" надписи. Пример использования функции
GrayString
приведен в листинге 1.38.

Листинг 1.38. Пример использования функции
GrayString

// Следующая группа команд выводит "полупрозрачную"

// надпись "Windows API"

Canvas.Brush.Color := clBlue;

// Функция GrayString при выводе текста закрашивает

// заданной кистью не все пикселы подряд, а в шахматном

// порядке, оставляя остальные нетронутыми. Это создает

// эффект полупрозрачности.

Canvas.Font.Name := 'Times New Roman';

Canvas.Font.Style := [fsBold];

Canvas.Font.Height := 69;

GrayString(Canvas.Handle, Canvas.Brush.Handle, nil, LPARAM(PChar('Windows API')), 0, 20, 350, 0, 0);

Обратите

внимание на второй параметр — через него передается дескриптор кисти, с помощью которой будет осуществляться закраска пикселов в выводимой строке. Функция
GrayString
игнорирует ту кисть, которая выбрана в контексте устройства и использует свою. Здесь для простоты мы передаем ей кисть контекста устройства, но, в принципе, это могла бы быть любая другая кисть. Третий параметр — это указатель на функцию обратного вызова. В нашем случае он равен
nil
, что указывает на использование функции
TextOut
. Четвертый параметр имеет тип
LPARAM
и содержит произвольные данные, которые передаются функции обратного вызова. В случае использования
TextOut
это интерпретируется как указатель на строку, которую нужно вывести, поэтому здесь приходится возиться с приведением типов. Пятый параметр содержит длину выводимой строки. Это очень характерно для функций GDI, предназначенных для вывода текста, конец строки в них определяется не обязательно по завершающему символу
#0
, можно вывести только часть строки, явно задав нужное число символов. Но этот же параметр можно сделать равным нулю (как в нашем случае), и тогда длина строки определяется обычным образом — по символу #0. Прочие параметры функции определяют координаты выводимой строки.

Последняя часть примера посвящена вопросу, который долгое время был очень популярен в форумах: как вывести текст, расположенный наклонно (в программе примером такого текста является надпись Sample, выведенная под углом 60 градусов). Это связано с тем, что только в BDS 2006 у класса TFont появилось свойство

Orientation
, позволяющее задавать направление текста (в справке BDS 2006 информация об этом свойстве отсутствует, она появляется только в справке Delphi 2007, но это свойство, тем не менее, есть и в BDS 2006, а также в Turbo Delphi). В более ранних версиях текст под углом можно было вывести только с помощью функций GDI, вручную создавая шрифт (листинг 1.9).

Листинг 1.39. Вывод текста под углом средствами GDI

// Следующая группа функций выводит надпись "Sample".

// повернутую на угол 60 градусов.

Canvas.Brush.Style := bsClear;

// При создании логического шрифта для контекста

// устройства следует в обязательном порядке указать

// угол поворота. Однако класс TFont игнорирует такую

// возможность, поэтому шрифт нужно создавать вручную.

// Чтобы выбрать шрифт в контексте устройства, легче

// всего присвоить его дескриптор свойству

// Canvas.Font.Handle. Параметры fdwItalic, fdwUnderline

// и fdwStrikeOut, согласно справке, могут принимать

// значения True или False, но имеют тип DWORD. Для

// С/C++ это не имеет значения - целый и логический типы

// в этих языках совместимы. Но в Delphi приходится

// использовать 0 и 1 вместо True и False. Угол поворота

// шрифта задается в десятых долях градуса, т.е.

// значение 600 означает 60 градусов.

Canvas.Font.Handle := CreateFont(60, 0, 600, 600, FW_NORMAL, 0, 0, 0,

 ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,

 DEFAULT_QUALITY, DEFAULT_РIТСН, 'Times New Roman');

Canvas.TextOut(140, 320, 'Sample');

// Эта строка нужна для того, чтобы пример работал

Поделиться:
Популярные книги

Дайте поспать! Том III

Матисов Павел
3. Вечный Сон
Фантастика:
фэнтези
5.00
рейтинг книги
Дайте поспать! Том III

Путь Чести

Щукин Иван
3. Жизни Архимага
Фантастика:
фэнтези
боевая фантастика
6.43
рейтинг книги
Путь Чести

Энфис 2

Кронос Александр
2. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 2

Сумеречный Стрелок 2

Карелин Сергей Витальевич
2. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный Стрелок 2

Сводный гад

Рам Янка
2. Самбисты
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Сводный гад

Книга пяти колец. Том 3

Зайцев Константин
3. Книга пяти колец
Фантастика:
фэнтези
попаданцы
аниме
5.75
рейтинг книги
Книга пяти колец. Том 3

Диверсант

Вайс Александр
2. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Диверсант

Ученичество. Книга 2

Понарошку Евгений
2. Государственный маг
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ученичество. Книга 2

Титан империи 3

Артемов Александр Александрович
3. Титан Империи
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Титан империи 3

Последний попаданец 9

Зубов Константин
9. Последний попаданец
Фантастика:
юмористическая фантастика
рпг
5.00
рейтинг книги
Последний попаданец 9

Измена. Право на сына

Арская Арина
4. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на сына

Неестественный отбор.Трилогия

Грант Эдгар
Неестественный отбор
Детективы:
триллеры
6.40
рейтинг книги
Неестественный отбор.Трилогия

Хозяйка дома на холме

Скор Элен
1. Хозяйка своей судьбы
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка дома на холме

Гром над Академией. Часть 2

Машуков Тимур
3. Гром над миром
Фантастика:
боевая фантастика
5.50
рейтинг книги
Гром над Академией. Часть 2