【转载】GDI 映像方式 之 SetViewportOrgEx 与 SetWindowOrgEx 解析
SetViewportOrgEx 与 SetWindowOrgEx 解析
这两个函数,用来改变视端口和窗口的原点,并都具有改变轴的效果,以致(0,0)不再指左上角。
「视端口」是依据设备坐标(图素)的。通常,视端口和显示区域相同.视端口也可以是指整窗口坐标或者屏幕坐标。点(0,0)是显示区域(或者整个窗口或屏幕)的左上角,x的值向右增加,y的值向下增加。
「窗口」是依据逻辑坐标的,逻辑坐标可以是图素、毫米、英寸或者您想要的任何其它单位。
对于视端口和窗口的概念可以这样理解: 幻想显示器大小可以随便改变,那么显示器每次都变成view「视端口」的太小就可以了,window「窗口」就没存在的必要了。
view「视端口」就是实际所需的大小; window「窗口」就是显示器给你的限制。
再来看下Windows中的几种坐标体系
1、屏幕坐标
屏幕坐标描述物理设备(显示器、打印机等)的一种坐标体系,坐标原点在屏幕的左上角,X轴向右为正,Y轴向下为正。度量单位是图素。原点、坐标轴方向、度量单位都是不能够改变的。
2、设备坐标(又称物理坐标)
设备坐标是描述在屏幕和打印机显示或打印的窗体的一种坐标体系。坐标原点是在其客户区的左上角。X轴向右为正,Y轴向下为正。度量单位为图素。原点和坐标轴方向可以改变,但是度量单位不可以改变。
3、逻辑坐标
逻辑坐标是在程序中控制显示,打印使用的坐标体系。该坐标系与定义的映射模式密切相关。默认的映射模式是MM_TEXT。我们可以通过设置不同的映射模式来改变该坐标体系的默认行为。 我们使用逻辑坐标系绘图,然后要在设备坐标系下显示。所以就有一个逻辑坐标和设备坐标之间的转换。
SetViewportOrgEx的参数总是使用设备坐标系单位(图素)。 假设显示区域为cxClient个图素宽和cyClient个图素高。映像方式为MM_TEXT。 如果想将逻辑点(0,0)定义为显示区域的中心,可进行如下呼叫:
SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ; 逻辑点(0,0)将映像为设备点(cxClient/2,cyClient/2)。
显示区域的坐标系变成如下形状:

SetWindowOrgEx的参数总是使用逻辑单位。 要想获得与上面使用SetViewportOrgEx同样的效果则可以进行如下呼叫:
SetWindowOrgEx (hdc, -cxClient / 2, -cyClient / 2, NULL) ; 逻辑点(-cxClient / 2,-cyClient / 2)映像为设备点(0,0),即显示区域的左上角。
很多人对于SetWindowOrgEx使用负数坐标参数表示很困惑,当然也包括我自己。进过几天的思考,终于恍然大悟。这里做一下解释。
首先要知道 不管对窗口和视端口原点作什么改变,设备坐标点(0,0)始终是显示区域的左上角。
我是这样理解的,窗口(逻辑)原点始终指向视端口(设备)原点。这样就很好解释了。
SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ; 逻辑点(0,0)将映像为设备点(cxClient/2,cyClient/2)。
设置视端口中心点为设备原点,逻辑原点映射之。
SetWindowOrgEx (hdc, -cxClient / 2, -cyClient / 2, NULL) ; 逻辑点(-cxClient / 2,-cyClient / 2)映像为设备点(0,0),即显示区域的左上角。
将逻辑原点起始坐标设置为 (-cxClient / 2,-cyClient / 2),再映射到设备原点。
假设函数调用时坐标如图所示:

首先,将坐标(-50 , -50)设置为逻辑原点的起始坐标。
然后,将逻辑原点映射到设备原点,这里是显示区域的左上角。
函数调用后上图改变为:

当我们使用逻辑坐标-50,-50的时候,被映像到了设备原点,也就是显示区域的左上角。
当我们使用逻辑坐标0,0的时候,便被映像到了设备中心点。
我们绘图的时候使用的是逻辑坐标,系统显示图像的时候是使用设备坐标,所以会有一个转换过程。
现在我们在逻辑坐标50,50处进行绘图,映像方式为MM_TEXT(转换比率1:1),系统显示时转换为设备坐标:
设备坐标点X = (50 - (-50 ) ) * (1/1) + 0 = 100
设备坐标点Y = (50 - (-50 ) ) * (1/1) + 0 = 100
这下清楚了吧。
再附下设备坐标与逻辑坐标的转换公式:
设备坐标点X = (待转换的逻辑点X - 逻辑坐标的窗口原点X) * (设备坐标的视端口范围X / 逻辑坐标的窗口范围X) + 设备坐标的视端口原点X
逻辑坐标点X = (待转换的设备点x - 设备坐标的视端口原点x) * (逻辑坐标的窗口范围x / 设备坐标的视端口范围x) + 逻辑坐标的窗口原点x
【转载】GDI 映像方式 之 SetViewportOrgEx 与 SetWindowOrgEx 解析的更多相关文章
- 【转载】GDI 映像方式 之 SetViewportExtEx 与 SetWindowExtEx 解析
所谓视口代表设备,比如屏幕. 窗口代表我们的思维. 我们对windows说在(5,6)处画个点(调用GDI函数).windows认为是在我们的思维的(5,6)处画了个点.(也就是说5,6是逻辑坐标,G ...
- 框架源码系列七:Spring源码学习之BeanDefinition源码学习(BeanDefinition、Annotation 方式配置的BeanDefinition的解析)
一.BeanDefinition 1. bean定义都定义了什么? 2.BeanDefinition的继承体系 父类: AttributeAccessor: 可以在xml的bean定义里面加上DTD ...
- [转载]GDI+中发生一般性错误
注:第一次写博客,把自己遇到的问题和收集的资料记录在博客上.在开发.NET应用中,使用 System.Drawing.Image.Save 方法而导致“GDI+ 中发生一般性错误”的发生,通常有以下三 ...
- (转载)GDI+双缓冲
双缓冲在GDI+里可以有效的提高描画效率.改善显示的质量. 下面的代码是一个最简单的双缓冲的模板.可以根据需要,做简单的修改即可. Bitmap CacheImage( [Width], [Heigh ...
- (转载)CentOS6下 源代码方式安装openERP7.0
CentOS6下 源代码方式安装openERP7.0 安装背景 :CPU32 bit,CentOS 6.4版本,openERP7.0,linux shell为bash,PostgreSQL9.2 1. ...
- 转载:python文件打开方式详解——a、a+、r+、w+区别
第一步 排除文件打开方式错误: r只读,r+读写,不创建 ###f.readline()是读取第一行,f.readlines()是读取全部并返回一个列表 w新建只写,w+新建读写,会将文件内 ...
- 【转载】SQL Server 2008 R2 使用的端口解析
转载博客:http://www.cnblogs.com/studyzy/archive/2009/11/30/1614139.html SQL Server在安装到服务器上后,出于服务器安全的需要,所 ...
- 【转载】Hadoop NameNode 高可用 (High Availability) 实现解析
转载:https://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop-name-node/ NameNode 高可用整体架构概述 在 Had ...
- [转]Android自定义控件:进度条的四种实现方式(Progress Wheel的解析)
最近一直在学习自定义控件,搜了许多大牛们Blog里分享的小教程,也上GitHub找了一些类似的控件进行学习.发现读起来都不太好懂,就想写这么一篇东西作为学习笔记吧. 一.控件介绍: 进度条在App中非 ...
随机推荐
- HDU 1009 FatMouse' Trade(贪心)
FatMouse' Trade Problem Description FatMouse prepared M pounds of cat food, ready to trade with the ...
- 2015 ACM/ICPC Asia Regional Shanghai Online
1001 Puzzled Elena 1002 Antonidas 1003 Typewriter 1004 Count the Grid 1005 Code Formatting 1006 Ther ...
- 36.中国特色社会主义的体制中有这样的现象:地方省政府要坚持党的领导和按 照国务院的指示进行安全生产。请编写一个java应用程序描述上述的体制现象。 要求如下: (1)该应用程序中有一个“党中央”接口:CentralPartyCommittee,该接口中 有个“坚持党的领导”方法:void partyLeader() (2)该应用程序中有一个“国务院”抽象类:StateCouncil,该抽象类中有
//接口:CentralPartyCommittee package jieKou; public interface CentralPartyCommittee { void partyLeader ...
- 正则表达式 Pattern & Matcher
1 compile and pattern Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(Strin ...
- JPA 系列教程16-继承-联合子类-JOINED
联合子类策略 这种情况下子类的字段被映射到各自的表中,这些字段包括父类中的字段,并执行一个join操作来实例化子类. 举例 如果实体类Teacher继承实体类Person,实体类Student也继承自 ...
- js常用API 数据类型 基本类型,基本包装类型,引用类型 Object String Array Boolean Number Date Math
数据类型 变量.作用域及内存 基础类型(primitive value):Undefined.Null.Boolean.Number和String.这些类型在内存中分别占用固定大小的空间,他们的值保存 ...
- mybatis---------insert,delete ,update的批量操作
在数据量大的情况下,可以使用批量 提高性能 批量插入insert 方法一: <insert id="insertbatch" parameterType="java ...
- C++编写一个简单的DLL
什么是DLL: 自从微软推出16位的Windows操作系统起,此后每种版本的Windows操作系统都非常依赖于动态链接库(DLL)中的函数和数据,实际上 Windows操作系统中几乎所有的内容都由DL ...
- Chapter 2 Open Book——3
But when I walked into the cafeteria with Jessica — 但是当我和Jessica 一起走进自助餐厅的时候 trying to keep my eyes ...
- 解析好的静态页面.shtml浏览器无法解析.需要apache解析后再返回给浏览器
解析好的静态页面.shtml浏览器无法解析.需要apache解析后再返回给浏览器 让Apache支持SHTML(SSI)的配置方法 http.conf放开addtype text/html .shtm ...