Win32: Drawing Lines and Ellipses with GDI
Drawing Lines and Ellipses with GDI
In this video, we demonstrate some simple graphics drawing with the Graphics Device Interface (GDI). We explain how to draw lines and ellipses, which we will make use of in future lessons. Using our Win32 Lesson 1 project as a base, we add the following lines to the WM_PAINT handler in the file Win32Lesson1.cpp between the BeginPaint() and EndPaint() function calls inside the WndProc() function:
HPEN hPenOld; // Draw a red line HPEN hLinePen; COLORREF qLineColor; qLineColor = RGB(255, 0, 0); hLinePen = CreatePen(PS_SOLID, 7, qLineColor); hPenOld = (HPEN)SelectObject(hdc, hLinePen); MoveToEx(hdc, 100, 100, NULL); LineTo(hdc, 500, 250); SelectObject(hdc, hPenOld); DeleteObject(hLinePen); // Draw a blue ellipse HPEN hEllipsePen; COLORREF qEllipseColor; qEllipseColor = RGB(0, 0, 255); hEllipsePen = CreatePen(PS_SOLID, 3, qEllipseColor); hPenOld = (HPEN)SelectObject(hdc, hEllipsePen); Arc(hdc, 100, 100, 500, 250, 0, 0, 0, 0); SelectObject(hdc, hPenOld); DeleteObject(hEllipsePen);
The basis for drawing graphics in GDI is the notion of a device context, which is given here by the hdc. A device context object abstracts the notion of a drawing surface so that we can use the same drawing commands whether we are drawing to a monitor screen, a printer, or any other device. The variable, hdc, is a handle to a device context.
The code above can be broken into two sections: drawing a line and drawing an ellipse. In the first section, we draw a line by using the Commands MoveToEx() and LineTo() to designate the start and end points, respectively.
In the second section, we draw an ellipse by making a call to the Arc() function. The parameters 100, 100, 500, 250 specify the upper-left hand corner of the bounding rectangle with the first two coordinates (100, 100) and the lower-right hand corner with the last two coordinates (500, 250). The remaining zeros that are passed in are not important for drawing an ellipse, but will be used when we draw arcs.
Most of the remaining code is set-up code for the drawing routines. The calls to CreatePen() set the drawing style, width, and color, respectively. However, the pen is not active until we select it into our device context by calling
SelectObject(). Notice that when we call SelectObject(), the currently selected pen is returned and we store it in hOldPen so that we can restore it when we are done drawing. When we are done drawing with our pens, we must always call DeleteObject() on them, since CreatePen() performs dynamic allocation.