Drawing Inside the View Window: The Windows GDI
Now you're ready to write code to draw inside the view window. You'll be making a few changes directly to the Ex03a source code. Specifically, you'll be fleshing out the OnDraw member function in

The OnDraw Member Function
OnDraw is a virtual member function of the CView class that the application framework calls every time the view window needs to be repainted. A window needs to be repainted if the user resizes the window or reveals a previously hidden part of the window, or if the application changes the window's data. If the user resizes the window or reveals a hidden area, the application framework calls OnDraw, but if a function in your program changes the data, it must inform Windows of the change by calling the view's inherited Invalidate (or InvalidateRect) member function. This call to Invalidate triggers a later call to OnDraw.Even though you can draw inside a window at any time, it's better to let window changes accumulate and then process them all together in the OnDraw function. That way, your program can respond both to program-generated events and to Windows-generated events such as size changes.
The Windows Device Context
Chapter 1 that Windows doesn't allow direct access to the display hardware but communicates through an abstraction called a device context that is associated with the window. In the MFC library, the device context is a C++ object of class CDC that is passed (by pointer) as a parameter to OnDraw. After you have the device context pointer, you can call the many CDC member functions that do the work of drawing.
Adding Draw Code to the Ex03a Program
Now let's write the code to draw some text and a circle inside the view window. Be sure that the project Ex03a is open in Visual C++ .NET. You can use Class View to locate the code for the function (double-click OnDraw), or you can open the source code file

Edit the OnDraw function in


void CEx03aView::OnDraw(CDC* /* pDC */)
{
CEx03aDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
Uncomment the pointer to the device context and add the following boldface code (which you type in) to replace the previous code:
void CEx03aView::OnDraw(CDC* pDC)
{
pDC->TextOut(0, 0, "Hello, world!"); // prints in default font
// & size, top left corner
pDC->SelectStockObject(GRAY_BRUSH); // selects a brush for the
// circle interior
pDC->Ellipse(CRect(0, 20, 100, 120)); // draws a gray circle
// 100 units in diameter
}
You can safely remove the call to GetDocument because we're not dealing with documents yet. The functions TextOut, SelectStockObject, and Ellipse are all member functions of the application framework's device context class CDC. The Ellipse function draws a circle if the bounding rectangle's length is equal to its width.The MFC library provides a handy utility class, CRect, for Windows rectangles. A temporary CRect object serves as the bounding rectangle argument for the ellipse drawing function. You'll see more of the CRect class in quite a few of the examples in this book.
Recompile and test Ex03a. Choose Build from the Build menu, and if there are no compile errors, test the application again. Now you have a program that visibly does something!
Rest assured that the standard Windows WinMain and window procedure functions are hidden away inside the application framework. You'll see those functions later in this book, when we examine the MFC library frame and application classes. In the meantime, you're probably wondering what happened to the WM_PAINT message. You'd expect to do your window drawing in response to this Windows message, and you'd expect to get your device context handle from a PAINTSTRUCT structure returned by the Windows BeginPaint function.It so happens that the application framework has done all the dirty work for you and served up a device context (in object pointer form) in the virtual function OnDraw. As explained in Chapter 2, true virtual functions in window classes are an MFC library rarity. MFC library message map functions dispatched by the application framework handle most Windows messages. MFC 1.0 programmers always defined an OnPaint message map function for their derived window classes. Beginning with version 2.5, however, OnPaint was mapped in the CView class, and that function made a polymorphic call to OnDraw. Why? Because OnDraw needs to support the printer as well as the display. Both OnPaint and OnPrint call OnDraw, thus enabling the same drawing code to accommodate both the printer and the display.