InfoCity
InfoCity - виртуальный город компьютерной документации
Реклама на сайте







Размещение сквозной ссылки

 

Рисование перьями и раскрашивание кистями


Перевод А.И. Легалова, SoftCraft


Англоязычный оригинал находится на сервере компании 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;

      };