Basic knowledge
CDC :: SetMapMode () in GDI drawing mode
Original link: http://blog.csdn.net/charlessimonyi/article/details/8264572
Before GDI drawing, generally set the mapping mode. What is the mapping mode? It is a conversion relationship between logical length units and actual length units. For example, if I want to draw a rectangle with a length of 800 units and a width of 600 units, then in different mapping modes, a unit may be equivalent to a pixel, or it may be It is equivalent to one millimeter and may be equivalent to one micrometer. That is to say, in some mapping modes, the length of 800 units that we specify is equivalent to 800 pixels. In some mapping modes, the length of 800 units that we specify is equivalent to 800 mm, and so on ...
Let's take a look at the MSDN description of the member function SetMapMode () of the CDC class that sets the mapping mode:
Function prototype virtual int SetMapMode (int nMapMode);
Return value: Previous mapping mode.
The parameter nMapMode specifies the new mapping mode and can be one of the following values:
MM_ANISOTROPIC
Converts logical units to arbitrary units on any scale axis. Setting the mapping mode to MM_ANISOTROPIC does not change the settings of the current window or view port. To change the units, orientation, and zoom, call the SetViewportExt and SetWindowtExt member functions.
MM_HIENGLISH Each logical unit is swapped for 0.001 inch, X is positive to the right, Y is positive.
MM_HIMETRIC swaps 0.001 millimeters for each logical unit, X is positive to the right and Y is positive to the right.
MM_ISOTROPIC logical units are converted to arbitrary units with equivalent scaling axes. That is, the X-axis 1 unit is the same as the Y-axis 1 unit. You can use the SetViewportExt and SetWindowtExt member functions to specify the required units and orientation of the axis. GDI correction can ensure that the dimensions of the X and Y axes are consistent.
MM_LOENGLISH Each logical unit is swapped by 0.01 inch. X is positive to the right and Y is positive to the right.
For each logical unit of MM_LOMETRIC, 0.01 mm is swapped, X is positive to the right and Y is positive to the right.
MM_TEXT swaps 1 device pixel for each logical unit, X is positive to the right and Y is positive to the down.
MM_TWIPS swaps 1/20 dots for each logical unit (1 dot is 1/72 inch, 1twip is 1/1440 inch). X is positive to the right, Y is positive.
If we don't set the mapping mode and keep the default value, its default mode is MM_TEXT, that is, a logical unit represents a pixel. In fact, this mode is not commonly used. why? For example, the resolution of your monitor is 1920 * 1080. You draw a rectangle with a length of 1024 pixels and a width of 768 pixels in the program you write. On your screen, this rectangle is not large. But when the program is run on someone else's computer, the screen resolution of others may only be 1024 * 768 or even 800 * 600, then your rectangle cannot be displayed well. Of course, you can also add some algorithms to your program, such as obtaining the resolution of the current computer display, and then determining how many pixels long and how wide a rectangle you want to draw based on a series of algorithms. Although this is feasible, but trouble. So we usually set the mapping mode before drawing.
Among so many modes, in fact, the two most commonly used modes are MM_ISOTROPIC (isotropic) and MM_ANISOTROPIC (anisotropic). In MM_ISOTROPIC mode, the horizontal and vertical scales are the same. In this mode, we draw a rectangle with a length of 300 and a width of 300. Since the horizontal and vertical scales are the same, the length of 300 units must equal the width of 300 units, which means It must be a square. However, in the MM_ANISOTROPIC mode, because the horizontal and vertical scaling can be set differently, when we draw a rectangle with a length of 300 and a width of 300, due to the different vertical and horizontal proportions, for example, a length of 300 units corresponds to 300 pixels, and a 300 unit The width corresponds to 300 mm, so this rectangle is not necessarily a square. This can be tested manually.
Now let's look at a piece of drawing code:
Copy code
CClientDC dc (this);
CRect rect;
GetClientRect (& rect);
dc.SetMapMode (MM_ANISOTROPIC);
dc.SetWindowExt (500,500);
dc.SetViewportExt (rect.Width (), rect.Height ());
dc.Rectangle (100,100,400,400);
Copy code
In the first line, a CClientDC object is created. This class is used to draw in the client area of the program.
In the second and third lines, a rectangular object is created, and the size information of the rectangular client area of the program is obtained and stored in the rectangular object.
In the fourth line, set the mapping mode to MM_ANISOTROPIC mode. In this mode, the horizontal and vertical zoom ratios are different.
When we use this mode, we have to define the scaling ratio ourselves, so we use the SetWindowExt and SetViewportExt functions to set in the fifth and sixth lines. We set the parameters of SetWindowExt to 500 and 500 here, which means we set the client The length of the district is 500 units and the width is 500 units. The parameters of SetViewportExt are set to the width and height of the rect. Since rect holds the rectangle information of the client area of our program, the width and height are given here, which is the actual width and height of the client area of our program. .
The last line draws a rectangle, 100,100 represents the coordinates of the upper-left corner of the rectangle, and 400,400 represents the coordinates of the lower-right corner of the rectangle. Note that the coordinates of the upper left corner of the client area of our program is (0,0), then you can imagine what our rectangle looks like in our 500 * 500 client area. The rectangle we draw is 300 units long and 300 units wide. 300 * 300 You feel like a square, but we use different mapping modes with different horizontal and vertical zoom ratios. We know that our program windows are rectangular, and the length and width are not equal, and we specify its length and width as 500, then their scaling must be different. So the 300 * 300 rectangle we draw is not a square, but a rectangle similar to our window. If we draw this rectangle in the program's OnPaint () function, if we stretch the program window, we will find that the shape of the rectangle we draw changes as the shape of the window changes. If we use the MM_ISOTROPIC mapping mode with the same aspect ratio, no matter how we stretch the program window, the shape we draw will always be a square. Its aspect ratio is always the same.
If you don't understand well, you can try it yourself. Learn programming, you should do it more.
How to choose these two modes in our future GDI drawing program? Let's put it this way, if you want the shape you draw to maintain its shape anyway, especially when drawing squares and circles, use the MM_ISOTROPIC mapping mode. If you want your shape to change its shape based on the scale of the window or the stretching of the window, use the MM_ANISOTROPIC mapping mode.