[Programming Visual C++]Chapter Four Mapping Modes

1.MM_TEXT

In MM_TEXT, coordinates map to pixels,
values of x increase as you move right,
and values of y increase as you move down,
but you're allowed to change the origin through calls to the CDC functions SetViewportOrg and SetWindowOrg

Here's some code that sets the window origin to (100, 100) in logical coordinate space and then draws a 200-by-200-pixel square offset by (100, 100).

The logical point (100, 100) maps to the device point (0, 0).A scrolling window uses this kind of transformation.

void CMyView::OnDraw(CDC* pDC)
{
pDC->SetMapMode(MM_TEXT);
pDC->SetWindowOrg(CPoint(100, 100));
pDC->Rectangle(CRect(100, 100, 300, 300));
}
屏幕上看到的是顶点在左上角的200*200的方框。


2.MM_HIMETRIC

If you assign the MM_HIMETRIC mapping mode, for example, a logical unit is 1/100 millimeter (mm) instead of 1 pixel.

In the MM_HIMETRIC mapping mode, the y axis runs in the opposite direction to that in the MM_TEXT mode:
y values decrease as you move down.

Thus, a 4-by-4-cm square is drawn in logical coordinates this way:
pDC->Rectangle(CRect(0, 0, 4000, -4000));

3.The Fixed-Scale Mapping Modes

Mapping Mode Logical Unit
MM_LOENGLISH 0.01 inch
MM_HIENGLISH 0.001 inch
MM_LOMETRIC 0.1 mm
MM_HIMETRIC 0.01 mm
MM_TWIPS 1/1440 inch

in the MM_HIMETRIC mapping mode,
x
values increase as you move right
and y values decrease as you move down.

1 twip = 1/20 point
1 point = 1/72 inch
=> 12-point = 12 × 20 = 240 twips

4.The Variable-Scale Mapping Modes
Windows provides two mapping modes, MM_ISOTROPIC and MM_ANISOTROPIC, that allow you to change the scale factor as well as the origin. With these mapping modes, your drawing can change size as the user changes the size of the window. Also, if you invert the scale of one axis, you can "flip" an image about the other axis and you can define your own arbitrary fixed-scale factors.

x scale factor = x viewport extent / x window extent
y scale factor = y viewport extent / y window extent
device x = logical x × x scale factor + x origin offset
device y = logical y × y scale factor + y origin offset

Suppose the window is 448 pixels wide (rectClient.right). The right edge of the ellipse's client rectangle is 500 logical units from the origin. The x scale factor is 448/1000, and the x origin offset is 448/2 device units. If you use the formulas shown on the previous page, the right edge of the ellipse's client rectangle comes out to 448 device units, the right edge of the window. The x scale factor is expressed as a ratio (viewport extent/window extent) because Windows device coordinates are integers, not floating-point values. The extent values are meaningless by themselves.

5.Coordinate Conversion

Your job is to decide when to use each system. Here are a few rules of thumb:

  • Assume that the CDC member functions take logical coordinate parameters.
  • Assume that the CWnd member functions take device coordinate parameters.
  • Do all hit-test operations in device coordinates. Define regions in device coordinates. Functions such as CRect::PtInRect work best with device coordinates.
  • Store long-term values in logical or physical coordinates. If you store a point in device coordinates and the user scrolls through a window, that point is no longer valid.

Suppose you need to know whether the mouse cursor is inside a rectangle when the user presses the left mouse button. The code is shown here.

// m_rect is CRect data member of the derived view class with MM_LOENGLISH
// logical coordinates

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rect = m_rect; // rect is a temporary copy of m_rect.
CClientDC dc(this); // This is how we get a device context
// for SetMapMode and LPtoDP
// -- more in next chapter
dc.SetMapMode(MM_LOENGLISH);
dc.LPtoDP(rect); // rect is now in device coordinates
if (rect.PtInRect(point)) {
TRACE("Mouse cursor is inside the rectangle.\n");
}
}
原文地址:https://www.cnblogs.com/huqingyu/p/199702.html