Understanding the Mapping Mode

In the previous three columns, we've drawn text and shapes on the

screen. We've specified the position of the text and shape as fixed

numbers. In this column, we'll examine the meaning of those numbers as

well as a few other miscellaneous operations.

The coordinates that you give to the drawing functions are interpreted

based on the mapping mode of the CDC. The default mapping mode is

MM_TEXT. With this mode, one logical unit equals one device unit. The

physical size of the pixels will vary from device to device. Many

programs use this mode, which is why the displayed size of windows on

the same size screen (e.g. 15" display) varies with the resolution.

The higher the resolution, the smaller the window.

Positive x values are to the right and positive y values are down. You

can think of the upper left hand corner of the window as the 0,0

point. However you can set the window's origin to be anything with

SetWindowOrg( int x, int y ).

For some of the other mapping modes, one logical unit corresponds to

one physical measurement. For example, the MM_LOENGLISH mode makes one

logical unit equal to .01 inches. Positive y values are upwards. You

can consider the lower right hand corner as the 0,0 point, but this is


With the MM_ISOTROPIC and MM_ANISOTROPIC modes, you can change at any

time the correspondence between logical units and the device units by

using other CDC functions - SetWindowExt() and SetViewportExt(). We'll

examine these functions in a future column.

You use the CDC function SetMapMode(int MapMode) to set the mapping

mode. You should use whatever mapping mode simplifies your

programming. For example, if you are trying to show actual dimensions

of an object on the screen, you would use one of the modes that

corresponds to physical measurements.

Before we leave the CDC, I'll mention a few of the geometry classes

that MFC provides. We've seen a few of these before. CPoint

represents a point and corresponds to a POINT structure. It has x and

y members and overloaded operators for addition, subtraction, and

equality. These operators work not only with CPoints, but also with

CSizes and CRects.

The CSize class represents a size with cx and cy as its members. It

corresponds to a SIZE structure. It has overloaded operators for

addition, subtraction, and equality.

Finally the CRect class depicts a rectangle which corresponds to a RECT

structure. Its members are the top, bottom, left, and right

coordinates. The values of a CRect structure need to be normalized

such that the value of the left coordinate is less than the right and

the top is less than the bottom. If it is not normalized, then some

member functions may not operate properly. The NormalizeRect( ) member

function will normalize a CRect.

The CRect class has many useful functions and constructors. For

example, CRect( POINT point, SIZE size ) constructs a rectangle with a

point and a size. The BOOL PtInRect(POINT point) function returns

whether a point is inside a rectangle. The function void InflateRect(

SIZE size ) inflates a rectangle on all sides by the size parameter.

In a previous column, we created a rectangle to surround text with:

CSize size = pDC->GetTextExtent(

"You are a winner");

// Set up a rectangle of appropriate size

RECT rectangle;

CSize border(size.cx / 2, size.cy / 2);

rectangle.top = 50 - border.cy;

rectangle.bottom = 50 + size.cy + border.cy;

rectangle.left = 50 - border.cx;

rectangle.right = 50 + size.cx + border.cx;

Instead, we could have used:

CRect rectangle(CPoint(50,50), size);

CSize border(size.cx / 2, size.cy / 2);


This version makes it a bit easier to understand what the code is


We'll leave graphics for a few columns and talk about dialogs in the

next one.

Portions Copyright 1993-2000 by Pugh-Killeen Associates

ITWorld DealPost: The best in tech deals and discounts.
Shop Tech Products at Amazon