Basic knowledge
The difference between SetWindowExt and SetViewportExt
GetClientRect (rectClient);
pDC-> SetMapMode (MM_ANISOTROPIC);
pDC-> SetWindowExt (CSize (1000,1000));
pDC-> SetViewportExt (rectClient.right, -rectClient.bottom);
pDC-> SetViewportOrg (rectClient.right / 2, rectClient.bottom / 2);
pDC-> Ellipse (-500, -500,500,500);
analyse as below:
SetWindowExt sets the window size (calculated in logical units), SetViewportExt sets the viewport size (calculated in physical units)
CRect rectClient;
GetClientRect (rectClient); // Get the physical size of the window (unit: pixels)
pDC-> SetMapMode (MM_ANISOTROPIC);
pDC-> SetWindowExt (1000, 1000); // Window logical size: 1000 * 1000,
pDC-> SetViewportExt (rectClient.right, -rectClient.bottom); // Change the Y coordinate direction --viewport uses physical size
pDC-> SetViewportOrg (rectClient.right / 2, rectClient.bottom / 2); // Set the window center point to the origin of the coordinate system-Viewport uses physical size
pDC-> Ellipse (CRect (-500, -500, 500, 500)); // Draw in logical units --- ordinary GDI API uses logical units
// In the default mode, the physical / logical value is 1: 1, which can be used interchangeably. However, the two cannot be mixed after using SetWindowExt / SetViewportExt.
In the above red part, my explanation is based on the physical origin as the coordinate system and the logical size as the unit to draw the circle. This problem will be explained in the following code.
Later, after my own elaboration, I think I finally figured out what happened.
The so-called mapping is physical and logical mapping. After using the GetClientRect method, the physical size of the window is obtained; then SetWindowExt is used to set the logical size of the window. The corresponding one is SetViewportExt, which means that a mapping is made here. The first parameter in SetWindowExt
cx
Specify the x-extent (in logical units) of the window.
X width (can this be understood?) With the first parameter in SetViewportExt
Cx
Specify the x-extent of the viewport (in device units).
Correspondence. It seems like the ratio of middle school. Logical width and physical width mapping, logical height and physical height mapping. In this way, once the mapping relationship is established, further operations are performed using the latter method.
The initial code is to display a limited circle in the window, and it will change as the window size changes.
I now change the parameters slightly.
CRect rectClient;
GetClientRect (rectClient);
pDC-> SetMapMode (MM_ANISOTROPIC);
pDC-> SetWindowExt (CSize (800,800));
pDC-> SetViewportExt (rectClient.right, -rectClient.bottom);
pDC-> SetViewportOrg (rectClient.right / 2, rectClient.bottom / 2);
pDC-> Ellipse (-500, -500,500,500);
Notice the code highlighted in red above. I have made the logical size smaller. Now notice that in the drawing code (shown in green), I have not modified its parameters. Compile and run it now. You will find that the trajectory of the circle in the implementation will exceed the window.
Just adjusted the mapping before physics and logic.
CRect rectClient;
GetClientRect (rectClient);
pDC-> SetMapMode (MM_ANISOTROPIC);
pDC-> SetWindowExt (CSize (1000,1000));
pDC-> SetViewportExt (rectClient.right, -rectClient.bottom);
pDC-> SetViewportOrg (rectClient.right / 2, rectClient.bottom / 2);
pDC-> Ellipse (0,0,500,500);
Adjust the parameters again, and you will find that the graph is really a two-dimensional coordinate graph.
After some testing, I think I should understand what each line of code means. Transformed into your own comments, it should be easier to understand and remember.
CRect rectClient;
GetClientRect (rectClient); // Get physical device size
pDC-> SetMapMode (MM_ANISOTROPIC); // Set the mapping mode
pDC-> SetWindowExt (CSize (1000,1000)); // device logical window size (may be different from physical window size)
pDC-> SetViewportExt (rectClient.right, -rectClient.bottom); // Set the range of the physical device to prepare for setting the dots
pDC-> SetViewportOrg (rectClient.right / 2, rectClient.bottom / 2); // Set the physical device coordinate origin, of course, based on the previous line of code
pDC-> Ellipse (-500, -500,500,500); // Based on the physical setting of the coordinate origin and logical unit, draw a circle.
You can transform the original code to make it easier to understand later:
CRect rectClient;
GetClientRect (rectClient);
pDC-> SetMapMode (MM_ANISOTROPIC);
pDC-> SetWindowExt (CSize (1000,1000));
pDC-> SetViewportExt (rectClient.right, -rectClient.bottom);
pDC-> SetViewportOrg (rectClient.left, rectClient.bottom); // Set the lower left corner of the window to the origin coordinate
pDC-> Ellipse (0,0,1000,1000);
You can transform the original code to make it easier to understand later:
CRect rectClient;
GetClientRect (rectClient);
pDC-> SetMapMode (MM_ANISOTROPIC);
pDC-> SetWindowExt (CSize (1000,1000));
pDC-> SetViewportExt (rectClient.right, -rectClient.bottom);
pDC-> SetViewportOrg (rectClient.left, rectClient.bottom); // Set the lower left corner of the window to the origin coordinate
pDC-> Ellipse (0,0,1000,1000);