Click here to Skip to main content
15,868,006 members
Articles / Desktop Programming / MFC

Introduction to Drawing in Windows

Rate me:
Please Sign up or sign in to vote.
4.55/5 (13 votes)
20 Mar 2000 162.1K   42   22
A simple introduction to using DCs to draw in Windows

Sample Image - DCDrawing.jpg

Everyone who knows me knows I am very enthusiastic about the Windows platform. Occasionally, someone will ask me why, or wouldn't I prefer to work with X-Windows or some other windowing platform. This article is for those and other people who have asked similar questions.

I started programming Windows with Windows 1.0 in the late 80s. At the time, there wasn't much good that could be said about Windows, but there were two things that jumped out at me as I was reading the documentation for the SDK (software development kit):

  • Device context
  • Mapping modes

The best way to describe what these two concepts mean is with a little code sample called PrintX that draws an X that is 4 inches on a side.

I am using Visual C++ 6.0 to build this application. Using the MFC App Wizard to create a new program called PrintX and accepting all defaults, the following is the only code I changed:

C++
////////////////////////////////////////////////////////////
// CPrintXView drawing

void CPrintXView::OnDraw(CDC* pDC)
{
    CPen pen( PS_SOLID, 0, RGB( 0, 0, 0 ));
    CPen* pPenOld = pDC->SelectObject( &pen );
    int nMap = pDC->SetMapMode( MM_HIENGLISH );

    pDC->MoveTo( 1000, -1000 );
    pDC->LineTo( 5000, -5000 );
    pDC->MoveTo( 5000, -1000 );
    pDC->LineTo( 1000, -5000 );

    pDC->SetMapMode( nMap );
    pDC->SelectObject( pPenOld );
}

Device Context

The parameter to the OnDraw method (pDC) is a pointer to the Device Context. The device context represents the surface of the device you will be drawing on. The magic of this is that surface is not limited to the screen or a memory context (as with the X-Windows graphics context), but can be a printer, a pen plotter, a bitmap, or any other device for which a windows driver can be written.

The first two lines of the OnDraw method are used to create a black pen:

C++
CPen pen( PS_SOLID, 0, RGB( 0, 0, 0 ));

which is then selected into the device context:

C++
CPen* pPenOld = pDC->SelectObject( &pen );

returning a pointer to the pen that was previously selected into the device context. When the line drawing commands are called later, they will be solid black lines defined by the pen.

Mapping Modes

The third line of the OnDraw method represents the second piece of magic:

C++
int nMap = pDC->SetMapMode( MM_HIENGLISH );

which is setting the mapping mode and returning the previously selected mapping mode. In this case, the mapping mode is set to MM_HIENGLISH which means co-ordinates that we pass to the line drawing commands will be in 1000ths of an inch--a logical co-ordinate system instead of a physical co-ordinate system!

This is the reason OnDraw does not care what the actual physical device is. A 640x480 screen may be using 80 pixels per inch while an HP LaserJet 4 uses 600 pixels per inch. The magic of the Mapping Mode is this code works for either!

The Rest of the Code

All that remains is to draw the lines and return the device context to its original state. The negative values in the line drawing routines represent negative Y values that are a result of changing the mapping mode to MM_HIENGLISH. In this mapping mode, Y values increase as you go up as opposed to the default mapping mode of MM_TEXT where Y values increase as you go down. Since the window origin defaults to being at the upper left corner of the window, negative Y values were required to make the X visible. An alternative would have been to move the window origin.

Windows provides a method for rolling your on mapping modes, so it would also be possible to create a mapping mode similar to MM_HIENGLISH except the Y values increase as you go down.

Conclusion

Windows has added a lot of magic since the Windows 1.0 days, but these first two are still close to my heart.

In the mid-90s, I had to convert some of my Windows code to X-Windows/Motif and guess what - no Device Context and no Mapping Modes. I was not a happy fellow for the next few months.

Of all the new magic that has been added to Windows over the years (multi-threaded, symmetric multi-processing, COM, etc.), it is hard to overlook how little code I had to write to make PrintX work.

If this were an X-Windows project, drawing an X that is 4 inches on a side is not too hard (certainly more than I have here), but once you get to that point, you have to write another equally complex program to do the printing - X-Windows knows nothing about printers--time to get out the PostScript manuals (unless of course your printer is one of thousands of Windows compatible printers that is not PostScript compatible).

Finally, the tools for writing Windows code have no peers. Anyone can go to CompUSA and buy a student version of Visual C++ for less than $100. Some of my UNIX friends run Windows (grudgingly) just so they can run Microsoft's Visual Studio and they readily admit that the best programming tools exist on the Windows platform.

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.


Written By
Software Developer (Senior) Retired
United States United States
I am currently retired, but spent the last 40 years of my career writing software for MS-DOS and Windows (starting with Windows 1.0).

My first experience with software was writing assembly code for the Motorola 6800.

During the S100 bus days, I wrote 8080 assembly and Basic.

With the introduction of the IBM PC I wrote in Borland Pascal for MS-DOS.

When Microsoft introduced Windows 1.0 I started writing in C code.

For the majority of my career, I did development in C++ starting with Visual C++ 1.0.

Some of my development was in .NET, but it never appealed to me like C++.

Comments and Discussions

 
GeneralDrawing into dialog control Pin
Vaclav27-May-05 10:13
Vaclav27-May-05 10:13 
GeneralI need an example Pin
bonmeepon9-Aug-04 7:15
bonmeepon9-Aug-04 7:15 
GeneralHelp Pin
Anonymous23-May-04 22:42
Anonymous23-May-04 22:42 
GeneralCircles Pin
Jolyn13-Dec-03 14:51
Jolyn13-Dec-03 14:51 
GeneralSetMapMode and HP Deskjets Pin
PawelSokolowski27-Jun-03 4:54
PawelSokolowski27-Jun-03 4:54 
GeneralRe: SetMapMode and HP Deskjets Pin
William T. Block27-Jun-03 11:32
William T. Block27-Jun-03 11:32 
Generalhahah Pin
11-Feb-02 11:37
suss11-Feb-02 11:37 
GeneralRe: hahah Pin
Christian Graus11-Feb-02 12:08
protectorChristian Graus11-Feb-02 12:08 
GeneralRe: hahah Pin
Giles11-Feb-02 12:39
Giles11-Feb-02 12:39 
GeneralRe: hahah Pin
Cloaca1-Feb-04 17:41
Cloaca1-Feb-04 17:41 
GeneralRe: hahah Pin
Dileep Cheruvallil George16-Apr-05 0:25
Dileep Cheruvallil George16-Apr-05 0:25 
GeneralRe: hahah Pin
Anonymous9-Sep-05 1:52
Anonymous9-Sep-05 1:52 
Questionprinting bitmaps? Pin
17-Dec-01 21:22
suss17-Dec-01 21:22 
My problem is, when I change mapping mode (not MM_TEXT), bitmaps doesn't appear on the printed page. When I draw that bitmap by lines (cyclic BitBlt) it is on the paper, but there are white linesin the picture. Why?Confused | :confused:

AK
AnswerRe: printing bitmaps? Pin
William T. Block18-Dec-01 12:26
William T. Block18-Dec-01 12:26 
Generalit's not X-windows Pin
21-Jun-01 1:29
suss21-Jun-01 1:29 
GeneralRe: it's not X-windows Pin
zorick13-Feb-04 18:13
zorick13-Feb-04 18:13 
QuestionRe: $100 for what? Pin
31-Dec-00 21:04
suss31-Dec-00 21:04 
AnswerReduce that size! Pin
NotDWorst19-Mar-01 15:53
NotDWorst19-Mar-01 15:53 
GeneralRe: Reduce that size! Pin
Anthony_Yio5-Jan-03 22:15
Anthony_Yio5-Jan-03 22:15 
QuestionWho Need Viusal C++ for $100? Pin
Chris Davis3-Apr-00 15:50
Chris Davis3-Apr-00 15:50 
AnswerRe: Who Need Viusal C++ for $100? Pin
Bill Block5-Apr-00 9:31
sussBill Block5-Apr-00 9:31 
GeneralRe: Who Need Viusal C++ for $100? Pin
Nigel Atkinson9-Nov-09 22:01
Nigel Atkinson9-Nov-09 22:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.