|
||||
|
Обертка для контекста устройствХолст или контекст устройств WindowsПеревод А. И. Легалова Англоязычный оригинал находится на сервере компании Reliable Software Чтобы раукрашивать, рисовать или печатать в окне, Вам необходим контекст устройств (device context или, кратко, DC). DC — это ресурс, который заимствуется у Windows и, как предполагается, возвращается сразу же после того, как вы сделаете свою работу. Отсюда и берет корни объект Canvas (Холст). Конструктор Холста получает DC, а деструктор освобождает его. Важно то, что Вы создаете объекты Canvas как автоматические (стековые) переменные. Это гарантирует, что, когда программа выйдет из локальной области (контекста), всегда вызовется их деструктор, в которой определены ресурсы (предлагаемый класс является примером более общей методологии Управления ресурсами). Типичное использование объекта Canvas демонстрируется следующем кодом (вы его уже видели в программе Generic): void Controller::Paint() { // prepare the canvas and let View do the rest PaintCanvas canvas(_hwnd); _view.Paint(canvas, _model); // Notice: The destructor of PaintCanvas called automatically! } Различные типы Холста совместно используют общего предка — класс Canvas. Обратите внимание, что конструктор Холста защищен. Фактически, Вы не можете сформировать объект этого класса. Однако, наследующие классы открыты, чтобы обеспечить доступ к их собственным конструкторам. Между прочим, Вы можете осуществлять добавление новых методов к Холсту, по мере возникновения такой потребности. class Canvas { public: // operator cast to HDC // (used when passing Canvas to Windows API) operator HDC() { return _hdc; } void Point(int x, int y, COLORREF color) { ::SetPixel(_hdc, x, y, color); } void MoveTo(int x, int y) { ::MoveToEx(_hdc, x, y, 0); } void Line(int x1, int y1, int x2, int y2 ) { MoveToEx(_hdc, x1, y1, 0); LineTo(_hdc, x2, y2); } void Rectangle(int left, int top, int right, int bottom) { // draw rectangle using current pen // and fill it using current brush ::Rectangle(_hdc, left, top, right, bottom); } void GetTextSize(int& cxChar, int& cyChar) { TEXTMETRIC tm; GetTextMetrics(_hdc, &tm); cxChar = tm.tmAveCharWidth; cyChar = tm.tmHeight + tm.tmExternalLeading; } void Text(int x, int y, char const * buf, int cBuf) { ::TextOut(_hdc, x, y, buf, cbuf); } void Char(int x, int y, char c) { TextOut(_hdc, x, y, &c, 1); } void SelectObject(void* pObj) { ::SelectObject(_hdc, pobj); } protected: Canvas(HDC hdc): _hdc(hdc) {} HDC _hdc; }; В ответ на сообщение WM_PAINT нужно создать объект PaintCanvas. Обратите внимание на способ получения и освобождения DC объектом PaintCanvas. class PaintCanvas: public Canvas { public: // Constructor obtains the DC PaintCanvas(HWND hwnd) : Canvas(BeginPaint(hwnd, &_paint)), _hwnd(hwnd) {} // Destructor releases the DC ~PaintCanvas() { EndPaint(_hwnd, &_paint); } protected: PAINTSTRUCT _paint; HWND _hwnd; }; Другой важный пример — класс UpdateCanvas, который используется для графических операций вне контекста обработки сообщения WM_PAINT. Конечно, ваша программа может всегда инициировать перерисовку, вызывая InvalidateRect, но во многих случаях это было бы массовым убийством. Если ваша программа осуществляет перерисовку новых объектов, когда они обрабатываются или в ответ на действия пользователя, Вы можете модифицировать окно, используя UpdateCanvas. class UpdateCanvas: public Canvas { public: UpdateCanvas(HWND hwnd) : Canvas(GetDC(hwnd)), _hwnd(hwnd) {} ~UpdateCanvas() { ReleaseDC(_hwnd, _hdc); } protected: HWND _hwnd; }; Можно создать и другие типы Холста: DrawItemCanvas используется для рисования элементов управления их владельцем, MemCanvas — для рисования во фрагментах памяти, и т.д. Далее: Использование перьев и кистей для рисования на холсте. |
|
||
Главная | В избранное | Наш E-MAIL | Добавить материал | Нашёл ошибку | Наверх |
||||
|