Windows的GDI映射方式,逻辑坐标,设备坐标的敞亮

要讲下边包车型大巴公式,就要先说一下视口(Viewport 山东译作视埠)和窗口(Window 浙江译作视窗)

里头,(xWindow,yWindows)是待转换的逻辑点,(xViewport,yViewport)是改造后的设备点。若是设备坐标是顾客区域坐标或全窗口坐标,则Windows在画一个目的前,还非得将那么些坐标调换来荧屏坐标。

    当绘制的图形须要随着窗口的分寸改造而活动改换的时候,平日选用MM_ISOTROPIC和MM_ANISOTROPIC映射方式。它们的独占鳌头不一致正是前者的X轴和Y轴的逻辑单位的分寸是同样的,单词“isotropic”正是各样方向相等的情趣,此映射方式切合绘制圆或星型。而实际利用中,平常给X轴和Y轴取不相同的比重,那时候采取MM_ANISOTROPIC映射情势。单词“anisotropic”就是逐个方向相异的野趣。

要专一的是在上述的5映射方式下,ViewExt/WinExt的比例都以曾经分明了,不可能改换的,若是要改成三个值,只好在MM_ISOTROPIC和MM_ANISOTROPIC映射方式下行使SetViewportExtEx()和SetWindowExtEx()退换。何况那多个函数在上头5种炫人眼目方式下无效。

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

(1)Windows坐标种类
Windows坐标系分为逻辑坐标系和器具坐标系两种,GDI协助这两种坐标系。平日来讲,
GDI的文本和图片输出函数使用逻辑坐标,而在客商区移动或按下鼠标的鼠标地点是利用配备坐标。
<1>逻辑坐标系是面向DC的坐标系,这种坐标不思虑现实的设备项目,在绘图时,Windows会依照当下设置的映照情势将逻辑坐标转变为设备坐标。
<2>设备坐标系是面向物理设备的坐标系,这种坐标以像素或设施所能表示的小小长度单位为单位,X轴方向向右,Y轴方向向下。设备坐标系的原点地点(0, 0)不限制在设备彰显区域的左上角。

图片 1

(作者地址:南开东军事和政院学科技(science and technology)行业楼401室,100084)

ScreentoClient(&rect);

近日在学Win32的编制程序,看的是《Windows程序设计第5版》一书,那本书是吉林人翻译的,有个别译法和陆地差异,书中还只怕有局地漏洞百出的地点,比非常多时候必要中瑞典语对照阅读,下载请点击

总结,假使大家可以依据映射形式值的特点,逻辑坐标和设施坐标都取经简化的窗口和视口范围值的翻番,则逻辑坐标和设备坐标间的转载将未有抽样误差。

(4).自定义映射格局

 

(1)顾客区域坐标,满含应用程序的顾客区域,客商区域的左上角为(0,0)。

 

上述代码中调用SetMapMode函数将映射形式设置为自定义的,该调用必需放在SetWindowExt 和SetViewportExt调用从前,不然设置将会失效。
上述代码实际少将映射方式设置成逻辑MM_LOENGLISH,若程序猿必要设置逻辑MM_LOMETRIC、MM_HIMETRIC、MM_HIENGLISH 或MM_TWIPS,只需修改上述代码中的SetWindowExt的参数,该参数实际上是每英寸所满含的各样映射格局下的单位数。依据表1中各映射方式的参数,可得到表2中每英寸所对应的各逻辑单位的个数。

GetWindowRect() 获得的是在显示器坐标系下的RECT(即以显示器左上角为原点)
GetClientRect() 获得的是在顾客区坐标系下的RECT(即以所在窗口左上角为原点,去掉了标题栏总括,仅仅是个轻重缓急,再次来到值的左上角永恒为0,0) 
  
CRect rect;

由此一旦记住初始的公式,获得不错的应和的参数,就足以画出供给的图形。

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

      映射形式规定了在绘制图形时所依靠的坐标系,它定义了逻辑单位的骨子里尺寸、坐标增生势头,全体映射形式的坐标原点均在设施出口区域(如客商区或打印区)的左上角。其他,对于有些映射情势,客户还足以自定义窗口的长短和幅度,设置视图区的情理范围。
Windows定义了8种炫彩情势,见下表。
照耀形式使得技术员可不用考虑输出设备的具体设备坐标系,而在一个合併的逻辑坐标系中实行图片的绘图。

1.逻辑坐标和设施坐标

"窗口"重视于逻辑坐标,能够是像素点、分米或技术员想要的另外规格。

(3).映射格局

   首先,逻辑坐标这么些名词就让很两人惊叹,确实,无法“以文害辞”地精晓的翻译就不是好翻译   ------周豫才。哈哈,开个玩笑,大家要驾驭那四个东西,首先要想到倘让你要用Win32要绘制八个事物,该如何做呢?譬如绘制二个矩形,假若大家调用的是Rectangle(hdc,30,20,50,80),(这一个函数的用法是Rectangle(hdc,left,top,right,bottom),作者叫雷锋(Lei Feng),不用谢小编)。能够看见,跟比较多GDI函数同样,这么些函数里面使用了许多数字,坐标。让我们想起一下小学文化,绘制四个事物,不仅仅应该搞通晓她的长度,还应当搞掌握他的单位,那么这里的30,20,50,80的单位是什么啊?很两个人会说,是像素!这几个答案是对的,但是又不全对。事实上,Windows默认的投射方式(Mapping Mode,简称就是MM)是MM_TEXT,在MM_TEXT映射格局(TEXT实际上跟文字没有多大关系,是这种映射方式下的坐标方向,从左到右,从上到下,跟文字阅读方式一样)下,那个单位确实是像素。实际上,逻辑坐标和装置坐标的分别就在于他们的单位差异!

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

//定义视口的坐标轴方向及区域、定义域和值域,单位为像素(Pixel)
WINGDIAPI BOOL  WINAPI SetViewportExtEx(HDC, int, int, LPSIZE);
此API函数在MFC中封装为CDC::virtual CSize SetViewportExt(int cx, int cy);
只顾:SetViewportExt(Ex) 唯有在光彩夺目情势为MM_ANISOTROPIC或MM_ISOTROPIC时才有意义。

最终,那些映射格局,视口原点(ViewOrg),窗口原点(WinOrg)等,都以装备内容(DC Device Context,又译作装置内容、设备上下文等)的质量,设备内容实在就是您绘制的区域。有三种BeginPaint(在WM_PAINT时绘制无效区域),GetDC是客商端区域(在更新时绘制整个客商区域),GetWindowsDC是全方位窗口区域(能够绘制包蕴窗口标题栏,菜单栏区域)。那一个知识细讲的话又是另一篇博客了

逻辑坐标是单独于设备的,它与设备点的深浅非亲非故。使用逻辑单位,是贯彻"所见即所得"的根底。当程序猿在调用一个画线的GDI函数LineTo,画出25.4mm(1英寸) 长的线时,他并无需思索输出的是何种设备。若设备是VGA显示屏,Windows自动将其转化为九十七个像素点;若设备是一个300dpi的激光打字与印刷机,Windows自动将其转化为300个像素点。

 

好了,下边早先正文:

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

//设置逻辑窗口的原点坐标,缺省原点为(0,0)。
WINGDIAPI BOOL  WINAPI SetWindowOrgEx(HDC, int, int, LPPOINT);
此API函数在MFC中封装为CDC::CPoint SetWindowOrg(int x, int y);
留意:SetWindowOrg(Ex) 唯有在炫人眼目形式为MM_ANISOTROPIC或MM_ISOTROPIC时才有含义。

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

(3)全窗口坐标,包罗一个前后相继的全套窗口,富含标题条、菜单、滚动条和窗口框,窗口的左上角为(0,0)。使用GetWindowDC得到的窗口设备条件,能够将逻辑单位调换来窗口坐标。

View调用GetWindwoRect(&rect), 获得的坐标是:左上角(33,99),右下角(1040,524),那是View相对于显示器的坐标,当调用ScreenToClient(&rect),rect产生为:左上角(-2,-2),右上角(1007,423),-2,-2是client和window之间的区间差--border。

 

2.设施坐标

设备坐标系分为荧屏坐标系、窗口坐标系和顾客区坐标系三种相互独立的坐标系。
1.显示屏坐标系以显示器左上角为原点,一些与成套显示屏有关的函数均选取显示屏坐标,如GetCursorPos()、SetCursorPos()、CreateWindow()、MoveWindow()。弹出式菜单使用的也是荧屏坐标。
2.窗口坐标系以窗口左上角为坐标原点,它总结窗口标题栏、菜单栏和工具栏等限定。
3.客商区坐标系以窗口客商区左上角为原点,首要用以顾客区的绘图输出和窗口音信的管理。鼠标音讯的坐标参数使用顾客区坐标,CDC类绘图成员函数使用与顾客区坐标对应的逻辑坐标。

事实上公式拿出去,学数学的伴儿是还是不是就懂了大多了,那些公式特别首要,明白了那个公式,后边的许多事物就能够明白,首先,公式中的Window,WinOrg,WinExt,正是带了Win的东西,正是选拔的逻辑坐标的值,就跟GDI函数中的同样,逻辑坐标的单位或然是像素(MM_TEXT映射)、毫米(单位是0.1mm,在MM_LOMET福特ExplorerIC映射下)等等等等(看下图).

(2)显示屏坐标,蕴含全体显示屏,荧屏的左上角为(0,0)。显示屏坐标用在WM_MOVE新闻中(对于非子窗口)以至下面包车型大巴Windows函数中:CreateWindow和MoveWindow(都对此非子窗口)、GetMessage、GetCursorPos、GetWindowRect、WindowFromPoint和SetBrushOrg中。用函数ClientToScreen和ScreenToClient能够将客户区域坐标调换来显示器区域坐标,或反之。

GetClient(&rect);
举个比方:有个单文档程序

 

在介绍了逻辑英寸的知识未来,很轻易将OLEServer设置为基于逻辑英寸的炫人眼目形式。假设程序猿仅仅调用SetMapMode(hdc,MM_LOENGLISH)来设置映射格局,当前的照射形式为大要英寸,实际不是逻辑英寸。设置逻辑英寸必需自定义窗口和视口的限定,使xViewExt/xWinExt =0.01逻辑英寸中国水力电力对外公司平像素的罗列,当xViewExt=LOGPIXELSX,xWinExt=100时,其比率正好满意上述供给。

from: