Здравствуйте. Вы находитесь на старом сайте и просматриваете устаревшую версию статьи.
Последняя версия статьи: здесь
Однако, если Вам так хочется... статью отсюда я удалять пока не собираюсь.
Цвета в Delphi - TColor
TЦвета в Delphi хранятся в переменных типа TColor. TColor - целочисленная переменная с диапазоном -$7FFFFFFF-1..$7FFFFFFF, что значит от -2147483648 до 2147483647.
Все цвета представимы в цветовой модели RGB (от Red, Green, Blue), т.е. задаются тремя числами, каждое из которых принадлежит диапазону 0..255. Легко посчитать, что всего существует 256^3 т.е. 16777216 цветов.
Для того, чтобы "собрать" TColor из трёх чисел задающих Красный, Зелёный и Синий есть стандартная функция, объявленная в модуле Windows.pas:
Вы ещё читаете? Вообще-то я уже написал. Сайт переезжает. Последняя версия статьи: здесь
function RGB(r, g, b: Byte): COLORREF;
begin
Result := (r or (g shl 8) or (b shl 16));
end;
Можно записать немного понятнее: Result:=r+256*g+65536*b;
Конечно же, существуют и обратные функции, объявленные всё в том же модуле:
function GetRValue(rgb: DWORD): Byte;
begin
Result := Byte(rgb);
end;
function GetGValue(rgb: DWORD): Byte;
begin
Result := Byte(rgb shr 8);
end;
function GetBValue(rgb: DWORD): Byte;
begin
Result := Byte(rgb shr 16);
end;
Цвета по названиям
В Delphi некоторые (наиболее используемые) цвета названы своими именами. Эти цвета скрываются за константами объявленными в модуле Graphics.pas . Примерами могут быть clRed, clSilver, clYellow, clLime и многие другие. Все цвета, названные своими именами, делятся на 3 группы: cbStandardColors, cbExtendedColors и cbSystemColors.
Это 16 цветов, знакомых каждому ребёнку. Далее представлена таблица этих цветов. (О колонке #RrGgBb я расскажу позже).
cbStandardColors
### |
Название |
Цвет |
Значение |
R,G,B |
#RrGgBb |
|
clBlack |
Чёрный |
0 |
0,0,0 |
#000000 |
|
clMaroon |
Тёмно-красный |
128 |
128,0,0 |
#800000 |
|
clGreen |
Зелёный |
32768 |
0,128,0 |
#008000 |
|
clOlive |
Оливковый |
32896 |
128,128,0 |
#808000 |
|
clNavy |
Тёмно-синий |
8388608 |
0,0,128 |
#000080 |
|
clPurple |
Пурпурный |
8388736 |
128,0,128 |
#800080 |
|
clTeal |
Стальной |
8421376 |
0,128,128 |
#008080 |
|
clGray |
Серый |
8421504 |
128,128,128 |
#808080 |
|
clSilver |
Серебряный |
12632256 |
192,192,192 |
#C0C0C0 |
|
clRed |
Красный |
255 |
255,0,0 |
#FF0000 |
|
clLime |
Ярко-зелёный |
65280 |
0,255,0 |
#00FF00 |
|
clYellow |
Жёлтый |
65535 |
255,255,0 |
#FFFF00 |
|
clBlue |
Синий |
16711680 |
0,0,255 |
#0000FF |
|
clFuchsia |
Фиолетовый |
16711935 |
255,0,255 |
#FF00FF |
|
clAqua |
Бирюзовый |
16776960 |
0,255,255 |
#00FFFF |
|
clWhite |
Белый |
16777215 |
255,255,255 |
#FFFFFF |
Здесь, пожалуй, всё должно быть понятно. Идём дальше...
Всего 4 цвета, зачем-то выделенные как особые...
cbExtendedColors
### |
Название |
Цвет |
Значение |
R,G,B |
#RrGgBb |
|
clMoneyGreen |
Money Green |
12639424 |
192,220,192 |
#C0DCC0 |
|
clSkyBlue |
Sky Blue |
15780518 |
166,202,240 |
#A6CAF0 |
|
clCream |
Cream |
15793151 |
255,251,240 |
#FFFBF0 |
|
clMedGray |
Medium Gray |
10789024 |
160,160,164 |
#A0A0A4 |
Эти цвета можно встретить в окне приложения в различных кнопках, списках, меню и т.д. Данные цвета зависят от операционной системы и её текущих настроек. Именно поэтому они заданы отрицательными числами. Далее в таблице приведены их значения, а также цвета для стандартных тем Windows XP и Windows 7:
cbSystemColors
Название |
Значение |
Win Xp |
Win 7 |
### |
R,G,B |
#RrGgBb |
### |
R,G,B |
#RrGgBb |
clActiveBorder |
-16777206 |
|
212,208,200 |
#D4D0C8 |
|
180,180,180 |
#B4B4B4 |
clActiveCaption |
-16777214 |
|
0,84,227 |
#0054E3 |
|
153,180,209 |
#99B4D1 |
clAppWorkSpace |
-16777204 |
|
128,128,128 |
#808080 |
|
171,171,171 |
#ABABAB |
clBackground |
-16777215 |
|
0,78,152 |
#004E98 |
|
0,0,0 |
#000000 |
clBtnFace |
-16777201 |
|
236,233,216 |
#ECE9D8 |
|
240,240,240 |
#F0F0F0 |
clBtnHighlight |
-16777196 |
|
255,255,255 |
#FFFFFF |
|
255,255,255 |
#FFFFFF |
clBtnShadow |
-16777200 |
|
172,168,153 |
#ACA899 |
|
160,160,160 |
#A0A0A0 |
clBtnText |
-16777198 |
|
0,0,0 |
#000000 |
|
0,0,0 |
#000000 |
clCaptionText |
-16777207 |
|
255,255,255 |
#FFFFFF |
|
0,0,0 |
#000000 |
clGradientActiveCaption |
-16777189 |
|
61,149,255 |
#3D95FF |
|
185,209,234 |
#B9D1EA |
clGradientInactiveCaption |
-16777188 |
|
157,185,235 |
#9DB9EB |
|
215,228,242 |
#D7E4F2 |
clGrayText |
-16777199 |
|
172,168,153 |
#ACA899 |
|
109,109,109 |
#6D6D6D |
clHighlight |
-16777203 |
|
49,106,197 |
#316AC5 |
|
51,153,255 |
#3399FF |
clHighlightText |
-16777202 |
|
255,255,255 |
#FFFFFF |
|
255,255,255 |
#FFFFFF |
clHotLight |
-16777190 |
|
0,0,128 |
#000080 |
|
0,102,204 |
#0066CC |
clInactiveBorder |
-16777205 |
|
212,208,200 |
#D4D0C8 |
|
244,247,252 |
#F4F7FC |
clInactiveCaption |
-16777213 |
|
122,150,223 |
#7A96DF |
|
191,205,219 |
#BFCDDB |
clInactiveCaptionText |
-16777197 |
|
216,228,248 |
#D8E4F8 |
|
67,78,84 |
#434E54 |
clInfoBk |
-16777192 |
|
255,255,225 |
#FFFFE1 |
|
255,255,225 |
#FFFFE1 |
clInfoText |
-16777193 |
|
0,0,0 |
#000000 |
|
0,0,0 |
#000000 |
clMenu |
-16777212 |
|
255,255,255 |
#FFFFFF |
|
240,240,240 |
#F0F0F0 |
clMenuBar |
-16777186 |
|
236,233,216 |
#ECE9D8 |
|
240,240,240 |
#F0F0F0 |
clMenuHighlight |
-16777187 |
|
49,106,197 |
#316AC5 |
|
51,153,255 |
#3399FF |
clMenuText |
-16777209 |
|
0,0,0 |
#000000 |
|
0,0,0 |
#000000 |
clScrollBar |
-16777216 |
|
212,208,200 |
#D4D0C8 |
|
200,200,200 |
#C8C8C8 |
cl3DDkShadow |
-16777195 |
|
113,111,100 |
#716F64 |
|
105,105,105 |
#696969 |
cl3DLight |
-16777194 |
|
241,239,226 |
#F1EFE2 |
|
227,227,227 |
#E3E3E3 |
clWindow |
-16777211 |
|
255,255,255 |
#FFFFFF |
|
255,255,255 |
#FFFFFF |
clWindowFrame |
-16777210 |
|
0,0,0 |
#000000 |
|
100,100,100 |
#646464 |
clWindowText |
-16777208 |
|
0,0,0 |
#000000 |
|
0,0,0 |
#000000 |
Так как цвета отрицательные, можно задаться вопросом: А как получить из них положительные для дальнейшего использования?
Для этого в библиотеке Graphics.pas есть специальныая функция:
function ColorToRGB(Color: TColor): Longint;
begin
if Color < 0 then
Result := GetSysColor(Color and $000000FF) else
Result := Color;
end;
После обработки системного цвета данной функцией мы получаем положительное число, из которого можно легко изъять нужные нам r, g и b компоненты.
Далее поставим задачу преобразовать строку (например 'clRed') в число, соответствующее этому цвету:
function StringToColor(const S: string): TColor;
begin
if not IdentToColor(S, Longint(Result)) then
Result := TColor(StrToInt(S));
end;
Теперь функция для преобразования цвета из числа в строку с его названием (напоминаю, все эти функции уже встроенны в delphi, в модуль Graphics):
function ColorToString(Color: TColor): string;
begin
if not ColorToIdent(Color, Result) then
FmtStr(Result, '%s%.8x', [HexDisplayPrefix, Color]);
end;
Здесь можно заметить, что при отсутствии у цвета названия, он будет преобразован в шестнадцатиричный вид. И теперь пришло время рассказать о последней колонке в таблице, т.е. о смысле #RrGgBb.
Внимание, далее может возникнуть ужасная путаница, которой я хочу избежать! Существует две очень похожих записи: #RrGgBb и #BbGgRr (Красный и синий поменялись местами). В первой записи (после знака #) на красный цвет отводится 2 символа ( шестнадцатиричная запись числа, т.е. символы от 0 до 9 и от A до F), затем 2 на зелёный, и потом 2 на синий. Во второй записи: 2 на синий, затем 2 на зелёный, и только потом 2 на красный.
При использования первой записи в памяти хранится цвет RGB, занимающий 3 байта, т.е. по байту на каждую компоненту (красный, зелёный или синий) именно в нужном порядке. Во втором случае хранится цвет BGR, аналогично, занимающий столько же места, но хранящий свои компоненты в другой последовательности.
Если просто преобразовать цвет как число из десятичной в шестнадцатиричную систему счисления, получится #BbGgRr. Если же вы хотите использовать этот цвет, например, на Html странице, вам придётся поменять Синий и Красный местами, для получения вида #RrGgBb.
Используя функцию ColorToString, мы (в случае когда цвет не имеет названия) получаем как раз запись BGR (вообще строку $BbGgRr, символ $ означает в Паскале, что это шестнадцатиричное число. Если заменить его на #, то используя StringToColor цвет мы не получим)
И последнее, если вы всё же хотите получить из цвета запись #RrGgBb, я напишу свою функцию:
function ColorToHex(rgb:TColor):String;
begin
Result:=Format('#%.2x%.2x%.2x', [byte(rgb),byte(rgb shr 8),byte(rgb shr 16)]);
end;
Ну вот и всё! Спасибо тем, кто дочитал до этого места и хоть немного понял меня :)
Автор: diversenok
|