Understanding SetMapMode, SetWindowOrg, SetViewportOrg, SetWindowExt, SetViewportExt
CDC :: SetMapMode
virtual int SetMapMode (int nMapMode);
Function description: This function sets the mapping mode of the specified equipment environment. The mapping mode defines the unit of measurement for converting logical units to equipment units, and defines the directions of the X and Y axes of the equipment.
nMapMode: Specifies the new mapping mode. This parameter can be any of the values listed below.
MM_ANISOTROPIC: Logical units are converted into arbitrary units with any scale axis. SetWindowExtEx and SetViewportExtEx functions can be used to specify the unit, direction and scale.
MM_HIENGLISH: Each logical unit is converted to 0.001 inches, the positive side of X is to the right, and the positive direction of Y is up.
MM_HIMETRIC: Each logical unit is converted to 0.01 mm, the positive direction of X is right, and the positive direction of Y is up.
MM_ISOTROPIC: The logical unit is converted into an arbitrary unit with an equal scale axis, that is, a unit along the X axis is equal to a unit along the Y axis. The unit and direction of the axis can be specified with the sum function. The graphics device interface (GDI) needs to be adjusted to ensure that the X and Y units remain the same size (when setting the window range, the viewport will be adjusted to achieve the same unit size).
MM_LOENGLISH: Each logical unit is converted to 0.1 inches, X positive direction is right, Y positive direction is up.
MM_LOMETRIC: Each logical unit is converted to 0.1 mm, X positive direction is right, Y positive direction is up.
MM_TEXT: Each logical unit is converted into a pixel, with X positive direction going to the right and Y positive direction going down.
MM_TWIPS; each logical unit is converted to 1/20 of the printing dot (that is, 1/1400 inch), the X positive direction is to the right, and the Y direction is upward.
Remarks:
The MM_TEXT method allows the application to work in units of device pixels. The size of the pixels varies depending on the device. The MM_HIENLISH, MM_HIMETRIC, MM_LOENGLISH, MM_LOMETRIC, and MM_TWIPS methods are very useful for applications that must be mapped in physical meaning units such as inches or millimeters. The MM_ISOTROPIC method guarantees an aspect ratio of 1: 1. MM_HIENLISH mode allows X and Y coordinates to be adjusted separately.
By convention, (0,0) is the origin and the origin is (0,0), but if you use this to understand the map mode of windows, you will go a detour. In fact, if you change the concept a little, the map mode of windows is easier to understand. for example:
page space ----> device space
pDC-> SetMapMode (MM_LOMETRIC);
pDC-> SetWindowOrg (40,0); // The origin of the "set" page space is (40,0), note that
// At this time, (40,0) is the origin, and the origin is (40,0). In fact, (0,0) is not necessarily related to the origin. This
// A sentence will not have any effect on the picture made by the drawing function in the page space. In a word: SetWindowOrg
// It is to specify which point in the page space is the origin.
pDC-> Rectangle (0,0,100, -100);
pDC-> Rectangle (0, -100,50, -200);
Similarly, SetViewportOrg also specifies which point in the device space is the origin. When the two coordinate systems are mapped, the two origins coincide.
SetWindowExt sets the size of the page space, and SetViewportOrg sets the size of the device space. In fact, what really matters is the proportional relationship between the two. For example, on a 1024 * 768 display:
pDC-> SetMapMode (MM_ISOTROPIC);
pDC-> SetWindowExt (10240,7680);
pDC-> SetViewportExt (1024,768);
pDC-> Rectangle (0,0,100,100); // The logical unit is given, but the specific drawing is to be converted into a device unit, and the conversion ratio is determined by the mode
Will draw a rectangle of 10 pixels * 10 pixels. The essence is that in the X direction, each logical unit has 1024/10240 pixels, and in the Y direction, each logical unit has 768/7680 pixels. Therefore, the following code has the same effect:
pDC-> SetMapMode (MM_ISOTROPIC);
pDC-> SetWindowExt (102400,76800);
pDC-> SetViewportExt (10240,7680);
pDC-> Rectangle (0,0,100,100);
The two are essentially the same, the former is easier to understand.
==================================
The two functions SetWindowOrg and SetViewportOrg are more difficult to understand. After my google and practice, I finally figured out the essential difference between the two functions.
1.SetWindowOrg (x, y) maps the origin (viewport) of device coordinates to (X, Y) of logical coordinates
2.SetViewportOrg (x, y) maps the origin (window) of logical coordinates to (X, Y) of device coordinates
3. The device origin is always the upper left corner of the client area.
(The following figure shows the meaning of these two functions)
Note the difference between device coordinates and logical coordinates:
1. The X and Y directions of the device coordinate are fixed, and the unit is also fixed. The X axis increases to the right and Y increases downward.
2. The X and Y directions of the logical coordinates are not fixed, and the units are not fixed. They change according to the selected mapping mode.
With the above explanations, I believe that everyone should be able to understand why the actual results of the following code are like this.
void CEx05aView :: OnDraw (CDC * pDC)
{
pDC-> SetMapMode (MM_LOMETRIC);
pDC-> SetWindowOrg (100, 100);
pDC-> Rectangle (0, 0, 200, 200);
pDC-> SetViewportOrg (100, 100);
pDC-> SelectStockObject (GRAY_BRUSH);
pDC-> Rectangle (0, 0, 200, 200);
}
======================================================= ==
Establishing a proper coordinate system can bring great convenience to our drawing. Here's how to set up the coordinate system we want in VC.
A device coordinate and logical coordinate
Device Coordinate, also known as Physical Coordinate, refers to the coordinates on the output device. The device coordinates on the screen are often called screen coordinates. Device coordinates use the horizontal and vertical distance of the object from the upper left corner of the window to specify the position of the object, expressed in pixels. The X axis of the device coordinate is positive to the right, and the Y axis is positive to the down. The origin of the coordinate is located in the window. Top left corner.
Logical Coordinate is the coordinate used by the system for recording. In the default mode (MM_TEXT), the direction and unit of logical coordinates are the same as the direction and unit of device coordinates, and are also expressed in pixels. The X axis is positive to the right, the Y axis is positive to the down, and the coordinate origin Located in the upper left corner of the window. Logical coordinates and device coordinates may not have the same value even in the default mode, except in the following two cases:
1. The window is a non-scrolling window
2. The window is a scroll window, but the vertical scroll bar is at the top of the scroll border, and the horizontal scroll bar is at the left. However, if you move the scroll bar, the two coordinates are not the same.
In VC, the coordinate position of the mouse coordinates is expressed by device coordinates, but all GDI drawings are expressed by logical coordinates, so when drawing with the mouse, the device coordinates must be converted into logical coordinates. You can use the CDC function DptoLP () to convert the device coordinates For logical coordinates, you can also use LptoDP () to convert logical coordinates to device coordinates.
Two coordinate mode
In order to use logical coordinates in different fields, Windows provides the following 8 coordinate modes:
为 MM_TEXT, MM_HIENGLISH, MM_LOENGLISH, MM_HIMETRIC, MM_LOMETRIC, MM_TWIPS, MM_ANISOTROPIC, and MM_ISOTROPIC, respectively.
Three instance analysis
(一) Establish the coordinates with the upper left corner as the origin and the X and Y axes as 1000, as shown below
We can use the following code:
Void CTtView :: OnDraw (CDC * pDC)
{
CTtDoc * pDoc = GetDocument ();
ASSERT_VALID (pDoc);
CRect rect;
GetClientRect (& rect);
PDC-> SetMapMode (MM_ANISOTROPIC);
PDC-> SetViewportOrg (0,0);
PDC-> SetViewportExt (rect.right, rect.bottom);
PDC-> SetWindowOrg (0,0);
PDC-> SetWindowExt (1000,1000);
PDC-> MoveTo (50,50);
PDC-> LineTo (50,950);
PDC-> LineTo (950,950);
PDC-> LineTo (50,50);
}
Code analysis:
1. GetClientRect (& rect); Get the rectangular area of the client area and store it in rect
2. Use pDC-> SetMapMode (MM_ANISOTROPIC); to set the mapping mode
3. Set the origin of logical coordinates by pDC-> SetViewportOrg (0,0) ;.
4. Via pDC-> SetViewportExt (rect.right, rect.bottom); and
pDC-> SetWindowExt (1000,1000); to determine the size correspondence between logical coordinates and device coordinates
5. In MM_ANISOTROPIC mode, the X-axis unit and Y-axis unit can be different
6. The method of determining the coordinate direction is that if the logical window range and the viewport range have the same sign, the logical coordinate direction and the viewport direction are the same, that is, the X axis is positive to the right, and the Y axis is downward to be positive.
7. If the display mode is changed to MM_ISOTROPIC, the X-axis unit and the Y-axis unit must be the same, and interested readers can use it for themselves.
(2) Establish coordinates with the center of the window as the origin, as follows:
Use the following code:
Void CTtView :: OnDraw (CDC * pDC)
{
CTtDoc * pDoc = GetDocument ();
ASSERT_VALID (pDoc);
CRect rect;
GetClientRect (& rect);
PDC-> SetMapMode (MM_ANISOTROPIC);
PDC-> SetViewportOrg (rect.right / 2, rect.bottom / 2);
PDC-> SetViewportExt (rect.right, rect.bottom);
PDC-> SetWindowOrg (0,0);
PDC-> SetWindowExt (1000, -1000);
PDC-> MoveTo (150,150);
DCpDC-> LineTo (-150, -200);
PDC-> LineTo (150, -150);
PDC-> LineTo (150,150);
}
Code analysis:
1. Use pDC-> SetViewportOrg (rect.right / 2, rect.bottom / 2); to set the origin of the viewport.
2. Use pDC-> SetViewportExt (rect.right, rect.bottom); and pDC-> SetWindowExt (1000, -1000); to determine the unit correspondence between device coordinates and logical coordinates.
3. Because the signs of the logical window range and the viewport range are inconsistent, the ordinate is inverted, so the Y axis is positive.
MM_LOENGLISH, MM_HIENGLISH, MM_LOMETRIC, MM_HIMETRIC, MM_TWIPS