Книга: Windows API Tutorials
Drawing with Pens and Painting with Brushes
Drawing with Pens and Painting with Brushes
Like a painter, you will need pens and brushes to create artwork on your canvas. When you call Canvas::Line or Canvas::Rectangle, Windows uses the currently attached pen to draw the lines and the currently attached brush to fill the insides of the shapes.
When you attach an object to the Canvas, you have to remember to detach it after you're done. Unless… you let C++ remember about that. Just use a local object whose constructor attaches, and destructor (called automatically when exiting the scope) detaches the object (see the Resource Management page for more details on this methodology). Notice that the following objects take HDC (handle to Device Context) as an argument in their constructors. However, you should simply pass them a Canvas object instead. Remember that Canvas can be automatically cast to 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 comes with a set of pre-defined pens and brushes. It is enough to attach them to your canvas for the time you want to use them.
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
}
If your program keeps using a small set of non-stock pens, you might want to create them up-front (e.g. by embedding them in the View object) and use a PenHolder object to temporarily attach them to your Canvas.
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;
};
Finally, if your program needs colored pens on-demand, i.e., you can't possibly preallocate them for all the colors you'll need, you should use colored pens. When you define an automatic ColorPen object, its constructor both creates and attaches the pen. When the destructor is called, at the end of the scope, it detaches the pen and deletes it.
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;
};
You deal with Brushes in exactly the same way (there are, however, more types of brushes supported by Windows). For instance, here's a definition of a 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;
};
As always, you are encouraged to experiment on your own.
And now for something completely different: Threads
- 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 на Borland Delphi
- Open Source Insight and Discussion
- Introduction to Microprocessors and Microcontrollers
- Chapter 6. Traversing of tables and chains
- Chapter 8. Saving and restoring large rule-sets
- Chapter 11. Iptables targets and jumps
- Chapter 5 Installing and Configuring VirtualCenter 2.0
- Chapter 16. Commercial products based on Linux, iptables and netfilter
- Appendix A. Detailed explanations of special commands
- Appendix B. Common problems and questions
- Appendix E. Other resources and links
- IP filtering terms and expressions