Рисование перьями и раскрашивание кистями
Перевод А. И. Легалова
Англоязычный оригинал находится на сервере компании
Reliable Software
Подобно живописцу, Вы нуждаетесь
в перьях и кистях, чтобы создать
шедевр на вашем холсте. Когда Вы
вызываете метод Canvas::Line или Canvas::Rectangle,
Windows использует текущие установки
пера, чтобы рисовать линии, и
текущие установки кисти, чтобы
заполнять охватываемые контуры.
Когда объект сопоставляется с
Холстом, нельзя забывать
освободить его после окончания
работы. Это надо делать до тех пор,
пока вы не обеспечите такой
возможностью вашу программу на
языке C++. Используйте только
локальные объекты, чьи конструкторы
присоединяют, а деструкторы (вызываемые
автоматически, при выходе области
действия) освобождают объекты (см.
страницу "Управление ресурсами"
для более детального знакомства с
этой методологией). Обратите
внимание, что ниже следующие
объекты используют HDC (дескрипторы
контекстов устройств) в качестве
параметры в их конструкторах.
Однако, взамен этого, Вы должны
просто передать им объект Canvas.
Помните, что "Холст" может
автоматически приводиться к HDC.
class StockObject
{
public:
StockObject (HDC hdc, int type)
: _hdc(hdc)
{
_hObjOld = SelectObject (_hdc, GetStockObject (type));
}
~StockObject ()
{
SelectObject (_hdc, _hObjOld);
}
private:
HGDIOBJ _hObjOld;
HDC _hdc;
};
Windows имеет набор предопределенных
перьев и кистей. Если Вы хотите
использовать их, то достаточно
присоединить выбранные перья и
кисти к вашему холсту не некоторое
время.
class WhitePen : public StockObject
{
public:
WhitePen (HDC hdc): StockObject (hdc, WHITE_PEN) {}
};
// example
void Controller::Paint (HWND hwnd)
{
PaintCanvas canvas (hwnd);
WhitePen pen (canvas);
canvas.Line (0, 10, 100, 10);
// destructor of WhitePen
// destructor of PaintCanvas
}
Если ваша программа поддерживает
использование несколько перьев,
отсутствующих в Windows, Вы можете
предварительно создать их (например,
внедрив их в объект View) и
использовать объект PenHolder, для
временного присоединения к Холсту.
class Pen
{
public:
Pen (COLORREF color)
{
_hPen = CreatePen (PS_SOLID, 0, color);
}
~Pen ()
{
DeleteObject (_hPen);
}
operator HPEN () { return _hPen; }
private:
HPEN _hPen;
};
class PenHolder
{
public:
PenHolder (HDC hdc, HPEN hPen)
: _hdc (hdc)
{
_hPenOld = (HPEN)SelectObject (_hdc, hPen);
}
~PenHolder ()
{
SelectObject (_hdc, _hPenOld);
}
private:
HDC _hdc;
HPEN _hPenOld;
};
class View
{
public:
View ()
: _penGreen (RGB (0, 255, 128))
{}
void Paint (Canvas & canvas)
{
PenHolder holder (canvas, _penGreen);
canvas.Line (0, 10, 100, 10);
// destructor of PenHolder
}
private:
Pen _penGreen;
};
И, наконец, если ваша программа
нуждается в произвольных цветных
перьях, то есть, невозможно
предварительно определить всех
цветов, в которых вы будете
нуждаться, Вы должны использовать
цветные перья. Когда Вы определяете
автоматический объект ColorPen, его
конструктор создает и присоединяет
перо. Когда, в конце области
действия, вызывается деструктор, он
отсоединяет перо и удаляет его.
class ColorPen
{
public:
ColorPen (HDC hdc, COLORREF color)
: _hdc (hdc)
{
_hPen = CreatePen (PS_SOLID, 0, color);
_hPenOld = (HPEN)SelectObject (_hdc, _hPen);
}
~ColorPen ()
{
SelectObject (_hdc, _hPenOld);
DeleteObject (_hPen);
}
private:
HDC _hdc;
HPEN _hPen;
HPEN _hPenOld;
};
Точно таким же способом Вы можете
работать с кистями (кистей,
поддерживаемых Windows, гораздо больше,
чем перьев). В качестве примера,
ниже дается определение ColorBrush.
class ColorBrush
{
public:
ColorBrush (HDC hdc, COLORREF color)
: _hdc (hdc)
{
_hBrush = CreateSolidBrush (color);
_hBrushOld = (HBRUSH)SelectObject (_hdc, _hBrush);
}
~ColorBrush ()
{
SelectObject (_hdc, _hBrushOld);
DeleteObject (_hBrush);
}
private:
HDC _hdc;
HBRUSH _hBrush;
HBRUSH _hBrushOld;
};
Как всегда, мы пощряем Ваши
собственные эксперименты.
Далее:
совершенно иная тема - "Потоки".
|