Windows的GDI映射方式,逻辑坐标,设备坐标的理解

最近在学Win32的编程,看的是《Windows程序设计第5版》一书,这本书是台湾人翻译的,有些译法和大陆不一样,书中还有一些错误的地方,很多时候需要中英文对照阅读,下载请点击

https://download.csdn.net/download/u013238941/10611720

好了,下面开始正文:

在看到GDI(GDI Graphic Device Interface图形设备接口)映射方式这一节的时候,书中又是逻辑坐标,又是设备坐标,又是视口,窗口,又是视埠什么的,搞得人头都大了。虽然我现在还没有完全读懂,但是我感觉我已经抓住了理解这些东西的主线,下面的东西就当作我的笔记吧:

1.逻辑坐标和设备坐标

   首先,逻辑坐标这个名词就让很多人望而却步,确实,不能“望文生义”地理解的翻译就不是好翻译   ------鲁迅。哈哈,开个玩笑,我们要理解这两个东西,首先要想到如果你要用Win32要绘制一个东西,该怎么做呢?比如绘制一个矩形,假设我们调用的是Rectangle(hdc,30,20,50,80),(这个函数的用法是Rectangle(hdc,left,top,right,bottom),我叫雷锋,不用谢我)。可以看到,跟很多GDI函数一样,这个函数里面使用了很多数字,坐标。让我们回忆一下小学知识,绘制一个东西,不仅应当搞清楚他的长度,还应该搞清楚他的单位,那么这里的30,20,50,80的单位是什么呢?很多人会说,是像素!这个答案是对的,但是又不全对。事实上,Windows默认的映射方式(Mapping Mode,简称就是MM)是MM_TEXT,在MM_TEXT映射方式(TEXT实际上跟文字没有多大关系,是这种映射方式下的坐标方向,从左到右,从上到下,跟文字阅读方式一样)下,这个单位确实是像素。实际上,逻辑坐标和设备坐标的区别就在于他们的单位不一样!

下面我们拿出一个公式

           

要讲上面的公式,就要先说一下视口(Viewport 台湾译作视埠)和窗口(Window 台湾译作视窗)

首先,不要被这两个名字迷惑了,这两个坐标是跟映射有关的,跟屏幕坐标系,窗口坐标系,客户端坐标系是相对独立的两个知识。

其实公式拿出来,学数学的小伙伴是不是就懂了大半了,这个公式非常重要,理解了这个公式,后面的很多东西就能理解,首先,公式中的Window,WinOrg,WinExt,就是带了Win的东西,就是使用的逻辑坐标的值,就跟GDI函数中的一样,逻辑坐标的单位可能是像素(MM_TEXT映射)、毫米(单位是0.1mm,在MM_LOMETRIC映射下)等等等等(看下图).

就是说我们在调用Win32函数绘图的时候,要知道自己使用的单位(根据映射模式确定的)。因为绘图函数里的数值,使用的就是这些单位,虽然默认的MM_TEXT映射模式使用的单位就是像素,但是很多时候其他单位也很有用,比如你要做一个屏幕尺子的时候,你要用尺子量一下物体有几厘米。尺子上的刻度就可以用其他的映射模式来画。但是屏幕在显示的时候却不能只知道逻辑坐标几厘米啊,屏幕得知道具体的像素位置才行啊!那这个时候,就需要用到上面的公式转换了。讲到这里,公式里的ViewExt/WinExt是什么意思就很明显了。那就是在当前逻辑坐标系下(比如几厘米,打比方哈),实际上是上面映射模式表格里的单位)对应的设备坐标应该是多少个像素!这样转换过后,得到实际的Viewport,就是该逻辑点在屏幕上的位置。

所以说视口和窗口实际上是表示的同一块区域,只不过是因为单位和原点的不同,需要进行映射,逻辑单位就是窗口,就是Window,就是像素,毫米,英寸,就是给人用的单位,就是设备无关的单位,设备单位就是视口,就是Viewport,就只能是像素,就是给设备用的单位,确定的一厘米,在不同的设备上的像素数可能会有区别,所以是设备相关的单位。

 

要注意的是在上述的5映射模式下,ViewExt/WinExt的比例都是已经确定了,不能更改的,如果要更改两个值,只能在MM_ISOTROPIC和MM_ANISOTROPIC映射模式下使用SetViewportExtEx()和SetWindowExtEx()更改。而且这两个函数在上面5种映射方式下无效。

最后,这些映射模式,视口原点(ViewOrg),窗口原点(WinOrg)等,都是设备内容(DC Device Context,又译作装置内容、设备上下文等)的属性,设备内容其实就是你绘制的区域。有三种BeginPaint(在WM_PAINT时绘制无效区域),GetDC是客户端区域(在更新时绘制整个客户区域),GetWindowsDC是整个窗口区域(可以绘制包括窗口标题栏,菜单栏区域)。这些知识细讲的话又是另一篇博客了

 

 

所以只要牢记开头的公式,得到正确的对应的参数,就可以画出需要的图形。

 

posted @ 2018-08-18 09:25 蓝域小兵 阅读(...) 评论(...) 编辑 收藏