Windows编程中的映射模式和坐标转换

From: http://www.vczx.com/article/show.php?id=1011820

一、Windows中的映射模式
1、Windows定义映射模式的目的
经过我的综合,Windows定义映射模的目的又以下几个方面:1、不同人的使用习惯。不同国家的,不同地区,以及不同的人因为习惯喜欢用不同的度量单位,有的人人喜欢用英寸,而有的人喜欢用公制中的厘米,毫米等。其他的人又喜欢用另外一些单位。、2、使软件与硬件向分离开来。让开发的软件能够最大限度的与硬件无关。3、提供逻辑和物理的一种转换。就相当于银行的利率。
2、默认的映射模式
默认的映射模式使MM_TEXT,它使以象素为单位的。X轴向左为正,Y轴向下为正。默认的坐标原点在左上角。
3、固定比例映射模式
固定比例的映射模式有MM_LOMETRIC、MM_HIMETRIC、MM_LOENGLISH、MM_HIENGLISH、MM_TWIPS种。它们默认的坐标原点都使在左上角。其区别在于每一个逻辑单位对应的物理大小不一样。所对用的逻辑单位分别为0.1毫米,0.01毫米,0.01英寸,0.001英寸,1/1440英寸(0.0007英寸)。
4、可变比例映射模式
对于可变比例的映射模式用户可以自己定义一个逻辑单位代表的大小,其大小可以任意。也可以让这个大小随环境改变而改变。有MM_ISOTROPIC,MM_ANISOTROPIC这两种映射模式。其逻辑单位的大小等于视口范围和窗口范围的比值。两者的不同在于前者要求X轴和Y轴的度量单位必须相同,而后者没有这样的限制。
二、Windows中的几种坐标体系
1、屏幕坐标
屏幕坐标描述物理设备(显示器、打印机等)的一种坐标体系,坐标原点在屏幕的左上角,X轴向右为正,Y轴向下为正。度量单位是象素。原点、坐标轴方向、度量单位都是不能够改变的。
2、设备坐标(又称物理坐标)
设备坐标是描述在屏幕和打印机显示或打印的窗体的一种坐标体系。默认的坐标原点是在其客户区的左上角。X轴向右为正,Y轴向下为正。度量单位为象素。原点和坐标轴方向可以改变,但是度量单位不可以改变。
3、逻辑坐标
逻辑坐标是在程序中控制显示,打印使用的坐标体系。该坐标系与定义的映射模式密切相关。默认的映射模式是MM_TEXT。我们可以通过设置不同的映射模式来改变该坐标体系的默认行为。
三、逻辑坐标和设备坐标之间的转换
现有如下代码:
void CMapModeView::OnPaint() 
{
       CPaintDC dc(this); 
       //获取设备类的设置
       CPoint ptOrgView,ptOrgWindow;
       CSize sizeView,sizeWindow;
       CString strMsg;
        ptOrgView=dc.GetViewportOrg();//获取视口原点
       ptOrgWindow=dc.GetWindowOrg();//获取窗口原点
       sizeView=dc.GetViewportExt();//获取视口范围
       sizeWindow=dc.GetWindowExt();//获取窗口范围

       strMsg.Format(_T("Viewport Extent:(%d,%d),\tViewport Org:(%d,%d)\tWindow Extent:(%d,%d)\tWindow Org(%d,%d)") sizeView.cx,sizeView.cy,ptOrgView.x,ptOrgView.y,
              sizeWindow.cx,sizeWindow.cy,ptOrgWindow.x,ptOrgWindow.y);
       TRACE("%s\n",strMsg);
       //设置映射模式以及原点
       dc.SetMapMode(MM_TEXT);//设置映射模式
       dc.SetWindowOrg(100,100);//设置窗口的坐标原点
       dc.SetViewportOrg(200,200);//设置视口的坐标原点
       dc.SetWindowExt(5,10);//改语句仅对可变比例映射模式有效
       dc.SetViewportExt(1,1);//同上
       ptOrgView=dc.GetViewportOrg();
       ptOrgWindow=dc.GetWindowOrg();
       sizeView=dc.GetViewportExt();
       sizeWindow=dc.GetWindowExt();
       strMsg.Format(_T("Viewport Extent:(%d,%d),\tViewport Org:(%d,%d)\tWindow Extent:(%d,%d)\tWindow Org(%d,%d)"),
              sizeView.cx,sizeView.cy,ptOrgView.x,ptOrgView.y,
              sizeWindow.cx,sizeWindow.cy,ptOrgWindow.x,ptOrgWindow.y);
       TRACE("%s\n",strMsg);
       
       //将点(300,400)从逻辑坐标体系映射到设备坐标体系。
       CPoint ptMap;
       ptMap=CPoint(300,400);
       dc.LPtoDP(&ptMap);
       strMsg.Format(_T("The Orginal Point(In LP):CPoint(300,400),Convert to DP is:CPoint(%d,%d)"),
                            ptMap.x,ptMap.y);
       TRACE("%s\n",strMsg);

       //将点(300,400)从设备坐标体系映射到逻辑坐标体系
       ptMap=CPoint(300,400);
       dc.DPtoLP(&ptMap);    
       strMsg.Format(_T("The Orginal Point(In DP):CPoint(300,400),Convert to LP is:CPoint(%d,%d)"),
              ptMap.x,ptMap.y);
       TRACE("%s\n",strMsg);
}
       以上代码最后调试输出结果为:
Viewport Extent:(1,1), Viewport Org:(0,0) Window Extent:(1,1) Window Org(0,0)
Viewport Extent:(1,1), Viewport Org:(200,200) Window Extent:(1,1) Window Org(100,100)
The Orginal Point(In LP):CPoint(300,400),Convert to DP is:CPoint(400,500)
The Orginal Point(In DP):CPoint(300,400),Convert to LP is:CPoint(200,300)
       按照MSDN上,函数SetWindowOrg(x,y)设定设备坐标下的点(x,y)对应于逻辑坐标的原点。SetVieportOrg(x,y)设定逻辑坐标下点(x,y)对应逻辑坐标的原点。而实际上如果同时设置了逻辑坐标和设备坐标原点的话,那么以上的说法是错误的。
在默认映射模式MM_TEXT下,一个逻辑单位对应于设备坐标下的一个象素。改变默认原点以后的坐标体系如下图所示:
(0,0)              Dx,Lx       (0,0)                             
                                                               (100,100)                      Lx
                                                                      (200,200)                  Dx
                                                                              .(300,400)



Dy,Ly                                Ly  Dy
       在VC中坐标系的转换和数学中的数学转化是不一样的。在这里是以距离为标准。首先看一下如何把点(300,400)如何从设备坐标转换成逻辑坐标。
在设备坐标体系下,点(300,400)与Y轴的距离为100个逻辑单位。那么所对应的逻辑坐标也要满足与逻辑坐标Y轴的距离为100个单位。又1个逻辑单位对应1个象素。所以所对应的设备坐标的X值为100+100=200。同样可以出对应的逻辑坐标的Y值为300。
按照同样的方法,我们也可以把逻辑坐标下的点(300,400)转换成设备坐标。在逻辑坐标下,点(300,400)与逻辑坐标Y轴的距离为200。那么在设备坐标体系,相应的设备坐标与设备坐标Y轴的距离也要为200。又1个逻辑单位对应1个象素,所以对应的设备坐标X值为200+200=400。同样的道理,可以求出对应的设备坐标Y值为500。
在这里,因为逻辑单位和设备单位一一对应,也可以把这个问题看作一个很简单的坐标平移问题来看。其结果是很显然的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/404686.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# 截取图片的方法

1、C#截取图片的方法 方法一、 一个像素一个像素的画&#xff0c;遍历每一个像素&#xff0c;速度慢 /// <summary> /// 截取一张图片的制定部分 /// </summary> /// <param name"bitmapPathAndName">原始图片路径名称<…

变压器油参数

以下体胀系数参考百度百科&#xff1a; 水银1.8210^-4 纯水2.0810^-4 煤油9.010^-4 酒精1.110^-3 汽油1.2410^-3 氢气3.6610^-3 氧气3.6710^-3 氨气3.8010^-3 空气 3.67610^-3 二氧化碳3.74110^-3 一切气体 ≈1/273 甘油 4.910^-4 乙醇 7.510^-4 相关&#xff1a…

Python用过的小知识备忘录

1. python中的优先权队列&#xff0c;priorityqueue用法&#xff1a;数字越小&#xff0c;表示优先级越高&#xff0c;越早被拿出 from queue import Queue from queue import PriorityQueue prioqueuePriorityQueue() prioqueue.put((1,hahaha)) prioqueue.put((5,ustc)) pr…

[react] 给组件设置很多属性时不想一个个去设置有什么办法可以解决这问题呢?

[react] 给组件设置很多属性时不想一个个去设置有什么办法可以解决这问题呢&#xff1f; es6展开运算符 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

cygwin This indicates that the /etc/passwd (and possibly /etc/group) files should be rebuilt 问题解决办法

From: http://blog.csdn.net/deaboway/article/details/6461587 我的Cygwin报&#xff1a; [css] view plaincopyYour group is currently "mkpasswd". This indicates that the /etc/passwd (and possibly /etc/group) files should be rebuilt. See the man p…

CSS布局教程:用DIV CSS实现国内经典式三行两列布局-CSS布局实例

我们碰到过很多的企业网站或其它小型的展示类网站&#xff0c;有一些共同的特点&#xff0c;即顶部放一个大的导航或BANNER&#xff0c;右侧是链接或图片&#xff0c;左侧放置内容&#xff0c;页面底部放置版权信息等。这样的形式是国内经典式的布局&#xff0c;我们这里不对它…

EC20模组使用MQTT库对接EMQX,基于STM32F407

一、说明 本lib库基于STM32F407编译&#xff0c;其他的cortexM4内核也支持&#xff0c;采用串口和EC20模组通信。 库包括两个文件&#xff1a;ec20_mqtt.h和ec20_mqtt.lib。使用时添加lib文件到工程中&#xff0c;头文件引用ec20_mqtt.h即可。 下载&#xff1a;https://gitee…

[react] 说说react diff的原理是什么

[react] 说说react diff的原理是什么 内存中存储两颗树&#xff0c;一颗树是已经渲染的树结构&#xff08;Current Tree&#xff09;&#xff0c;另一颗是即将变化的树&#xff08;Fiber Tree&#xff09;。 每次状态发生变化&#xff0c;会对原来的树结构进行遍历&#xff0c…

什么是I帧,P帧,B帧

From: http://blog.csdn.net/abcjennifer/article/details/6577934 视频压缩中&#xff0c;每帧代表一幅静止的图像。而在实际压缩时&#xff0c;会采取各种算法减少数据的容量&#xff0c;其中IPB就是最常见的。 简单地说&#xff0c;I帧是关键帧&#xff0c;属于帧内压缩。…

iOS 证书错误 Certificates下面的 App Store and Ad Hoc是灰的?? 点不了

原因 因为一个用户名下只能同时有一个发布证书&#xff0c;你之前建立了某个证书并且没有使用的话就无法再创建了&#xff0c;先把它撤销或者使用后才可以继续创建新的 转载于:https://www.cnblogs.com/yhj1787354782/p/4991182.html

linux中的memory management和page mapping

1 首先要说的最简单的是在一个process在运行的时候&#xff0c;它看到的内存是这个样子的。3G以后是给kernel使用的运行和动态分配的内存的空间&#xff0c;注意因为是process所看到的&#xff0c;下面全部都是虚拟地址空间。如下&#xff1a; 2 然后需要说的是Linux Physical …

[react] react的函数式组件有没有生命周期?

[react] react的函数式组件有没有生命周期&#xff1f; 没有 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

I帧、P帧、B帧

From: http://xiaoq169.blog.sohu.com/66865917.html 1. I帧&#xff1a;帧内编码帧 I帧特点&#xff1a; ①它是一个全帧压缩编码帧。它将全帧图像信息进行JPEG压缩编码及传输。 ②解码时仅用I帧的数据就可重构完整图像。 ③I帧描述了图像背景和运动主体的详情。 ④I帧不需要…

linux 使用paho C库实现mqtt客户端

一、下载 github 下载paho mqtt c库源码&#xff0c;编译安装库文件。 地址&#xff1a;https://github.com/eclipse/paho.mqtt.c 关键API&#xff1a;Paho Asynchronous MQTT C Client Library: MQTTAsync.h File Reference 说明&#xff1a;paho客户端库是纯c库&#xff…

Linux实验二报告

北京电子科技学院&#xff08;BESTI&#xff09; 实 验 报 告 课程&#xff1a;信息安全系统设计基础 班级&#xff1a; 201352 姓名&#xff1a;池彬宁 贺邦 学号&#xff1a;20135212 20135208 成绩&#xff1a; 指导教…

[react] 在react中什么是合成事件?有什么用?

[react] 在react中什么是合成事件&#xff1f;有什么用&#xff1f; 是一个跨浏览器原生事件包装器。 它具有与浏览器原生事件相同的接口&#xff0c;包括 stopPropagation() 和 preventDefault() &#xff0c;除了事件在所有浏览器中他们工作方式都相同。 个人简介 我是歌谣…

重学数据结构007——二叉查找树

之前的博客中提到过&#xff0c;我学习采用的参考书是《数据结构与算法分析——C语言描述》。这门书的组织安排与国内广泛实用的教材《数据结构——C语言版》比较不同。这本书描述了一些树和二叉树的概念&#xff0c;举例讲解了什么是树的三种遍历之后&#xff0c;就开始重点讲…

无线网卡共享Internet访问到电脑有线接口注意事项

一、共享网卡访问 网卡属性--共享--以太网 Note: 观察有线以太网的IPv4是否有Internet访问权限。Note&#xff1a;配置IPv4的NDS与无线网卡WLAN的属性一致。 二、有线网卡配置 Note&#xff1a;连接到有线网卡上的外接设备需要配置IP地址为192.168.137.xxx&#xff0c;处于同…

Nginx 多进程连接请求/事件分发流程分析

Nginx使用多进程的方法进行任务处理&#xff0c;每个worker进程只有一个线程&#xff0c;单线程循环处理全部监听的事件。本文重点分析一下多进程间的负载均衡问题以及Nginx多进程事件处理流程&#xff0c;方便大家自己写程序的时候借鉴。 一、监听建立流程 整个建立监听socket…

[react] useState和this.state的区别是什么?

[react] useState和this.state的区别是什么&#xff1f; useState内部基于 useReducer 实现&#xff0c;方法返回 state 本身以及一个修改 state 的方法。 通过 setXXX 修改数据&#xff0c;不会和 setState 一样进行对象属性合并&#xff0c;会直接覆盖。Hooks 函数组件中&a…