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

на главную - закладки

Жанры

О чём не пишут в книгах по 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');

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

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

Черный маг императора 3

Герда Александр
3. Черный маг императора
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Черный маг императора 3

Повелитель механического легиона. Том VIII

Лисицин Евгений
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VIII

Пипец Котенку! 3

Майерс Александр
3. РОС: Пипец Котенку!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Пипец Котенку! 3

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Боги, пиво и дурак. Том 6

Горина Юлия Николаевна
6. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 6

Болотник 2

Панченко Андрей Алексеевич
2. Болотник
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Болотник 2

Ты всё ещё моя

Тодорова Елена
4. Под запретом
Любовные романы:
современные любовные романы
7.00
рейтинг книги
Ты всё ещё моя

S-T-I-K-S. Пройти через туман

Елисеев Алексей Станиславович
Вселенная S-T-I-K-S
Фантастика:
боевая фантастика
7.00
рейтинг книги
S-T-I-K-S. Пройти через туман

Имя нам Легион. Том 4

Дорничев Дмитрий
4. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 4

Сводный гад

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

Я князь. Книга XVIII

Дрейк Сириус
18. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я князь. Книга XVIII

Королевская Академия Магии. Неестественный Отбор

Самсонова Наталья
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Королевская Академия Магии. Неестественный Отбор

Последняя Арена 6

Греков Сергей
6. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 6

Жребий некроманта. Надежда рода

Решетов Евгений Валерьевич
1. Жребий некроманта
Фантастика:
фэнтези
попаданцы
6.50
рейтинг книги
Жребий некроманта. Надежда рода