【转载】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

原文地址:http://blog.csdn.net/typecool/article/details/5898110

时间: 2024-10-10 13:42:30

【转载】GDI 映像方式 之 SetViewportOrgEx 与 SetWindowOrgEx 解析的相关文章

【转载】GDI 映像方式 之 SetViewportExtEx 与 SetWindowExtEx 解析

所谓视口代表设备,比如屏幕. 窗口代表我们的思维. 我们对windows说在(5,6)处画个点(调用GDI函数).windows认为是在我们的思维的(5,6)处画了个点.(也就是说5,6是逻辑坐标,GDI函数中的大部分都是逻辑坐标) 那么,要把它映射到屏幕上,必须作一些解释. 解释包括: 原点在哪里? 5,6代表什么? 注意,解释5,6时不光是距离问题,还有方向呢! SetViewportOrgEx和SetWindowOrgEx是管第一个问题的.设置原点和设置X轴Y轴方向(SetMapMode)

gem5验证cache的不同映像方式对cache命中率的影响

陆续写些关于新书<自己动手写CPU>的博客,本篇主要是讲解 gem5验证cache的不同映像方式对cache命中率的影响. cache的基本在http://blog.csdn.net/leishangwen/article/details/30049469中已有介绍,此处不再重复,只是简单介绍一下. 主要由三大部分组成: Cache存储体:存放由主存调入的指令与数据块. 地址转换部件:建立目录表以实现主存地址到缓存地址的转换. 替换部件:在缓存已满时按一定策略进行数据块替换,并修改地址转换部件

Java之Pull方式生成xml文件和解析xml文件

Pull XML解析器早已经被google集成到android sdk当中,它是google官方推荐的解析器. 如果我们要在Java桌面.J2ME等当中使用Pull方式生成xml文件和解析xml文件,需要用到kxml2: KXML解析器是基于普通XML PULL解析器的一个小巧的解析器,官网是http://kxml.org/ 普通XML PULL解析器的官网是http://xmlpull.org/ 实验开始: 在Eclipse中新建一个java项目,其中新建一个libs文件夹,拷贝从网上下载的k

[转载]GDI+中发生一般性错误

注:第一次写博客,把自己遇到的问题和收集的资料记录在博客上.在开发.NET应用中,使用 System.Drawing.Image.Save 方法而导致"GDI+ 中发生一般性错误"的发生,通常有以下三种原因:1. 相应的帐户没有写权限.解决方法:赋予 NETWORK SERVICE 帐户以写权限.2. 指定的物理路径不存在.解决方法:在调用 Save 方法之前,先判断目录是否存在,若不存在,则创建.if (!Directory.Exists(dirpath))Directory.Cre

转载:python文件打开方式详解——a、a+、r+、w+区别

第一步 排除文件打开方式错误: r只读,r+读写,不创建 w新建只写,w+新建读写,会将文件内容清零 (以w方式打开,不能读出.w+可读写) **w+与r+区别: r+:可读可写,若文件不存在,报错:w+: 可读可写,若文件不存在,创建 r+与a+区别: [python] view plain copy print? <span style="background-color: rgb(255, 255, 255);">fd = open("1.txt"

GDI映像

窗口与视口 将窗口.视口想象为两块叠放的透明玻璃 "窗口玻璃"在上,"视口玻璃"在下 我们以"窗口玻璃"坐标系为准,映射到"视口玻璃"上画图 原点 默认,两块玻璃的画图原点都在左上角,x轴向右,y轴向下 当使用 SetWindowOrgEx 时,相当于在"窗口玻璃"相应坐标处打个原点孔 当使用 SetViewportOrgEx 时,相当于在"视口玻璃"相应坐标处打个原点孔 然后将两块玻璃

javascript两种声明函数的方式的一次深入解析

声明函数的方式 javascript有两种声明函数的方式,一个是函数表达式定义函数,也就是我们说的匿名函数方式,一个是函数语句定义函数,下面看代码: /*方式一*/ var FUNCTION_NAME = function() { /* FUNCTION_BODY */}; /*方式二*/ function FUNCTION_NAME () { /* FUNCTION_BODY */}; 区别一 方式一的声明方式是先声明后使用 方式二的声明方式可以先调用,后声明 /*方式一: *先声明后使用 *

PHP 以编译方式安装,编译参数详解析!

./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-mysql=/usr/local/mysql --with-mysqli=/usr/bin/mysql_config --with-iconv-dir=/usr/local --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-

以芯片直读方式得到的全盘镜像解析及ext4日志区域解析

之前在centos中分析了/dev/sda1下的结构,但当对象是一块以芯片直读方式作出来的全盘镜像呢? 这次以安卓手机的全盘镜像为对象,尝试按照ext4文件系统结构手动解析,加强对ext4文件系统.EFI系统分区.GPT磁盘的理解,补充ext4文件系统的日志结构的描述. 我得到的全盘镜像有两种格式,一种.img,一种是.bin,两种镜像的组织方式是比较类似的,但可能因为是不同的直读机做出的原因,.img格式的镜像在"真正的数据"前附加了机器的标志信息. .bin格式镜像分析 .bin格