I am wondering about the difference between OnDraw()
and OnPaint()
in MFC.
After searching the Internet for a while, I found a useful article. In summary,
WM_PAINT
will triggerOnPaint()
, which callsOnDraw()
and passes aCDC*
:void CView::OnPaint() { // standard paint routine CPaintDC dc(this); OnPrepareDC(&dc); OnDraw(&dc); }
Another article mentions that when printing a document,
OnPrint()
also callsOnDraw()
by passing a printer DC. Therefore, by overridingOnDraw()
, you get screen painting and printing both in one function, which is convenient.
I tried to put my statements for drawing in either OnDraw()
and OnPaint()
. Either can work well. OnDraw()
is a little easier because it has already gotten a pointer pDC
.
Device contexts are an ancient abstraction. They have been described as early as 1982 in the first edition of Computer Graphics: Principles and Practice (probably even earlier) and seem to confuse people to this day.
The primary purpose of a device context is to abstract peculiarities of render devices (such as displays, printers, in-memory bitmaps, etc.) and provide a coherent interface. Code that's rendering into a device context generally does not need to know, which device is ultimately consuming the render commands.
The documentation entry titled Drawing in a View goes on to explain how the system is intended to work: In short, all painting should be performed in an
OnDraw
override that receives a device context. The system-providedOnPaint
implementation then constructs aCPaintDC
and callsOnDraw
.Up to this point this seems to be just an overly complex way to render the contents of a window. Things start to make sense when you implement, say, printing support. Now all you have to do is set up a printing device context and call
OnDraw
. Nothing in yourOnDraw
implementation needs to change.