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

图片 2

近年在学Win32的编制程序,看的是《Windows程序设计第5版》大器晚成书,那本书是云南人翻译的,有些译法和陆上不符合,书中还会有部分荒谬的地点,超级多时候要求中匈牙利(Hungary卡塔 尔(阿拉伯语:قطر‎语对照阅读,下载请点击

Windows应用程序绘制图形时利用的是黄金时代种逻辑单位,每一个逻辑单位的轻重由映射方式决定,
那么些逻辑单位既可以够与设施单位(荧屏或打字与印刷机上的叁个像素点卡塔尔相近,也得以是大器晚成种物理单
位(如分米卡塔尔国,还是能够是客户自定义的风度翩翩种单位。在Windows应用程序中,只要与输出有涉及,都
要使用映射形式。本文的目标是支援读者领会映射形式的意气风发对基本知识,并对在动用中不经常现身的一些主题材料建议应用方案。

大器晚成、映射格局基本知识
当Windows应用程序在其顾客区绘制图形时,必需交给在客商区的地点,其任务用x和y
四个坐标表示,x表示横坐标,y表示纵坐标。在装有的GDI绘制函数中,那个坐标使用的是大器晚成种”逻辑单位”。当GDI函数将出口送到有些物理设备上时,Windows将逻辑坐标
调换来设备坐标(如显示屏或打字与印刷机的像素点卡塔尔国。逻辑坐标和装置坐标的转移是由映射形式决
定的。映射格局被储存在装置条件中。GetMapMode函数用于从设备条件获得当前的映照格局,SetMapMode函数用于安装设备条件的照耀格局。
1.逻辑坐标

好了,上面开头正文:

逻辑坐标是单独于设备的,它与设备点的轻重非亲非故。使用逻辑单位,是达成”所见即所得”的底子。当程序猿在调用三个画线的GDI函数LineTo,画出25.4mm(1英寸)
长的线时,他并没有必要考虑输出的是何种设备。若设备是VGA显示器,Windows自动将其转会为玖拾玖个像素点;若设备是一个300dpi的激光打字与印刷机,Windows自动将其转会为300个像素点。

在看到GDI(GDI Graphic Device
Interface图形设备接口)
辉映格局那焕发青新春的时候,书中又是逻辑坐标,又是道具坐标,又是视口,窗口,又是视埠什么的,搞得人头都大了。就算自身前天尚未完全读懂,然而自个儿倍感本人后生可畏度掀起了接头这几个事物的主线,下边包车型大巴东西就当作自个儿的笔记吧:

2.设施坐标

1.逻辑坐标和配备坐标

Windows将GDI函数中钦定的逻辑坐标映射为器具坐标,在具备的设备坐标种类中,单位以像素点为准,水平值从左到右增大,垂直值从上到下增大。

 
 首先,逻辑坐标那个名词就让超多个人心惊胆跳,确实,不可能“以管窥天”地领悟的翻译就不是好翻译 
 ——周豫山。哈哈,开个玩笑,大家要明白那多个东西,首先要想到假若您要用Win32要绘制叁个事物,该怎么办啊?比如绘制八个矩形,假若大家调用的是Rectangle(hdc,30,20,50,80),(那些函数的用法是Rectangle(hdc,left,top,right,bottom),作者叫雷锋(Lei Feng卡塔 尔(英语:State of Qatar),不用谢小编)。能够看看,跟超多GDI函数同样,这几个函数里面使用了许好些个字,坐标。让大家纪念一下完全小学文化,绘制三个东西,不仅仅应该搞通晓她的长短,还应有搞理解她的单位,那么这里的30,20,50,80的单位是怎么着吧?非常多人会说,是像素!那些答案是没有错,不过又不全对。事实上,Windows默许的炫耀方式(Mapping
Mode,简单的称呼就是MM)是MM_TEXT,在MM_TEXT映射格局(TEXT实际上跟文字未有多大关系,是这种映射情势下的坐标方向,从左到右,从上到下,跟文字阅读形式相同)下,那一个单位实乃像素。实际上,逻辑坐标和设施坐标的区分就在于他们的单位分裂等!

Windows中满含以下3种配备坐标,以满意种种不相同须要:

下边大家拿出五个公式

(1)客商区域坐标,包涵应用程序的客商区域,客商区域的左上角为(0,0卡塔 尔(阿拉伯语:قطر‎。

         
 图片 1

(2)显示器坐标,包罗总体荧屏,显示器的左上角为(0,0卡塔尔国。显示器坐标用在WM_MOVE音信中(对于非子窗口卡塔 尔(英语:State of Qatar)甚至下边包车型大巴Windows函数中:CreateWindow和MoveWindow(都对此非子窗口)、GetMessage、GetCursorPos、GetWindowRect、WindowFromPoint和SetBrushOrg中。用函数ClientToScreen和ScreenToClient能够将客商区域坐标转变到显示屏区域坐标,或反之。

要讲上边的公式,将要先说一下视口(Viewport 江西译作视埠)和窗口(Window
湖南译作视窗)

(3)全窗口坐标,包罗七个主次的方方面面窗口,包涵标题条、菜单、滚动条和窗口框,窗口的左上角为(0,0卡塔 尔(阿拉伯语:قطر‎。使用GetWindowDC获得的窗口设备条件,能够将逻辑单位转变来窗口坐标。

先是,不要被那三个名字吸引了,那七个坐标是跟映射有关的,跟显示屏坐标系,窗口坐标系,客商端坐标系是争持独立的多少个文化。

3.逻辑坐标与设备坐标的调换格局

实际上公式拿出去,学数学的同伙是或不是就懂了大概了,这么些公式特别关键,领悟了这一个公式,前面包车型地铁大多东西就能够驾驭,首先,公式中的Window,WinOrg,WinExt,正是带了Win的事物,就是选拔的逻辑坐标的值,就跟GDI函数中的相像,逻辑坐标的单位大概是像素(MM_TEXT映射)、毫米(单位是0.1mm,在MM_LOMET索罗德IC映射下)等等等等(看下图).

辉映方式定义了Windows怎么样将GDI函数中钦点的逻辑坐标映射为设备坐标。要继续研讨映射方式大家要介绍Windows有关映射形式的有些术语:我们将逻辑坐标所在的坐标系称为”窗口”,将设备坐标所在的坐标系称为”视口”。

图片 2

“窗口”正视于逻辑坐标,可以是像素点、分米或技士想要的其余标准。

实属大家在调用Win32函数绘图的时候,要掌握自己行使的单位(依据映射格局规定的)。因为绘图函数里的数值,使用的正是这一个单位,纵然暗中同意的MM_TEXT映射格局选择的单位正是像素,不过众多时候任何单位也很有用,譬喻您要做三个屏幕尺子的时候,你要用尺子量一下实体有几毫米。尺子上的刻度就能够用别的的映照方式来画。可是荧屏在展现的时候却不可能只通晓逻辑坐标几分米啊,荧屏得领会具体的像素地方才行啊!那这时,就要求选取下边包车型大巴公式调换了。讲到这里,公式里的ViewExt/WinExt是哪些意思就很显眼了。那就是在这里时此刻逻辑坐标系下(举例几毫米,打比如哈),实际上是地点映射格局表格里的单位)对应的器材坐标应该是有个别个像素!那样调换之后,得到实质上的Viewport,正是该逻辑点在荧屏上的职位。

“视口”信赖于设备坐标(像素点卡塔 尔(英语:State of Qatar)。平常,视口和顾客区域等同。不过,若是程序猿用GetWindowDC或CreateDC获取了三个器材条件,则视口也可以指全窗口坐标或显示器坐标。点(0,0卡塔 尔(阿拉伯语:قطر‎是顾客区域的左上角。x的值向右增添,y的值向上扩张。

据此说视口和窗口实际上是意味的如出黄金时代辙块区域,只不过是因为单位和原点的比不上,必要举行映射,逻辑单位正是窗口,正是Window,便是像素,分米,英寸,便是给人用的单位,正是设备毫不相关的单位,设备单位正是视口,便是Viewport,就只可以是像素,就是给配备用的单位,分明的一分米,在分化的装置上的像素数只怕会有分别,所以是设备相关的单位。

对此全数映射方式,Windows都用上边五个公式将窗口坐标转变成视口坐标:

 

  1. xViewport = (xWindow – xWinOrg) * (xViewExt / xWinExt) + xViewOrg
  2. yViewport = (yWindow – yWinOrg) * (yViewExt / yWinExt) + yViewOrg

要注意的是在上述的5映射方式下,ViewExt/WinExt的百分比都以已经规定了,不能够改换的,假设要转移五个值,只好在MM_ISOTROPIC和MM_ANISOTROPIC映射方式下行使SetViewportExtEx()和SetWindowExtEx()校订。并且那多少个函数在上头5种炫彩情势下无效。

在那之中,(xWindow,yWindows卡塔 尔(英语:State of Qatar)是待调换的逻辑点,(xViewport,yViewport卡塔 尔(阿拉伯语:قطر‎是改造后的设备点。假若设备坐标是客商区域坐标或全窗口坐标,则Windows在画二个对象前,还必需将那些坐标转变到显示屏坐标。

最后,这么些映射形式,视口原点(ViewOrg),窗口原点(WinOrg)等,都以设备内容(DC
Device
Context,又译作装置内容、设备上下文等)的性质,设备内容实在就是您绘制的区域。有二种BeginPaint(在WM_PAINT时绘制无效区域),GetDC是顾客端区域(在立异时绘制整个顾客区域),GetWindowsDC是漫天窗口区域(能够绘制包罗窗口标题栏,菜单栏区域)。这个知识细讲的话又是另生龙活虎篇博客了

那五个公式使用了分别钦赐窗口和视口原点的点:(xWinOrg,yWinOrg卡塔尔是逻辑坐标的窗口原点;(xViewOrg,yViewOrg卡塔尔是器械坐标的视口原点。在缺省的配备条件中,那三个点均安装为(0,0卡塔尔,但它们得以更改。此公式意味着,逻辑点(xWinOrg,yWinOrg卡塔尔总被映射为设备点(xViewOrg,yViewOrg卡塔尔国。

 

Windows还能够将视口(设备卡塔尔国坐标转换为窗口(逻辑卡塔尔国坐标:

 

  1. xWindow=(xViewport-xViewOrg)*(xWinExt/xViewExt)+xWinOrg
  2. yWindow=(yViewport-yViewOrg)*(yWinExt/yViewExt)+yWinOrg

于是只要记住起头的公式,获得正确的相应的参数,就足以画出须要的图片。

能够选择Windows提供的五个函数DPtoLP和LPtoDP在装置坐标及逻辑坐标之间人机联作转变。

 

4.映射情势的项目

Windows定义了表1所列出的8种绚烂格局。

映 射 方 式 逻 辑 单 位 X 轴 增 加 Y 轴 增 加 毫 米
MM_TEXT 像 素 点 与 设 备 有 关
MM_LOMETRIC 0. 1mm 0.1
MM_HIMETRIC 0. 01mm 0.01
MM_LOENGLISH 0. 01英寸 0.254
MM_HIENGLISH 0.001英寸 0.0254
MM_TWIPS 1/1440英寸 0.0176
MM_ISOTROPIC 任 意(x=y) 可 选 可 选 可 设
MM_ANISOTROPIC 任 意(x!=y) 可 选 可 选 可 设

注:MM_TWIPS常常在打字与印刷机上,单位是1/40磅(1磅=1/72英寸卡塔尔。

上述映射情势中又可分为以下3类:

  1. MM_TEXT映射格局这种映射情势被称得上”文本”映射方式,不是因为它对
    于文本最合适,而是轴的大方向与读文件的主旋律风度翩翩致。Windows提供了函数SetViewportOrg和SetWindowOrg
    用来安装视口和窗口的原点。缺省的窗口原点和视口原点均为(0,0卡塔 尔(阿拉伯语:قطر‎,能够改良;缺省的窗
    口范围和视口范围均为(1,1卡塔尔,不可改造。
  2. 心胸映射形式MM_LOMETRIC、MM_HIMETRIC、MM_LOENGLISH、MM_HIENGLISH和MM_TWIPS
    将1个逻辑单位映射为稳固的其实单位,其中1twip约等于0.0176mm(1/1440英寸)。其余映射情势对应的概略单位参见表1。设置了绚烂形式之后,Windows自动设置了窗口及视口的范围,范围自个儿的值并不首要,但范围比是八个恒定的值,对于MM_LOMETPRADOIC,Windows总计范围比xViewExt/xWinExt=0.1mm中国水力电力对外公司平像素的罗列。
  3. 自定义映射形式MM_ISOTROPIC和MM_ANISOTROPIC二种酷炫格局允许程序猿设置自己的窗口和视口范围。MM_ISOTROPIC和MM_ANISOTROPIC的区分是所设置的x轴和y轴的的界定必得生机勃勃律,而MM_ANISOTROPIC所设置的x轴和y轴的的限定能够不相同。isotropi的情趣是”
    在具有矛头肖似”,anisotropic的意趣正相反。自定义映射格局中窗口和视口的原点和限定都足以改造,技师可以安装自个儿须要的照射形式。函数SetWindowExt和SetViewportExt
    用于转移窗口和视口的范围。上边包车型客车代码将1个逻辑单位映射成0.396mm(1/64英寸)。

SetMapMode(hDC, MM_ISOTROPIC); 
SetWindowExt(64, 64); 
SetViewportExt(hdc,GetDeviceCaps(hdc,LOGPIXELSX),GetDeviceCaps(hdc, LOGPIXELSY)); 

二、与映射方式有关的主题材料的清除
实际上应用中,程序猿会境遇有的与体现情势有关的主题素材。比如OLEServer中映射模式的安装、怎么着减少逻辑坐标与设施坐标间相互调换的固有误差等。上边,小编就商讨一下那多少个难题的解决格局。
1.OLEServer中映射情势的装置方式

开荒OLEServer应用程序时,若是技术员直接调用SetMapMode函数将映射格局设置成衡量映射格局中的意气风发种后,在Windows95/98上程序会寻常运转,但在WindowsNT上对象出示的大小比边框小。经过小编研商后,开掘WindowsNT上OLEServer应使用基于逻辑英寸的映照情势。在争论哪些设置基于逻辑英寸的照耀格局前,大家先介绍一下逻辑英寸的概念。

Windows在展现时以”逻辑英寸”为单位,逻辑英寸比其实的英寸要大。假若Windows程序行使实际英寸,则平时的10磅文本在显示屏上就能小到大概难以辨认,因而Windows使用放大了的”逻辑英寸”来代表文本。逻辑英寸只影响显示,而不影响打字与印刷。

行使GetDeviceCaps函数可获取当前配备的各样技能,其首先个参数nIndex提示要获取音信的类型。当nIndex为HORubiconZSIZE和VERTSIZE时,可得到展现区域的上升的幅度和高度;当nIndex
为HO路虎极光ZRES和VERTRES时,可拿到每种水平和垂直方向的像素数即分辨率;当nIndex的值为LOGPIXELSX
和LOGPIXELSY时,可收获水平和垂直方向每逻辑英寸所含像素数。

在介绍了逻辑英寸的学问未来,超轻易将OLEServer设置为基于逻辑英寸的映射情势。要是程序员仅仅调用SetMapMode(hdc,MM_LOENGLISH)来安装映射情势,当前的映照形式为大意英寸,并非逻辑英寸。设置逻辑英寸必需自定义窗口和视口的节制,使xViewExt/xWinExt
=0.01逻辑英寸中国水力电力对外公司平像素的罗列,当xViewExt=LOGPIXELSX,xWinExt=100时,其比率刚好满意上述供给。

以下是设置映射形式的代码。

intxLogPixPerInch = GetDeviceCaps(hdc, LOGPIXELSX); 
intyLogPixPerInch = GetDeviceCaps(hdc, LOGPIXELSY); 
SetMapMode(MM_ANISOTROPIC); 
SetWindowExt(100, 100); 
SetViewportExt(xLogPixPerInch, yLogPixPerInch); 

上述代码中调用SetMapMode函数将映射形式设置为自定义的,该调用必得放在SetWindowExt
和SetViewportExt调用以前,不然设置将会失效。
上述代码实际大校映射方式设置成逻辑MM_LOENGLISH,若技师须要安装逻辑MM_LOMETRIC、MM_HIMETRIC、MM_HIENGLISH
或MM_TWIPS,只需改善上述代码中的SetWindowExt的参数,该参数实际上是每英寸所蕴藏的种种映射情势下的单位数。依照表1中各映射方式的参数,可收获表2中每英寸所对应的各逻辑单位的个数。

诸如,要安装逻辑MM_TWIPS,函数SetWindowExt中的参数为应1440。

2.逻辑坐标与设备坐标调换时基值误差的管理

表2

映 射 模 式 每 英 寸 所 对 应 的 逻 辑 单 位 数
MM_LOENGLISH 100
MM_HIENGLISH 1000
MM_LOMETRIC 254
MM_HIMETRIC 2540
MM_TWIPS 1440

当大家将映射格局设置成基于逻辑英寸的MM_LOMETENVISIONIC时,窗口的范围设为256,视口的范围设为96(在VGA显示屏下LOGPIXELSX的值卡塔尔,约2.6个逻辑单位对应1个像素,那分明会诱致超级大的相对误差,它会显未来应用程序的种种方面:顾客区的三个有的未有被刷新;对象时期自然从没间距,却显得出有间隔;对象在荧屏的例外职位上会裁减或附加二个像素等难题。

能够利用以下四个步骤防止转变相对误差。(1)尽量选用窗口范围和视口范围比能够整除的映射格局,举个例子基于逻辑英寸的MM_TWIPS其窗口范围和视口范围比1440/96,可简化为15/1,从设备坐标转变为逻辑坐标前卫未测量误差,从撤除引用误差角度看,MM_TWIPS比其余多少个映射格局都要好。(2)窗口范围和视口范围比不能够整除时,也硬着头皮将其简化,举例,当使用0.3900mm
中的将1个逻辑单位映射成1/64英寸的投射方式时,其窗口范围和视口范围比值为64/96,可简化为2/3。假如大家将逻辑单位的值都取为2的倍数,设备单位的值都取为3的翻番,转变后就一向不精度的不见了。

归咎,假如我们能够基于映射方式值的特点,逻辑坐标和设备坐标都取经简化的窗口和视口范围值的翻番,则逻辑坐标和装置坐标间的转载将还没标称误差。

(笔者地址:武大东军政大学学科学和技术行业楼401室,100084卡塔尔国

发表评论

电子邮件地址不会被公开。 必填项已用*标注