Книга: Windows API Tutorials
Canvas, or Windows Device Context
Canvas, or Windows Device Context
To paint, draw or print in a window you need a device context, DC for short. A DC is a resource that you borrow from Windows and you're supposed to return it immediately after you're done. That's where the Canvas object comes. The Canvas' constructor obtains the DC and the Canvas' destructor releases it. It is important that you create Canvas objects as automatic (stack) variables. That will guarantee that their destructor is always called when the program exits the local scope where they are defined (this class is an example of a more general Resource Management methodology). The typical use of the Canvas object is as follows (as you've already seen in the Generic program):
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!
}
All the various types of Canvas share the common ancestor — the Canvas class. Notice that Canvas' constructor is protected. You can't actually instantiate an object of this class. However, the derived classes are free to provide their own constructors. By the way, you can keep adding new methods to Canvas as the need arises.
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;
};
In response to the WM_PAINT message one should construct the PaintCanvas object. Notice the way PaintCanvas obtains and releases the DC.
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;
};
Another important example is the UpdateCanvas which is used for graphical operations outside of the context of WM_PAINT processing. Of course, your program may always force the repainting by calling InvalidateRect, but in many cases it would be an overkill. If your program keeps painting new things as it executes or in response to user actions, you can update the window using UpdateCanvas.
class UpdateCanvas: public Canvas {
public:
UpdateCanvas (HWND hwnd) : Canvas (GetDC (hwnd)), _hwnd(hwnd) {}
~UpdateCanvas () {
ReleaseDC (_hwnd, _hdc);
}
protected:
HWND _hwnd;
};
There are other types of Canvas: DrawItemCanvas used for owner-draw controls, MemCanvas for drawing on a piece of memory, etc.
Use pens and brushes to draw and paint on your canvas.
- Windows API Tutorials
- The Simplest Windows Program
- The Generic Windows Program
- Windows Controls
- Program with a Dialog Box as the Main Window
- Dialog Box
- Canvas, or Windows Device Context
- Drawing with Pens and Painting with Brushes
- Using Threads
- When Folders Change
- Using Windows95 Shell and COM — A. K. A. OLE
- What's Wrong with OLE? The Insider's story
- Rationalizing OLE Building smart OLE on top of, you know, the other ole.
- OLE Automation
- Splitter Bar
- Bitmaps
- Direct Draw
- Joining the Tutorial Project
- Сноски из книги
- Содержание книги
- Популярные страницы
- InterBase Super Server для Windows
- Интеграция с платформой Windows NT
- Часы в Windows показывают неправильное время
- Классическая архитектура на Windows NT (Yaffil CS)
- 4.2. Центр уведомлений Windows 10
- Загрузочные дискеты и Live CD для Windows
- 6.8. Разгон видеокарты на Windows 10
- Интеграция Windows SharePoint и Microsoft Office
- Наик Дайлип Системы хранения данных в Windows
- Глава 10 Возможности подсистемы хранения данных в различных версиях Windows NT
- 1.1 Режимы ядра и пользователя Windows
- 1.3 Архитектура Windows NT