В системе определены два специальных значения цвета: CLR_NONE
($1FFFFFFF
) и CLR_DEFAULT
($20000000
). Они используются только в списках рисунков (image lists) для задания фонового и накладываемого цветов при выводе рисунка. CLR_NONE
задаёт отсутствие фонового или накладываемого цвета (в этом случае соответствующий визуальный эффект не применяется). CLR_DEFAULT
— установка цвета, заданного для всего списка.
В VCL для передачи цвета предусмотрен тип TColor
, определенный в модуле Graphics
. Это 4-байтное число, множество значений которого является множеством значений типа TColorRef
. К системным форматам 0, 1 и 2 добавлен формат 255. Если старший байт значения типа TColor
равен 255, то младший байт интерпретируется как индекс системного цвета (второй и третий байт при этом не учитываются). Системные цвета — это цвета, используемые системой для рисования различных элементов интерфейса пользователя. Конкретные RGB-значения этих цветов зависят от версии Windows и от текущей цветовой схемы. RGB-значение системного цвета можно получить с помощью функции GetSysColor
. 255-й формат TColor освобождает от необходимости явного вызова данной функции.
Для типа TColor определен ряд констант, облегчающих его использование. Некоторые из них соответствуют определенному RGB-цвету (clWhite
, clBlack
, clRed
и т. п.), другие — определенному системному цвету (clWindow
, clHighlight
, clBtnFace
и т. п.). Значения RGB-цветов определены в нулевом формате. Это не приведет к потере точности цветопередачи в режимах с палитрой, т. к. константы определены только для 16-ти основных цветов, которые обязательно присутствуют в системной палитре. Значениям CLR_NONE
и CLR_DEFAULT
соответствуют константы clNone
и clDefault
. Они служат (помимо списков рисунков) для задания прозрачного цвета в растровом изображении. Если этот цвет равен clNone
, изображение считается непрозрачным, если clDefault
, в качестве прозрачного цвета берется цвет левого нижнего пиксела.
Везде, где требуется значение типа TColor, можно подставлять TColorRef
, т. е. всем свойствам и параметрам методов класса TCanvas
, имеющим тип TColor
можно присваивать те значения TColorRef
, которые сформированы функциями API. Обратное неверно: API-функции не умеют обращаться с 255-м форматом TColor
. Преобразование из TColor
в TColorRef
осуществляется с помощью функции ColorToRGB
. Значения нулевого, первого и второго формата, а также clNone
и clDefault
она оставляет без изменения, а значения 255-го формата приводит к нулевому с помощью функции GetSysColor
. Эту функцию следует использовать при передаче значении типа TColor
в функции GDI.
Применение кистей, перьев и шрифтов в GDI принципиально отличается от того, как это делается в VCL. Класс TCanvas
имеет свойства Pen
, Brush
, и Font
, изменение свойств которых приводит к выбору того или иного пера, кисти, шрифта. В GDI эти объекты самостоятельны, должны создаваться, получать свой дескриптор, "выбираться" в нужный контекст устройства с помощью функции SelectObject
и уничтожаться после использования. Причем удалять можно только те объекты, которые не выбраны ни в одном контексте. Есть также несколько стандартных объектов, которые не нужно ни создавать, ни удалять. Их дескрипторы можно получить с помощью функции GetStockObject
. Для примера рассмотрим фрагмент программы, рисующей на контексте с дескриптором DC две линии: синюю и красную (листинг 1.18). В этом фрагменте используется то, что функция SelectObject
возвращает дескриптор объекта, родственного выбираемому, который был выбран ранее. Так, при выборе нового пера она вернет дескриптор того пера, которое было выбрано до этого.
SelectObject(DC, CreatePen(PS_SOLID, 1, RGB(255, 0, 0)));
MoveToEx(DC, 100, 100, nil);
LineTo(DC, 200, 200);
DeleteObject(SelectObject(DC, CreatePen(PS_SOLID, 1, RGB(0, 0, 255))));
MoveToEx(DC, 200, 100, nil);
LineTo(DC, 100, 200);
DeleteObject(SelectObject(DC, SetStockObject(BLACK_PEN)));
Дескрипторы объектов GDI имеют смысл только в пределах того процесса, который их создал, передавать их между процессами нельзя. Тем не менее изредка можно встретить утверждения, что такая передача возможна. Источник этой ошибки в том. что дескрипторы объектов GDI можно было передавать между процессами в старых, 16-разрядных версиях Windows, так что все утверждения о возможности такой передачи просто основываются на устаревших сведениях.