Webocreation

Monday, November 23, 2009

Working with Mapping Modes

Working with Mapping Modes

This section describes windows and viewports, then presents mapping modes, origins, and extents.

All drawing functions called by a Windows-based application draw to logical space. Windows maps — or transforms — the drawing to physical space. As a result, the application has the advantage of being able to "size" the logical space in a way that is convenient for the problem domain at hand, and to have Windows map the drawing to the physical space. For example, for some applications it might be convenient to think of the logical space as if it is dimensioned in terms of miles or kilometers.

This section includes the following topics:

Windows and Viewports

The drawing area in logical space is called the "window."

The drawing area in physical space is called a "viewport." It typically corresponds to a view in your application that represents a given output device, such as a monitor screen or a printer. Physical coordinates are often called device coordinates or device units.

You can use CDC "viewport" and "window" functions and mapping modes to control how the drawing in logical space will be mapped (or transformed) into the physical space of the viewport.

To see an overview of how to initialize the view for isotropic drawing, click this icon.

® Mapping Modes

Because your application can change the mapping mode, it can control how the drawing in logical space will be transformed to physical space. The mapping mode defines the unit of measure that is used to convert logical units to physical units; it also defines the orientation of the device's x- and y-axes.

Windows supports eight mapping modes. Six are absolute; two are proportional. An absolute mapping mode equates a logical unit to a fixed unit of measure; a proportional mapping mode varies the display with the relative size of the output window.

The following table describes the eight mapping modes, how they transform a drawing from logical space to physical space, and notes on usage or outcome.

Mapping mode Mapping rules Notes


Absolute None Absolute modes equate a logical unit to a fixed unit of measure.

MM_TEXT Each logical unit is converted to 1 device pixel. Positive x is to the right; positive y is down. The default mode. It follows the conventions of text display for many languages: left to right, top to bottom.

MM_LOENGLISH Each logical unit is converted to 0.01 inch. Positive x is to the right; positive y is up. Useful in applications that must draw in physically meaningful units of measure (such as inches or millimeters).

MM_HIENGLISH Each logical unit is converted to 0.001 inch. Positive x is to the right; positive y is up. (same as above)

MM_LOMETRIC Each logical unit is converted to 0.1 millimeter. Positive x is to the right; positive y is up. (same as above)

MM_HIMETRIC Each logical unit is converted to 0.01 millimeter. Positive x is to the right; positive y is up. (same as above)

MM_TWIPS Each logical unit is converted to 1/20 of a point. (Because a point is 1/72 inch, a twip is 1/1440 inch.) Positive x is to the right; positive y is up. (same as above)

Proportional None Display varies with the relative size of the output window.

MM_ANISOTROPIC Allows the x- and y-coordinates to be adjusted independently. The exact shape of the image is not preserved.

MM_ISOTROPIC Ensures a 1:1 aspect ratio. The exact shape of an image is preserved.



The functions CDC::SetMapMode and CDC::GetMapMode manage the current mapping mode. Each application can change the mapping mode for its client area; one view can display concurrently graphical objects that are created with different mapping modes.

® Origins and Extents
The default origin (location for the coordinates 0,0) is the upper-left corner of the view. The default window and viewport extents establish a ratio or scaling factor of 1:1, so one unit in logical space is equivalent to one pixel in physical space.


Note that it is the ratio between extents of the window and the viewport that is important, not the actual values for each.

To see sample code that shows how to set origins and extents in order to display a soccer field in the viewport, click this icon.

// FootView.CPP
void CFootballView::SetMappingMode(CDC *pDC)
{
// Preserve aspect ratio
pDC->SetMapMode(MM_ISOTROPIC);
// A soccer field is 110 x 70 meters, but the drawing
// needs a 10 meter border on all 4 sides.
// Constants: LENGTH = 110, WIDTH = 70, BORDER = 10
pDC->SetWindowExt(LENGTH + 2 * BORDER, WIDTH + 2 * BORDER);
CRect rect;
GetClientRect(&rect); // Get size of viewport
// Make y negative to increase y
// in an upwards direction.
pDC->SetViewportExt(rect.Width(), -rect.Height());
// Set the origin in the center of the screen
// by dividing the height and width by 2.
pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);
}

You can use the following functions to get information about or change the current settings.

Logical space Physical space


Origin CDC::GetWindowOrg, CDC::SetWindowOrg CDC::GetViewportOrg, CDC::SetViewportOrg

Extent CDC::SetWindowExt, CDC::GetWindowExt CDC::SetViewportExt, CDC::GetViewportExt



You can obtain the capabilities of your output device through CDC:GetDeviceCaps.

DPtoLP and LPtoDP

Often there is a need to transform between logical and device coordinates. For example, mouse handlers receive information only in device units, but there may be a requirement to use the information in logical units. The CDC class provides two functions to perform these transformations, DPtoLP and LPtoDP.

The following example code shows how to transform device units to logical units:

void CMyView::OnMouseMove(UINT nFlags, CPoint point)

{
// Create a DC based upon this view.
CClient dc(this);
// convert the point
dc.DPtoLP(&point);
// point is now in logical units.
// do something with it...
}


Special Visual Effects

MFC provides several ways to create special visual effects. This section discusses three of these methods: using ROP2 codes to set the raster copying mode, using the CRectTracker class to handle OLE objects and to customize the borders of polygons, and using the BitBlt function to efficiently repaint data to the screen.

This section includes the following topics:

Using ROP2 Codes

ROP (raster operation) codes can be used to erase objects, emulate continuous movement, or create other visual effects. In a graphical application, it is common to draw with different graphical objects, and colors, in the same area of the screen. Windows uses the current setting of the ROP attribute of the DC to determine how the colors interact in these areas. For example, a black line can be made to stand out against a black-filled rectangle by drawing the line with an ROP code of R2_XORPEN selected.

The ROP attribute of the DC is managed with the CDC::SetRop2 and CDC::GetRop2 functions.

The complete code for a sample application that shows how different ROP2 codes achieve certain effects is in \Samples\Ch07.

For more information, search for "SetROP2" and "GetROP2" in Visual C++ Help.

® Using the CRectTracker Class

The CRectTracker class allows an item to be displayed, moved, and resized in different ways. Although the CRectTracker class is designed to allow the user to interact with OLE items by using a graphical interface, its use is not restricted to OLE-enabled applications.

Specific visual effects that CRectTracker provides include the following:

® CRectTracker borders can be solid or dotted lines.

® The item can be given a hatched border or overlaid with a hatched pattern to indicate different states of the item.

® You can place eight resize handles on either the outside or the inside border of the item. (For information about resize handles, search for "GetHandleMask" in Visual C++ Help.)

® You can change the orientation of an item during resizing.



For more information about the CRectTracker class, see Visual C++ Help.

Using BitBlt

Flicker can occur if the view is rapidly and repeatedly repainted. This can happen, for example, when a mouse-move event generates successive paint messages. This flicker is generated by a sequence of alternating view-erase and view-drawing code executing. If your application requires this functionality, then one way to remove the flicker is to perform all painting on an internal bitmap and then transfer the bitmap to the view using a BitBlt operation.

Much of this functionality can be hidden from the application drawing code by overriding the view's OnPaint handler. The OnPaint handler normally sets up CPaintDC and then calls the view's OnDraw function. The intention is to create a memory device context and pass this new context to the OnDraw function. The drawing code uses the new DC; the drawing is simply stored in memory and not sent directly out to the view. When the OnDraw function returns, the OnPaint handler performs a rapid bitmap transfer from the memory DC to the view's DC.

To override a view's OnPaint handler

1. Create a memory DC object, compatible with the view.
2. Create a new bitmap object, compatible with the view.
3. Select the bitmap into the CDC object.
4. Call the view's OnDraw function.
5. Select the bitmap into the view's DC.
6. Call the view DC's BitBlt function using the memory DC as the source.
7. Delete the memory DC object and the bitmap object.

The following example code shows you how to implement this functionality:

void CMyView::OnPaint()
{
// Generate a paint DC based upon the view.
CPaintDC dc(this); // device context for painting

// Create a compatible memory dc

pMemDC= new CDC;
pMemDC->CreateCompatibleDC(&dc);

// Get the view's dimensions

CRect rect;
GetClientRect(&rect);

// Create compatible bitmap.

pBitmap = new CBitmap;
pBitmap->CreateCompatibleBitmap( &dc, rect.Width(), rect.Height());
pMemDC->SelectObject(pBitmap);
// Call the view's OnDraw, passing it the memory DC.
OnDraw(pMemDC);
// do the bitblt to the view from the memory DC.
dc.SelectObject(pBitmap);
dc.BitBlt(
0,0,rect.Width(), rect.Height(), pMemDC, 0, 0, SRCCOPY);
// clean up memory DC and bitmap
pBitmap->DeleteObject();
delete pBitmap;
delete pMemDC;
}

Self-Check Questions

1. Which one of the following is not a responsibility of a device context?

f A. A DC gives permission to a program to write to an output device.
f B. A DC maintains a clipping region for the associated window.
f C. A DC gives permission to a program to read from an input device.
f D. A DC maintains current information about how to draw to a window.

2. If you called CDC::SetTextColor with a value of RGB(255, 0, 0) and CDC::SetBkColor with a value of RGB(0, 0, 0), and subsequently called CDC::TextOut to display text to the client area, what would the text look like?

ff A. None would be displayed because no font was selected into the DC.
f B. Blue text with a white background.
f C. Red text with a white background.
f D. Red text on either a black background or window background color.
3. Which one of the following is not a GDI object?

f A. Rectangle
f B. Pen
f C. Font
f D. Bitmap

4. What is the default mapping mode in Windows?

f A. MM_TEXT
f B. MM_WINDOWS
f C. MM_TWIPS
ff D. MM_ISOTROPIC

No comments:

Post a Comment