原文链接:http://blog.csdn.net/charlessimonyi/article/details/8264572

在GDI绘图前,一般要设置映射模式。映射模式是什么呢?它是逻辑长度单位与实际长度单位的一中转换关系,比如我要画一个长为800单位,宽为600单位的矩形,那么在不同的映射模式下,一个单位可能相当于一个像素,也可能相当于一毫米,也可能相当于一微米。也就是说在有的映射模式下,我们指定的800单位的长度相当于800像素,在有的映射模式下,我们指定的800单位的长度相当于800毫米,等等…..

我们来看一下关于设置映射模式的CDC类的成员函数SetMapMode()在MSDN中的说明:

函数原型virtual int SetMapMode(int nMapMode);
返回值:上一个映射模式。
参数nMapMode 指定新的映射模式,可为下列值之一:

MM_ANISOTROPIC

把逻辑单位转换为任意缩放轴上的任意单位。把映射模式设置为MM_ANISOTROPIC并不改变当前窗口或视图端口的设置。要改变单位、方向和缩放,可调用SetViewportExt和SetWindowtExt成员函数。
MM_HIENGLISH 每一逻辑单位对换0.001英寸,X向右为正,Y向上为正。
MM_HIMETRIC 每一逻辑单位对换0.001毫米,X向右为正,Y向上为正。
MM_ISOTROPIC 逻辑单位转换为带有对等缩放轴的任意单位。即X轴1单位与Y轴1单位是相等的。可使用SetViewportExt和SetWindowtExt成员函数,指定需要的单位和轴的方向。GDI修正可以保证X、Y轴的尺寸是一致的。
MM_LOENGLISH 每一逻辑单位对换0.01英寸,X向右为正,Y向上为正。
MM_LOMETRIC 每一逻辑单位对换0.01毫米,X向右为正,Y向上为正。
MM_TEXT 每一逻辑单位对换1设备像素,X向右为正,Y向下为正。
MM_TWIPS 每一逻辑单位对换1/20个点(1点为1/72英寸,1twip为1/1440英寸)。X向右为正,Y向上为正。

如果我们不对映射模式进行设置,保持默认值的话,它默认的模式为MM_TEXT,即一个逻辑单位代表一个像素点,实际上这种模式并不常用。为什么呢?比如你的显示器分辨率是1920*1080,你在你写的程序中画一个长为1024像素,宽为768像素的矩形,在你的屏幕上,这个矩形不大。但是当程序放在别人的电脑上运行时,可能别人的屏幕分辨率只有1024*768甚至800*600,那么你的这个矩形就无法很好的显示。当然,你也可以在你的程序中加入一些算法,比如先获取当前电脑显示器的分辨率,再根据一系列算法来确定你要画多少像素长、多少像素宽的矩形,这虽然可行,但是比较麻烦。所以我们在绘图前,一般要设置映射模式。

在这么多的模式中,其实我们最常用的是两个自定义的模式,MM_ISOTROPIC(各向同性)和MM_ANISOTROPIC(各向异性)模式。MM_ISOTROPIC模式中,横纵缩放比例是相同的,在这个模式下,我们画一个长300宽300的矩形,由于横纵缩放比例是相同的,300单位的长一定等于300单位的宽,这意味着它肯定是一个正方形。但是在MM_ANISOTROPIC模式下,由于可以将横纵缩放比例设置为不同,当我们再画一个长300宽300的矩形时,由于横纵比例不同,比如300单位的长对应着300像素,而300单位的宽对应着300毫米,所以这个矩形不一定是正方形。这一点大家可以动手测试。

现在我们来看一段绘图代码:

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);

第一行,创建一个CClientDC对象,该类用于在程序客户区绘图。

第二、三行,创建一个矩形对象,并获取程序的矩形客户区的尺寸信息保存到矩形对象中。

第四行,设置映射模式为MM_ANISOTROPIC模式,该模式下绘图,横纵缩放比不同。

当我们使用了这个模式后,我们要自己来定义这个缩放的比例,所以在第五行和第六行用SetWindowExt和SetViewportExt函数来设置,SetWindowExt的参数这里我们设置为500和500,意味着我们把客户区的长规定为500单位,宽规定为500单位。SetViewportExt的参数我们设置为rect的宽度和rect的高度,由于rect保存着的是我们的程序的客户区这个矩形的信息,这里给它的宽度和高度,即为我们程序客户区的实际宽度和高度。

最后一行画一个矩形,100,100代表着矩形左上角点的坐标,400,400代表着矩形右下角的坐标。注意,我们的程序的客户区的左上角坐标为(0,0),那么可以想象我们的这个矩形在我们500*500的客户区是什么样的了。我们画的这个矩形长为300单位,宽为300单位。300*300你感觉是个正方形,但我们用的是横纵缩放比不同的映射模式,我们知道我们的程序窗口都是长方形的,长和宽不相等,而我们把它的长和宽都规定为500,那么他们的缩放比例肯定不同。所以我们画出来的300*300的矩形也不是正方形,而是和我们的窗口一样的长方形。如果我们在程序的OnPaint()函数中绘制此矩形的话,拉伸程序窗口,我们会发现我们画的矩形的形状随着窗口的形状改变而改变。如果使用横纵缩放比相同的MM_ISOTROPIC映射模式,无论我们怎样拉伸程序窗口,我们画的图形始终是一个正方形。它的长宽比例总保持一致。

如果你不太理解可以动手试一试,学编程就应该多动手,多试试。

在我们以后的GDI绘图程序中该如何选用这两种模式呢?这样说吧,如果你希望你画的图形无论如何都能保持它的形状,特别是在画正方形和圆形的时候,就用MM_ISOTROPIC映射模式。如果你希望你的图形能够根据窗口的比例情况或者说窗口的拉伸情况而改变它的形状的话,就用MM_ANISOTROPIC映射模式。

GDI绘图中的映射模式CDC::SetMapMode()的更多相关文章

  1. Windows绘图中的GDI映射模式

    对Windows编程新手来说,GDI编程中最困难的部分就是映射模式(Mapping Mode). 什么是映射模式? 我们知道,GDI画图是在设备描述表这个逻辑意义上的显示平面上进行,其使用的是逻辑坐标 ...

  2. Windows GDI 映射模式(出自:Windows程序设计第5版-珍藏版)

    GDI映射模式(mapping mode):和映射模式紧密相关的还有4个其它的设备环境属性:1.窗口原点(window origin)2.视口原点(viewport origin)3.窗口范围(win ...

  3. GDI 映射模式(11)

    概述 调用 SetMapMode 函数可以设置映射模式: int SetMapMode( HDC hdc, // 设备环境句柄 int fnMapMode // 要设置的映射模式 ); 同样,调用 G ...

  4. VS2013中使用GDI+绘图

    VC范例,400多个例子源代码下载 http://download.csdn.net/detail/bigtree_mfc/7727977 VS2013中使用GDI+绘图和VC6.0不同,在VC6.0 ...

  5. Shapefile文件中的坐标绘制到屏幕时的映射模式设置

    pDC->SetMapMode(MM_ANISOTROPIC ); //首先选择MM_ANISOTROPIC映射模式,其它映射模式都不合适 pDC->SetWindowExt( max(a ...

  6. [Qt2D绘图]-06QPainter的复合模式&&双缓冲绘图&&绘图中的其他问题

    本篇读书笔记主要记录QPainter的复合模式&&双缓冲绘图&&绘图中的其他问题   大纲:     复合模式     双缓冲绘图     绘图中的其他问题       ...

  7. MFC GDI绘图基础

    一.关于GDI的基本概念 什么是GDI? Windows绘图的实质就是利用Windows提供的图形设备接口GDI(Graphics Device Interface)将图形绘制在显示器上. 在Wind ...

  8. MFC坐标空间与映射模式

    逻辑坐标:使用GDI绘图时使用的坐标系 设备坐标系:实际设备(显示器.打印机)的坐标系,即我们实际看到的坐标系. 坐标空间 在Windows NT/2000中Win32 API中支持以下四层坐标空间: ...

  9. Visual C++ 打印编程技术-编程基础-映射模式

    映射模式: Visual C++ 中采用的坐标映射方式使得用户图形坐标和输出设别的像素完全一致. eg:当屏幕的像素大小为800X600时,每英寸包含屏幕像素为96,打印机则需要几倍的点数才能达到同样 ...

随机推荐

  1. .Net Core On Liunx 环境搭建之安装Mysql8

    上一篇文章安装了MongoDB紧接上一篇随笔,来进行MySql数据库的安装 服务器环境:阿里云云服务器,操作系统CentOS.7-x64 注:文章的图片是我从我的CSDN博客中直接粘贴过来的,不是扒的 ...

  2. Spring IoC的底层技术支持——Java反射机制

    我们知道,通过 new XmlClassPathApplicationContext("beans.xml")等方式即可启动容器.在容器启动时,Spring 根据配置文件的描述信息 ...

  3. 微信小程序-通知公告滚动提示

    wxml如下: <view class='scroll_view_border'> <view class="srcoll_view" bindtap=" ...

  4. thinkphp5一些文件夹用法

    一.vendor通常放一些第三方的文件,如短信.支付宝等.用法: 1.在vendor中建一个文件夹: 2.在文件夹中新建一个类:主要命名空间(没有vendor ):如下面: 3.在控制器中调用,除了通 ...

  5. pyspider -- 禁止请求非200响应码抛异常

    在pyspider中若crawl()网址时出现非200的异常信息,会抛出一个异常. 可以在对应的回调函数上面通过@catch_status_code_error 进行修饰,这样就能不抛出异常正常进入回 ...

  6. python 装饰器 生成及原里

    # 装饰器形成的过程 : 最简单的装饰器 有返回值的 有一个参数 万能参数 # 装饰器的作用 # 原则 :开放封闭原则 # 语法糖 :@ # 装饰器的固定模式 #不懂技术 import time # ...

  7. array_x

    import java.util.*; public class array_x { public static void main(String args[]) { int a[][]={{2,4, ...

  8. 工作中使用的linux命令汇总

    ln -s  /usr/local/tomcat/ ./tomcat   创建软连接到/usr/local/tomcat tar -zxvf apache-kylin-2.4.0-bin-hbase1 ...

  9. LeetCode算法1—— 两数之和

    给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target ...

  10. Hbase表格设计

    Rowkey设计 Region: 基于RowKey的分区,可理解成MySQL的水平切分. 每个Region Server就是Hadoop集群中一台机器上的一个进程. 比如我们的有1-300号的RowK ...