Win32 GDI Programming with Pens

Windows Drawing with CreatePen and CreatePenIndirect Tutorial

© Guy Lecky-Thompson

Oct 24, 2008
Windows programming tutorial explaining pens and drawing with the GDI for Windows graphics programming and Windows drawing program techniques.

In order to draw on a device context, the application needs to select a pen into the device context. This pen can be one of the stock pens, selected using the GetStockObject function, but this does not allow the programmer to choose the style, width, or color of the pen.

To do this, the CreatePen and CreatePenIndirect functions must be used. First, however, it is necessary to introduce the data types that will be used in pen programming with the Windows GDI.

Windows Drawing Programming with Pens

A pen is defined by three key parameters:

  • Style - various PS_ identifiers (i.e. PS_SOLID, PS_DASH, etc.);
  • Width - in pixels;
  • Color - a standard Windows API COLORREF.

These can also be included in a LOGPEN structure, which has three members:

  • UINT lopnStyle
  • POINT lopnWidth
  • COLORREF lopnColor

In the pWidth is defined as a POINT, where only the x parameter (i.e. LOGPEN.lopnWidth.x) is actually used.

The Windows CreatePen Function

The CreatePen function simply takes the three parameters that define the pen that the programmer wants to create, and returns a handle to a pen. This handle can then be selected into the device context (with the SelectObject function), and used to draw with. The function is defined as follows:

  • HPEN CreatePen ( UINT, POINT, COLORREF )

To create a solid blue pen, 2 pixels wide, the programmer would use code such as:

HPEN hBluePen = CreatePen ( PS_SOLID, 2, RGB(0,0,255) );

The PS_SOLID identifier is one of many that can be used to change the style of the line.

The PS_ Identifiers in the Win32 GDI API

The following PS_ (Pen Style) identifiers can be used in the CreatePen function:

  • PS_SOLID - a solid line;PS_DASH - line consisting of dashes;PS_DOT - line consisting of dots;PS_DASHDOT - line of dash and dots;PS_DASHDOTDOT - line of dashes followed by two dots;PS_NULL - invisible pen.

The last of these produces a pen which cannot be seen, but leaves no border. Each of them can also be used in the LOGPEN structure when using the CreatePenIndirect function.

The Windows CreatePenIndirect Function

There are two key uses for the LOGPEN structure. One is to fill in data that can be passed to the CreatePenIndirect function:

  • HPEN CreatePenIndirect ( LOGPEN * )

As in the CreatePen function, it returns a handle to a pen that can be used to draw with. However, it takes a pointer to a LOGPEN structure, so the programmer must use the & operator to pass it by reference. The code might look like the following:

LOGPEN oLogPen;

oLogPen.lopnStyle = PS_SOLID

oLogPen.lopnWidth = 2;

oLogPen.lopnColor = RGB(0, 0, 255);

HPEN hPen = CreatePenIndirect( &oLogPen );

This code creates the same blue pen as the previous example. While this may seem longwinded, it's utility is illustrated by the second use for the LOGPEN structure and CreatePenIndirect function - to use the definition of an existing GDI object to populate the structure, before then using it to create another object. This uses the GetObject function:

LOGPEN oLogPen;

GetObject ( GetStockObject ( GRAY_PEN ),

sizeof(oLogPen), &oLogPen );

Once the oLogPen structure has been filled out, it can be modified, and then used to create a new pen. This advanced use of pens can be practical when creating Windows drawing program code.


The copyright of the article Win32 GDI Programming with Pens in Windows Programming is owned by Guy Lecky-Thompson. Permission to republish Win32 GDI Programming with Pens in print or online must be granted by the author in writing.




Post this Article to facebook Add this Article to del.icio.us! Digg this Article furl this Article Add this Article to Reddit Add this Article to Technorati Add this Article to Newsvine Add this Article to Windows Live Add this Article to Yahoo Add this Article to StumbleUpon Add this Article to BlinkLists Add this Article to Spurl Add this Article to Google Add this Article to Ask Add this Article to Squidoo