Windows应用程序绘制图形时使用的是一种逻辑单位,每个逻辑单位的大小由映射模式决定,这个逻辑单位既可以与设备单位(屏幕或打印机上的一个 像素点)相同,也可以是一种物理单位(如毫米),还可以是用户自定义的一种单位。在Windows应用程序中,只要与输出有关系,都要使用映射模式。
首先谈谈映射模式基本知识,当Windows应用程序在其客户区绘制图形时,必须给出在客户区的位置,其位置用x和y 两个坐标表示,x表示横坐标,y表示纵坐标。在所有的GDI绘制函数中,这些坐标使用的是一种"逻辑单位"。当GDI函数将输出送到某个物理设备上 时,Windows将逻辑坐标转换成设备坐标(如屏幕或打印机的像素点)。逻辑坐标和设备坐标的转换是由映射模式决定的。映射模式被储存在设备环境中。 GetMapMode函数用于从设备环境得到当前的映射模式,SetMapMode函数用于设置设备环境的映射模式。
设备坐标(Device Coordinate)又称物理坐标(Physical Coordinate),指输出设备上的坐标。通常将屏幕上的设备坐标称为屏幕坐标。设备坐标用对象距离窗口左上角的水平距离和垂直距离来指定对象的位 置,是以像素为单位来表示的,设备坐标的X轴向右为正,Y轴向下为正,坐标原点位于窗口的左上角。当程序员在调用一个画线的GDI函数LineTo,画出 25.4mm(1英寸) 长的线时,他并不需要考虑输出的是何种设备。若设备是VGA显示器,Windows自动将其转化为96个像素点;若设备是一个300dpi的激光打印 机,Windows自动将其转化为300个像素点。
逻辑坐标(Logical Coordinate)是系统用作记录的坐标。在缺省的模式(MM_TEXT)下,逻辑坐标的方向和单位与设备坐标的方向和单位相同,也是以像素为单位来表示的,X轴向右为正,Y轴向下为正,坐标原点位于窗口的左上角。
逻辑坐标和设备坐标在以下缺省模式中一般是一致的:
1.窗口为非滚动窗口
2.窗口为滚动窗口,垂直滚动条位于滚动边框的最上端,水平滚动条位于最左端
Windows中包括以下3种设备坐标,以满足各种不同需要:
1.客户区域坐标,包括应用程序的客户区域,客户区域的左上角为(0,0)。
2.屏幕坐标,包括整个屏幕,屏幕的左上角为(0,0)。屏幕坐标用在WM_MOVE消息中(对于非子窗口)以及下面的Windows函数 中:CreateWindow和MoveWindow(都对于非子窗口)、GetMessage、GetCursorPos、 GetWindowRect、WindowFromPoint和SetBrushOrg中。用函数ClientToScreen和 ScreenToClient可以将客户区域坐标转换成屏幕区域坐标,或反之。
3.全窗口坐标,包括一个程序的整个窗口,包括标题条、菜单、滚动条和窗口框,窗口的左上角为(0,0)。使用GetWindowDC得到的窗口设备环境,可以将逻辑单位转换成窗口坐标。
Windows中逻辑坐标所在的坐标系称为"窗口",将设备坐标所在的坐标系称为"视口"。
"窗口"依赖于逻辑坐标,可以是像素点、毫米或程序员想要的其他尺度。
"视口"依赖于设备坐标(像素点)。通常,视口和客户区域等同。但是,如果程序员用GetWindowDC或CreateDC获取了一个设备环境,则视口也可以指全窗口坐标或屏幕坐标。点(0,0)是客户区域的左上角。x的值向右增加,y的值向下增加。
对于所有映射模式,Windows都用下面两个公式将窗口坐标转换成视口坐标:
xViewport=(xWindow-xWinOrg)*(xViewExt/xWinExt)+xViewOrg
yViewport=(yWindow-yWinOrg)*(yViewExt/yWinExt)+yViewOrg
其中,(xWindow,yWindows)是待转换的逻辑点,(xViewport,yViewport)是转换后的设备点, (xWinOrg,yWinOrg)是逻辑坐标的窗口原点;(xViewOrg,yViewOrg)是设备坐标的视口原点。在缺省的设备环境中,这两个点 均设置为(0,0),但它们可以改变。此公式意味着,逻辑点(xWinOrg,yWinOrg)总被映射为设备点 (xViewOrg,yViewOrg)。如果设备坐标是客户区域坐标或全窗口坐标,则Windows在画一个对象前,还必须将这些坐标转换成屏幕坐标。
Windows还能将视口(设备)坐标转换为窗口(逻辑)坐标:
xWindow=(xViewport-xViewOrg)*(xWinExt/xViewExt)+xWinOrg
yWindow=(yViewport-yViewOrg)*(yWinExt/yViewExt)+yWinOrg
可以使用Windows提供的两个函数DPtoLP和LPtoDP在设备坐标及逻辑坐标之间互相转换。
Windows定义了8种映射方式。
上述映射模式中又可分成以下3类:
MM_TEXT映射模式这种映射模式被称为"文本"映射方式,不是因为它对于文本最合适,而是轴的方向与读文本的方向一致。Windows提供了函 数SetViewportOrg和SetWindowOrg 用来设置视口和窗口的原点。缺省的窗口原点和视口原点均为(0,0),可以改变;缺省的窗口范围和视口范围均为(1,1),不可改变。
度量映射方式MM_LOMETRIC、MM_HIMETRIC、MM_LOENGLISH、MM_HIENGLISH和MM_TWIPS 将1个逻辑单位映射为固定的实际单位,其中1twip等于0.0176mm(1/1440英寸)。其他映射模式对应的物理单位参见表1。设置了映射模式以 后,Windows自动设置了窗口及视口的范围,范围本身的值并不重要,但范围比是一个固定的值,对于MM_LOMETRIC,Windows计算范围比 xViewExt/xWinExt=0.1mm中水平像素的点数。
自定义映射模式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);(WINCE不支持)
SetWindowExt(64,64);
SetViewportExt(hdc,GetDeviceCaps(hdc,LOGPIXELSX),GetDeviceCaps(hdc,LOGPIXELSY));