суббота, 3 апреля 2010 г.

Что можно сделать с DC-кистью?

Это перевод What is the DC brush good for? Автор: Реймонд Чен.

DC-кисть, возвращаемая GetStockObject(DC_BRUSH) - это stock-кисть, ассоциированная с контекстом устройства (DC - device context). Как и кисти системных цветов, цвет DC-кисти может быть различным. Но если цвета системных кистей меняются по системным цветам, то цвет DC-кисти меняется по вашей команде.

DC-кисть очень удобна, когда вам нужна кисть со сплошным цветом на короткое время, потому что она всегда существует, и её не надо создавать и удалять. Обычно, вам нужно создать кисть, что-то ей нарисовать и удалить. Но с DC-кистью вы можете просто задать её цвет и начать рисовать. Но это сработает только на короткое время, потому что в тот момент, когда кто-то ещё вызовет функцию SetDCBrushColor для вашего DC, DC-кисть будет изменена. На практике это означает, что DC-кисть может быть использована только на участках кода, где вы не вызываете внешних функций для вашего DC (заметьте, что каждый DC имеет свою собственную DC-кисть, поэтому в этом случае вам нужно волноваться только о другом потоке, который может работать с вашим DC одновременно с вами, но это не происходит ни в одной модели рисования, с которыми я знаком).

DC-кисть удивительно удобна для обработки различных сообщений типа WM_CTLCOLOR. Эти сообщения требуют от вас вернуть описатель кисти, которым нужно рисовать, скажем, фон элемента управления. Если вам нужна сплошная кисть, то обычно это означает создание кисти, сохранение её куда-то на всё время жизни окна и удаление её, когда окно уходит (некоторые люди хранят кисть в глобальной переменной, что отлично работает, пока кто-то не решит создать второе окно - тогда у вас начинаются большие проблемы).

Давайте используем DC-кисть, чтобы изменить цвет фона элемента управления. Сама программа не слишком интересна; это просто демонстрация того, как вы можете использовать DC-кисть.

Начните, как всегда, с пустого VCL-приложения, бросьте на форму TStaticText и сделайте такие изменения:
type
TForm1 = class(TForm)
StaticText1: TStaticText;
private
{ Private declarations }
public
{ Public declarations }
procedure WMCtrlColorStatic(var Msg: TWMCtlColorStatic); message WM_CTLCOLORSTATIC;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.WMCtrlColorStatic(var Msg: TWMCtlColorStatic);
begin
inherited;
SetDCBrushColor(Msg.ChildDC, ColorToRGB(clRed));
Msg.Result := GetStockObject(DC_BRUSH);
end;
Запустите эту программу и заметьте, что мы изменили цвет фона на красный.

Когда нас просят кастомизировать цвет, мы сначала вызываем унаследованный вариант, так что будут установлены цвета по-умолчанию (не имеет значения в нашем случае, потому что мы ничего не рисуем, а цвет фона изменяем сами - но это хороший принцип). Поскольку мы хотим изменить цвет фона, то мы устанавливаем цвет DC-кисти в красный и возвращаем нашу DC-кисть как желаемую кисть для фона.

Затем элемент управления берёт кисть, которую мы вернули (DC-кисть), и использует её, чтобы нарисовать фон, что приводит к красному фону, потому что это тот цвет, что мы установили для DC-кисти.

Обычно при кастомизации фоновой кисти, мы создаём кисть, возвращаем её из обработчика сообщения, а потом удаляем её, когда окно уничтожается. Но, используя DC-кисть, нам удалось избежать всего этого кода.

Существует также и DC-перо - GetStockObject(DC_PEN), которое ведёт себя в аналогичной манере.

2 комментария:

  1. Я вижу, вы хорошо отпраздновали :) Больше двух опечаток я раньше никогда не находил

    ОтветитьУдалить
  2. rofl :)

    На самом деле я просто вымотался с уборкой и подготовкой к дню рождению (не моё). Перевод делал уже ночью перед сном.

    Решил, что переводы надо публиковать строго раз в день, а то раз пропустишь - опять задержка в полмесяца.

    Спасибо за поправки.

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.