Графический интерфейс GDI в Microsoft Windows
3.2. Выбор цвета без использования палитры
Приложения, которые не хотят ничего знать про палитры, могут указывать логический цвет изображений, составляя его из RGB-компонент, указывая их количественный состав. Однако, если видеоконтроллер не работает в режиме True Color, для вывода на экран будут использованы только статические цвета или смешанные цвета, состоящие из статических цветов. В результате полученный на экране физический цвет может не соответствовать запрошенному логическому цвету.
Как указать цвет
Многие функции программного интерфейса GDI (например, функции, создающие перья и кисти) требуют в качестве одного из своих параметров ссылку на используемый цвет. Цвет указывается при помощи переменной, имеющей тип COLORREF :
Тип COLORREF определен в файле windows.h следующим образом:
Эта макрокоманда упаковывает отдельные цветовые компоненты в двойное слово, причем (что важно) старший байт этого слова должен быть равен нулю (рис. 3.2).
Рис. 3.2. Представление цвета, полученное с помощью макрокоманды RGB
В файле windows.h определены также макрокоманды, извлекающие из переменной типа COLORREF, упакованной с помощью макрокоманды RGB, отдельные цветовые компоненты:
Как мы уже говорили, в зависимости от текущего цветового разрешения Windows может предоставить приложению приближенный цвет, который максимально соответствует запрошенному логическому цвету. Функция GetNearestColor возвращает для запрошенного логического цвета clrref физический цвет, составленный только из компонент чистого цвета:
Через параметр hdc необходимо передать идентификатор контекста отображения.
Системные цвета
Как выбрать цвета для объектов приложения?
Самый простой (и самый плохой) способ заключается в том, что в исходном тексте приложения вы указываете цвета как комбинации RGB-компонент. Очевидный недостаток этого способа заключается в том, что пользователь не сможет изменить эти цвета. Даже если у вас идеальный вкус и вы сможете подобрать превосходную цветовую гамму, следует учитывать, что ваше приложение может быть запущено на монохромном мониторе, где отдельные цвета преобразуются в градации серого цвета. В результате некоторые элементы изображения могут стать плохо различимыми или пропадут вовсе.
Приложение Control Panel, которое входит в состав Windows, позволяет вам изменять системные цвета, обеспечивая приемлемую цветовую палитру практически для любого типа видеомонитора.
Для того чтобы узнать цвет той или иной системной компоненты экрана Windows, вы можете вызвать функцию GetSysColor :
В качестве единственного параметра следует передать этой функции идентификатор компоненты:
| Идентификатор | Описание |
| COLOR_ACTIVEBORDER | Рамка вокруг активного окна |
| COLOR_ACTIVECAPTION | Заголовок активного окна |
| COLOR_APPWORKSPACE | Фон окна приложения MDI (приложение, использующее многооконный интерфейс) |
| COLOR_BACKGROUND | Окно Desktop |
| COLOR_BTNFACE | Кнопка |
| COLOR_BTNHIGHLIGHT | Выбранная кнопка |
| COLOR_BTNSHADOW | Тень, «отбрасываемой» кнопкой |
| COLOR_BTNTEXT | Текст надписи на поверхности кнопки |
| COLOR_CAPTIONTEXT | Текст заголовка окна, кнопки изменения размера, кнопки полосы просмотра |
| COLOR_GRAYTEXT | Текст серого цвета |
| COLOR_HIGHLIGHT | Фон выбранного элемента в органе управления |
| COLOR_HIGHLIGHTTEXT | Текст для выбранного органа управления |
| COLOR_INACTIVEBORDER | Рамка вокруг неактивного окна |
| COLOR_INACTIVECAPTION | Заголовок неактивного окна |
| COLOR_INACTIVECAPTIONTEXT | Текст заголовка для неактивного окна |
| COLOR_MENU | Фон меню |
| COLOR_MENUTEXT | Текст меню |
| COLOR_SCROLLBAR | Полоса просмотра |
| COLOR_WINDOW | Фон окна |
| COLOR_WINDOWFRAME | Рамка окна |
| COLOR_WINDOWTEXT | Текст в окне |
Ваше приложение может выбрать для использования некоторые из системных цветов, при этом пользователь сможет влиять на внешний вид вашего приложения с помощью Control Panel, настраивая цвета на свой вкус.
Вы можете создать приложение, изменяющее системные цвета. Для этого обратите внимание на функцию SetSysColors :
Параметр cDspElements определяет количество элементов, для которых изменяются цвета.
Параметр lpnDspElements представляет собой указатель на массив идентификаторов элементов изображения, список которых приведен выше.
Перед вызовом функции вам надо подготовить также массив из cDspElements элементов, содержащих новые значения для цветов, передав функции адрес этого массива через параметр lpdwRgbValues.
Внесенные изменения сохраняются только до очередного перезапуска операционной системы Windows.
Сообщение WM_SYSCOLORCHANGE
Как мы только что сказали, сообщение WM_SYSCOLORCHANGE посылается всем активным окнам верхнего уровня при изменении системных цветов. В ответ на это сообщение приложения, которые создают свои перья и кисти на базе системных цветов, должны удалить эти перья и кисти, а затем создать их заново.
Так как после изменения системных цветов все активные окна получают сообщение WM_PAINT, обработчик сообщения WM_SYSCOLORCHANGE не должен ничего перерисовывать в окне.
Сообщение WM_SYSCOLORCHANGE не имеет параметров, поэтому значения, передаваемые через wParam и lParam следует проигнорировать.
Функция ChooseColor
Рис. 3.3. Диалоговая панель для выбора цвета
Если нажать на кнопку «Define Custom Colors. «, внешний вид диалоговой панели изменится (рис. 3.4).
Рис. 3.4. Расширенная диалоговая панель
Пользуясь правой половиной диалоговой панели, пользователь сможет добавить новый цвет в набор «Custom Colors» и затем выбрать его из этого набора.
Функция ChooseColor описана в файле commdlg.h:
Перед вызовом функции следует заполнить структуру CHOOSECOLOR, передав функции ее адрес через параметр lpcc.
В случае успешного выбора цвета функция возвращает TRUE. Если пользователь отказался от выбора или, если произошла ошибка, возвращается значение FALSE.
Структура CHOOSECOLOR и указатель на нее описаны в файле commdlg.h:
Опишем назначение и правила использования отдельных полей этой структуры.
Поле lStructSize заполняется перед вызовом функции. Оно должно содержать размер структуры в байтах.
Поле Flags также заполняется до вызова функции. В него следует записать флаги инициализации, влияющие на использование других полей этой структуры.
| Флаг | Описание |
| CC_RGBINIT | Для цвета, выбранного по умолчанию, используется цвет, указанный в поле rgbResult |
| CC_FULLOPEN | Если указан этот флаг, на экране появляется полный вариант диалоговой панели, обеспечивающий возможность определения произвольного цвета. Если этот флаг не указан, для определения произвольного цвета пользователь должен нажать на кнопку «Define Custom Color» |
| CC_PREVENTFULLOPEN | Кнопка «Define Custom Color» блокируется, таким образом, при использовании этого флага пользователь не может определить произвольный цвет |
| CC_SHOWHELP | Флаг разрешает отображение кнопки «Help». Если указан этот флаг, в поле нельзя указывать значение hwndOwner |
| CC_ENABLEHOOK | Если указан этот флаг, используется функция фильтра, адрес которой указан в поле lpfnHook. С помощью этой функции можно организовать дополнительную обработку сообщений от диалоговой панели |
| CC_ENABLETEMPLATE | Используется шаблон диалоговой панели, определяемый содержимым поля hInstance. Адрес строки, содержащей имя шаблона, должен быть указан в поле lpTemplateName |
| CC_ENABLETEMPLATEHANDLE | Используется шаблон диалоговой панели, идентификатор которого записан в поле hInstance. Содержимое поля lpTemplateName игнорируется |
В поле hwndOwner перед вызовом функции следует записать идентификатор окна, создавшего диалоговую панель, или NULL. В последнем случае нельзя использовать флаг CC_SHOWHELP.
Поле hInstance заполняется в тех случаях, когда приложение использует свой собственный шаблон диалоговой панели (вместо стандартного шаблона, расположенного в ресурсах DLL-библиотеки). В этом случае перед вызовом функции в это поле следует записать идентификатор модуля, содержащего шаблон диалоговой панели. В поле Flags необходимо указать флаги CC_ENABLETEMPLATE или CC_ENABLETEMPLATEHANDLE.
В поле lpTemplateName следует записать адрес текстовой строки идентификатора ресурса шаблона диалоговой панели (если этот шаблон используется).
Поле rgbResult предназначено для передачи приложению цвета, выбранного пользователем. Если записать в это поле значение NULL, сразу после вывода диалоговой панели выбора цвета по умолчанию будет выбран черный цвет. Вы, однако, можете использовать для начального выбора любой другой цвет, записав его в это поле и указав флаг CC_RGBINIT.
Перед вызовом функции вы должны подготовить массив из 16 двойных слов, содержащих цвета для использования в меню «Custom Colors». Адрес этого массива следует передать через параметр lpCustColors.
Поле lCustData используется для передачи данных функции фильтра (если она определена).
Адрес функции фильтра передается через параметр lpfnHook. Для использования функции фильтра следует указать флаг CC_ENABLEHOOK.
UCanCode Software focuses on general application software development. We provide complete solution for developers. No matter you want to develop a simple database workflow application, or an large flow/diagram based system, our product will provide a complete solution for you. Our product had been used by hundreds of top companies around the world!
«100% source code provided! Free you from not daring to use components because of unable to master the key technology of components!»
GDI Accessories and Tools: COLORREF
Overview of Colors
The color is one the most fundamental objects that enhances the aesthetic appearance of an object. The color is a non-spatial object that is added to an object to modify some of its visual aspects. The MFC library, combined with the Win32 API, provides various actions you can use to take advantage of the various aspects of colors.
Three numeric values are used to create a color. Each one of these values is 8 bits. The first number is called red. The second is called green. The third is called blue:
| Bits | |||||||||
| Red |
| ||||||||
| Green |
| ||||||||
| Blue |
|
Converted to decimal, each one of these numbers would produce:
2 7 + 2 6 + 2 5 + 2 4 + 2 3 + 2 2 + 2 1 + 2 0
= 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1
Therefore, each number can have a value that ranges from 0 to 255 in the decimal system.
These three numbers are combined to produce a single number as follows:
| Color Value |
| ||||||||||||||||||||||||||||||||||||||||||||||||
Converted to decimal, this number has a value of 255 * 255 * 255 = 16581375. This means that we can have approximately 16 million colors available. The question that comes to mind is how we use these colors, to produce what effect.
You computer monitor has a surface that resembles a series of tinny horizontal and vertical lines. The intersection of a one horizontal line and a vertical line is called a pixel. This pixel holds, carries, or displays one color.
As the pixels close to each other have different colors, the effect is a wonderful distortion that creates an aesthetic picture. It is by changing the colors of pixels that you produce the effect of color variances seen on pictures and other graphics.
The Color as a Data Type
Microsoft Windows considers that a color is a 32-bit numeric value. Therefore, a color is actually a combination of 32 bits:
| Color Value |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
The bits of the most significant byte (the left byte) are reserved for the operating system’s internal use and must be set to 0. Based on this, each color is characterized by its combination of a red, a green, and a blue values.
When all three numbers have their lowest value, which is 0, the color is called black. When the numbers are at their highest value, which is 255, the color is called white. Not all color combinations have a name. In fact, in MS Windows programming, the names are very limited. For this reason, color are rarely called by a name and usually, a name would depend on who is using it. Nevertheless, there are popular names that most people recognize. Examples are Black, White, Red, Green, Blue, Yellow. Except for black and white, each color can assume different variations. For example, when all three numbers have the same value but neither 0 nor 255, the color is called Gray by there are more than 250 possible combinations. Sometimes the combination is called Silver (each value is 192) or Gray (values=128).
The 32-bit numeric value used to characterize a color is defined by the COLORREF data type in Microsoft Windows programming. It can be used to declare a color value. Here is an example:
When of after declaring such a variable, you can initialize it with a 32-bit decimal value. Here is an example:
Although the above number (16711935) is a legitimate color value, it does not mean much. To create a color value, the Win32 API provides the RGB macro. Its syntax is:
The RGB macro behaves like a function and allows you to pass three numeric values separated by a comma. Each value must be between 0 and 255. Therefore, the above initialization can be done as follows:
Whether a color was initialized by a 32-bit integer or using the RGB macro, if you want to retrieve the red, green, and blue values of a color, you can use the GetRValue (), the GetGValue (), of the GetBValue () macros to extract the value of each. The syntaxes of these macros are:
Each macro takes a 32-bit value as argument, arg. The GetRValue () macro returns the red value of the rgb number. The GetGValue () macro returns the green value of the rgb number. The GetBValue () macro returns the blue value of the rgb number.
Device independence is the ability for an application to draw its intended figures, text, shapes, and display colors regardless of the device on which the drawing is performed. One way to take care of this is to manage colors at the operating system level so that Microsoft Windows can select the right color to render an object or portion of it. In some cases, a device, such as a monitor or a printer, may need to take care of the coloring details of the jobs it is ucancode.neted to perform.
There are two types of color palettes. The default color palette is a list of colors that the operating system would use on a device unless notified otherwise. There are typically 20 reserved colors as default. A logical palette is a palette that an application creates for a specific device context.
As mentioned above, a pixel is the real object that holds a color. Although it is so small, you can access a pixel and change its color. The pixels are stored in an array of [x][y] value. In fact, when you try accessing a pixel, you would be ucancode.neted to provide a color for it. To change the color of a pixel, you can call the CDC::SetPixel() method. Its syntaxes are:
The pixel you want to access is defined by its x and y coordinates, which can also be specified with a POINT or CPoint object as the point argument. The color you want to specify is the crColor argument.
Here is an example of using the SetPixel() function:
Rectangles With 3-D Effect
Using colors, you can draw a rectangle with a 3-D effect. To do this, the CDC class provides the Draw3dRect() method. Its syntaxes are:
The rectangle to draw can be provided by its location and size through the x, y, cx, and cy arguments. You can also pass it as a pointer to RECT or CRect for the lpRect argument.
Specify a color for the top and left sides of the rectangle as the clrTopLeft argument.
The clrBottomRight argument holds the color of the right and bottom sides of the rectangle.
Разукрашиваем вывод в консоли: теория и практика
Консоль привлекает многих своей минималистичностью и эстетикой, но даже в ней иногда хочется выделить определённый фрагмент, чтобы показать его роль или значимость. Например, отметить зелёным текстом сообщение об успешном выполнении операции или обозначить длинный текст ошибки курсивом. О том, как это делать, а также о реализации на питоне — читайте далее.
Управляющие последовательности ANSI
ANSI escape sequences или Управляющие последовательности ANSI — это стандарт, дающий возможность управлять курсором, цветами, начертание в текстовых консолях. Такие последовательности воспринимаются отрисовщиком терминала, как команды отображать последующий текст в определенном формате. Есть также последовательность, которая сбрасывает предыдущие команды, и отображение текста становиться обычным. Существует несколько форматов управляющих последовательностей, различающихся возможностями и появившимися в разных версиях кодировок. Поговорим об этих форматах подробнее.
8 основных цветов и стили
Для обычного пользователя разнообразия цветов этого формата будет более чем исчерпывающим. Но прежде чем задумываться о том, что терракотовый цвет гораздо круче красного, и он вам уж точно нужен, давайте разберемся, как устроена самая простая версия управляющей последовательности ANSI для форматирования текста.
Чтобы изменить текущий цвет шрифта или фона можно использовать следущий синтаксис:
Возможные аргументы
| Модификатор | Код |
|---|---|
| 1 | Жирный |
| 2 | Блеклый |
| 3 | Курсив |
| 4 | Подчёркнутый |
| 5 | Мигание |
| 9 | Зачёркнутый |
Изменения цвета шрифта
| Цвет | Код |
|---|---|
| 30 | Чёрный |
| 31 | Красный |
| 32 | Зелёный |
| 33 | Жёлтый |
| 34 | Синий |
| 35 | Фиолетовый |
| 36 | Бирюзовый |
| 37 | Белый |
Изменения цвета фона
| Цвет | Код |
|---|---|
| 40 | Чёрный |
| 41 | Красный |
| 42 | Зелёный |
| 43 | Жёлтый |
| 44 | Синий |
| 45 | Фиолетовый |
| 46 | Бирюзовый |
| 47 | Белый |
Бонус: другие интересные модификаторы, которые могут поддерживаться не всеми платформами
| Модификатор | Код |
|---|---|
| 38 | RGB цвет (см. раздел «Совсем много цветов») |
| 21 | Двойное подчёркивание |
| 51 | Обрамлённый |
| 52 | Окружённый |
| 53 | Надчёркнутый |
Давайте поэкспементируем. Для примеров я буду использовать Python.
Важно заметить, что форматирование повлияло и на консоль питона, а не только на ее вывод. Именно поэтому очень важно закрывать все «тэги» изменения форматирования.
Часто используемые сочетания (copy-paste-able)
| Код | Описание |
|---|---|
| \033[0m | вернуться к начальному стилю |
| \033[31m \033[0m | красный текст — для обозначения ошибок |
| \033[1;31m \033[0m | жирный красный текст — для обозначения критических ошибок |
| \033[32m \033[0m | зеленый текст — успешное выполнение |
| \033[3;31m \033[0m | красный курсив — текст ошибки |
| \033[43m \033[0m | выделение основного, как будто жёлтым маркером |
Больше цветов: аж целых 256
В этом формате синтаксис немного другой:
Для генерации кодов цветов можно использовать генератор.
А палитру доступных цветов можно увидеть на картинке ниже.
Совсем много цветов
Этот формат не всегда поддерживается стандартными консолями.
Некотрые будут негодовать: «256 цветов и нет моего любимого терракотового, какой ужас!». Для таких ценителей существует формат, который уже поддерживает 24 битные цвета (3 канала RGB по 256 градаций).
Для не ценителей поясню, что терракотовый кодируется как — (201, 100, 59) или #c9643b.
Синтаксис в этом формате выглядит вот так:
Python: Использование библиотеки Colorama
Библиотека Colorama позволяет форматировать текст, не запоминая коды цветов. Рассмотрим её использование на примере:
Style позволяет изменить стиль, Fore — цвет шрифта, Back — цвет фона. Использовать переменные из colorama нужно также, как и коды изменения стиля. Но плюс использования библиотеки в том, что Fore.RED более читаем, чем \033[0;31m
А что не так с Windows?
Просто так синтаксис, описанный в начале статьи, не работает в командной строке Windows. Поддержка цветов появлялась постепенно, причём в странном варианте. В начале программы надо сделать системный вызов, активирующий отрисовку цветов. А в более старых версиях необходимо заменить все ANSI последовательности на системные вызовы.
Но colorama.init() сделает всё за вас в большинстве версий Windows. Однако если вы используете другую операционную систему, то функцию init() вызывать в начале программы не обязательно. Также некоторые IDE на Windows (например, PyCharm) тоже поддерживают цвета без каких-либо махинаций.
А еще Windows не поддерживает многие модификаторы, такие как жирный текст. Подробнее можно почитать на странице Colorama
Termcolor
Ещё одна библиотека для вывода цветного текста с более удачным, на мой взлгяд, синтаксисом.
Кстати, проблему с Windows всё ещё можно починить с помощью colorama.init()
Выводы
Стандартные 8 цветов позволяют разнообразить вывод в консоль и расставить акценты. 256 цветов намного расширяют возможности, хотя и поддерживаются не всеми консолями. Windows, к сожалению, не поддерживает многие основные модификаторы, например, курсив. Также есть некоторые цвета, которые не прописаны в стандартах, но могут поддерживаться вашей операционной системой. Если вы хотите больше цветов, то вы можете поискать их в Гугле.
Пока что не любой терминал поддерживает 24-битные цвета и все модификаторы, но мы вряд ли увидим сильные изменения в этой сфере. Так что пока нам остаётся выбирать самые красивые варианты из тех, что доступны в любимом терминале.
Источники
Облачные серверы от Маклауд быстрые и безопасные.
Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!






