MFC View-Port Origin and Window Origin

MFC Mapping Modes & Drawing Coordinate

1. Introduction to Coordinates & Mapping Modes

MFC supports two kinds of coordinate systems. One is Device Coordinate and the other one is Logical Coordinate. In device coordinate, we point out all in terms of pixels. In logical coordinate, we measure each unit in terms of Metric Standard or British Standard. How each unit maps to the logical measure is called the mapping. We can mention the mapping using the Mapping Modes. In MFC, having the knowledge of Drawing Origin is the key to draw in the Client Area the way you want.

In this Example, we will walk through the examples and demo videos, which will help us in learning the Mapping Modes and doing the MFC drawing using the device contexts. We will also try the ViewPort Origin and Window Origin and how to use them while drawing using MFC GDI APIs.

2. Three MFC Coordinate Systems

The first step is creating the SDI Application with no document view architecture support. Once the application is ready, we can start our drawing using the OnPaint() handler. Now, have a look at the below picture:

Screen, Window and Client Coordinates in MFC
Screen, Window and Client Coordinates in MFC

In the above picture, the black screen is the desktop. Top left corner of the desktop (P1) is the Origin of the Screen Coordinate. The notepad application is displaying on top of the desktop screen. Point P2 specifies the Origin of the notepad window. We can say P2 is the origin of the Window Coordinate system. If there are three windows in the desktop area, then three such Window Coordinate exits. Means, one for each window. The client area of the window is nothing but the working area of the window. In the notepad’s case, the actual working area is the portion of the window in which we type our text content. Point P3 specifies the Origin of the Client Coordinate system. In these three Coordinate Systems, we can use the Device or Logical units. In Device Coordinate, MFC measures the drawing units in terms of pixels.

Below piece of code, we will start with the client coordinate and then will move to Mapping Mode and Logical Coordinate based drawing.

When we run the SDI application it looks like below (Resized):

MFC Client Coordinate - Top-Left & Bottom-Right
MFC Client Coordinate – Top-Left & Bottom-Right

The screen marked in blue is termed as client area of the window. GetClientRect() function will help in getting the rectangular marked as blue in the above depiction. The function will get four values Left, Top, Right and Bottom and the picture also shows this above. Look at the below video that debugs and examines value after calling GetClientRect() function.


Video 1: Shows GetClientRect getting the Values in Device Units (Pixels)


3. Mapping Modes – MMISOTROPIC & MMANISOTROPIC

The Mapping Modes are useful to perform the real-world drawing. Say for example; let us say you are making software utility to perform an engineering drawing. When the drawing is printed out, you want to see the 10 mm line drawn in your monitor, measured as 10 mm in the hard copy, taken from the printer. Here, we need to represent how a single drawing unit measures to the real-world measuring standards. MFC supports eight mapping modes. The below picture shows these Mapping Modes:

MFC Mapping Modes
MFC Mapping Modes

For MM_TEXT Mapping Mode, the positive X moves from the default top left corner origin to the right side. This is true for other Modes as well. The picture shows how Y coordinate direction changes based on the mapping mode. MM_ISOTROPIC and MM_ANISOTROPIC have a user-defined coordinate system. In MM_ISOTROPIC MFC equally measures both x and y units. But in the MM_ANISOTROPIC mode X and Y can have different units of scale. The above picture shows for a given Mapping Mode how MFC calculates a single logical unit. The MM_TEXT mapping mode is the default mapping mode used by MFC. Using the SetMapMode function of the underlying Device Context, you can pick any of the mapping modes shown above.

A Device Context is Bag of Tools which defines property for the drawing action. It is a data structure in MFC. Let us say Drawing Board in a meeting room. The properties here are: White Drawing Board, Pen and it color, its thickness. Likewise, Device Context defines all the properties required for the drawing.

4. Drawing a Line Using MM_TEXT Mapping Mode

In the OnPaint handler, let us draw a line using MM_TEXT Mapping Mode. Remember from the previous picture that each unit you specify to the drawing function represents a pixel. For an example, if the length of line 100 means, it is 100 pixels long as the Mapping Mode is MM_TEXT. Next thing we should remember is that the origin is in the upper-left corner of the window. Here, Positive Y goes down. So for seeing the drawing of what we draw, we should specify both x & y units in positives (Look at the picture for reference). OK, let us draw a line. Have a look at the below code:

In the above code, first, we moved the drawing pen to the Origin 0,0 using MoveTo function. Then we asked MFC to draw a line by specifying the end point as 100,100 to the function LineTo. When we run the Example, we can see a line from origin 0,0 to the point at 100,100. This can be illustrated something like the below one:

MFC Drawing using MM_TEXT & MoveTo, LineTo Functions
MFC Drawing using MM_TEXT & MoveTo, LineTo Functions

For more explanation on how this work, watch the youtube video below.


Video 2: Drawing Using MM_TEXT Mapping Mode


What happens if we change the Mapping Mode from the default MM_TEXT to MM_LOMETRIC? The first thing one should know is that the Unit of measure changes from pixels to a millimetre. The second thing is that the Positive Y axis shifts its direction. Below is the Example that uses the MM_LOMETRIC as the mapping mode:

For More explanation look at the video below:


Video 3: Change the Mapping Mode to MM_LOMETRIC


5. Shifting Drawing Origin Via SetViewportOrg

In the previous examples, we saw that how we can set the Mapping Modes on the Device Context. Also, in the previous examples, MFC kept the drawing origin in the top left corner of the window which is the default origin. Device Context has the capability of changing this origin from the default left corner. We can do that via the SetViewPortOrg function call.

5.1 MFC SetViewportOrg Example

SetViewPortOrg function expects the new location in terms of pixel and shifts the drawing origin from top left corner to the new location. Have a look at the below code:

In the OnPaint() handler, first we shift the Origin from the top left corner to the center of the window. The rct is the CRect object, which we used to get the Client Area dimensions in device Coordinate. So, we specify the center of the client area in terms of a pixel to the SetViewportOrg API of the PaintDC. Below is the picture which shows the shifted Origin:

MFC Mapping Modes - Shifting the Drawing Origin
MFC Mapping Modes – Shifting the Drawing Origin

The code in effect is shown in the above picture. The Red one is the origin before the shift, and the blue one is the origin after the shift via SetViewportOrg API. Here, we specified the new origin in terms of pixels. In the below code, we create a blue pen and then draw a line using PaintDC . Remember, we previously set the Mapping Mode as MM_LOMETRIC. But, we comment those piece of code before trying with Snippet 4.2 (Watch the video at the end of this section).

After drawing the blue line, we draw one more line in red. This time we use the MM_LOENGLISH Mapping Mode (British Standard). At this stage, since we have gained a good idea of Mapping Modes, we no need to explore that again. The code is below:

Now running the entire code makes your drawing look like the one shown below (Note the shifted origin):

Drawing Lines after shifting the Drawing Origin
Drawing Lines after shifting the Drawing Origin

For More explanation look at the video below:


Video 4: Shifting the view-port origin using SetViewPortOrg API


6. Using the SetWindowOrg API

At this stage, we know what the SetViewportOrg API does. In a summary again, the SetViewPortOrg sets the drawing origin by specifying the values in terms of pixels. The SetWindowOrg function sets the given logical point as Lower Left Corner of the client Area Window.

Note the difference, View Port Origin is mentioned in terms of pixels and Window Origin is pointed out in terms of Logical units, which depends on the currently set Mapping Mode of the device context. Have a look at the below Example:

In this example, first we set the Mapping Mode as MM_LOMETRIC. Then we shifted the drawing origin to lower left corner of the screen by specifying the location to be shifted as pixels. Then using the SetWindowOrg function, we specify the logical unit -100, -100 should be at the lower left corner of the window. After this, we draw two lines using Red color Solid Pen. In those lines, one moves from the drawing origin(View Port Origin) to 500 unit in the positive X direction and other one moves 500 units in positive Y direction. Have a look at the below picture to understand this as it confuses most of MFC professionals:

MFC View-Port Origin and Window Origin
MFC View-Port Origin and Window Origin (Window Origin @ Lower Left Corner, the Red Mark shows View Port Origin)

To get better insight on View Port Origin and Window Origin, watch the video below:


Video 5: VC++ MFC View Port Origin and Window Origin


Source Code: Download VC++ MFC Mapping Mode, Window and ViewPort Origin Example From Google Drive

Do you like this Example? Please comment about it for others!!

This site uses Akismet to reduce spam. Learn how your comment data is processed.