windows端口映射:Windows中的映射模式来源: 发布时间:星期四, 2009年2月12日 浏览:93次 评论:0
、Windows中映射模式 1、Windows定义映射模式目 经过我综合Windows定义映射模目又以下几个方面:1、区别人使用习惯区别国家区别地区以及区别人习惯喜欢用区别度量单位有人人喜欢用英寸而有人喜欢用公制中厘米毫米等其他人又喜欢用另外些单位、2、使软件Software和硬件向分离开来让开发软件Software能够最大限度和硬件无关3、提供逻辑和物理种转换就相当于银行利率 2、默认映射模式 默认映射模式使MM_TEXT,它使以象素为单位X轴向左为正Y轴向下为正默认坐标原点在左上角 3、固定比例映射模式 固定比例映射模式有MM_LOMETRIC、MM_HIMETRIC、MM_LOENGLISH、MM_HIENGLISH、MM_TWIPS种它们默认坐标原点都使在左上角其区别在于每个逻辑单位对应物理大小不样所对用逻辑单位分别为0.1毫米0.01毫米0.01英寸0.001英寸1/1440英寸(0.0007英寸) 4、可变比例映射模式 对于可变比例映射模式用户可以自己定义个逻辑单位代表大小其大小可以任意也可以让这个大小随环境改变而改变有MM_ISOTROPICMM_ANISOTROPIC这两种映射模式其逻辑单位大小等于视口范围和窗口范围比值两者区别在于前者要求X轴和Y轴度量单位必须相同而后者没有这样限制 2、Windows中几种坐标体系 1、屏幕坐标 屏幕坐标描述物理设备(显示器、打印机等)种坐标体系坐标原点在屏幕左上角X轴向右为正Y轴向下为正度量单位是象素原点、坐标轴方向、度量单位都是不能够改变 2、设备坐标(又称物理坐标) 设备坐标是描述在屏幕和打印机显示或打印窗体种坐标体系默认坐标原点是在其客户区左上角X轴向右为正Y轴向下为正度量单位为象素原点和坐标轴方向可以改变但是度量单位不可以改变 3、逻辑坐标 逻辑坐标是在中控制显示打印使用坐标体系该坐标系和定义映射模式密切相关默认映射模式是MM_TEXT我们可以通过设置区别映射模式来改变该坐标体系默认行为 3、逻辑坐标和设备坐标的间转换 现有如下代码: void CMapModeView::OnPa { CPaDC dc(this); //获取设备类设置 CPo ptOrgView,ptOrgWindow; CSize sizeView,sizeWindow; CString strMsg; ptOrgView=dc.GetViewportOrg;//获取视口原点 ptOrgWindow=dc.GetWindowOrg;//获取窗口原点 sizeView=dc.GetViewportExt;//获取视口范围 sizeWindow=dc.GetWindowExt;//获取窗口范围 strMsg.Format(_T(\"Viewport Extent:(%d,%d),\\tViewport Org:(%d,%d)\\tWindow Extent:(%d,%d)\\tWindow Org(%d,%d)\"), sizeView.cx,sizeView.cy,ptOrgView.x,ptOrgView.y, sizeWindow.cx,sizeWindow.cy,ptOrgWindow.x,ptOrgWindow.y); TRACE(\"%s\\n\",strMsg); //设置映射模式以及原点 dc.SetMapMode(MM_TEXT);//设置映射模式 dc.SetWindowOrg(100,100);//设置窗口坐标原点 dc.SetViewportOrg(200,200);//设置视口坐标原点 [Page] dc.SetWindowExt(5,10);// 改语句仅对可变比例映射模式有效 dc.SetViewportExt(1,1);//同上 ptOrgView=dc.GetViewportOrg; ptOrgWindow=dc.GetWindowOrg; sizeView=dc.GetViewportExt; sizeWindow=dc.GetWindowExt; strMsg.Format(_T(\"Viewport Extent:(%d,%d),\\tViewport Org:(%d,%d)\\tWindow Extent:(%d,%d)\\tWindow Org(%d,%d)\"), sizeView.cx,sizeView.cy,ptOrgView.x,ptOrgView.y, sizeWindow.cx,sizeWindow.cy,ptOrgWindow.x,ptOrgWindow.y); TRACE(\"%s\\n\",strMsg); //将点(300,400)从逻辑坐标体系映射到设备坐标体系 CPo ptMap; ptMap=CPo(300,400); dc.LPtoDP(&ptMap); strMsg.Format(_T(\"The Orginal Po(In LP):CPo(300,400),Convert to DP is:CPo(%d,%d)\"), ptMap.x,ptMap.y); TRACE(\"%s\\n\",strMsg); //将点(300,400)从设备坐标体系映射到逻辑坐标体系 ptMap=CPo(300,400); dc.DPtoLP(&ptMap); strMsg.Format(_T(\"The Orginal Po(In DP):CPo(300,400),Convert to LP is:CPo(%d,%d)\"), ptMap.x,ptMap.y); TRACE(\"%s\\n\",strMsg); } 以上代码最后调试输出结果为: Viewport Extent:(1,1), Viewport Org:(0,0) Window Extent:(1,1) Window Org(0,0) Viewport Extent:(1,1), Viewport Org:(200,200) Window Extent:(1,1) Window Org(100,100) The Orginal Po(In LP):CPo(300,400),Convert to DP is:CPo(400,500) The Orginal Po(In DP):CPo(300,400),Convert to LP is:CPo(200,300) 按照MSDN上SetWindowOrg(x,y)设定设备坐标下点(xy)对应于逻辑坐标原点SetVieportOrg(x,y)设定逻辑坐标下点(xy)对应逻辑坐标原点而实际上如果同时设置了逻辑坐标和设备坐标原点话那么以上说法是 在默认映射模式MM_TEXT下,个逻辑单位对应于设备坐标下个象素改变默认原点以后坐标体系如下图所示: (0,0) DxLx (0,0) (100,100) Lx (200,200) Dx .(300,400) Dy,Ly LyDy 在VC中坐标系转换和数学中数学转化是不样在这里是以距离为标准首先看下如何把点(300400)如何从设备坐标转换成逻辑坐标 [Page]在设备坐标体系下点(300400)和Y轴距离为100个逻辑单位那么所对应逻辑坐标也要满足和逻辑坐标Y轴距离为100个单位又1个逻辑单位对应1个象素所以所对应设备坐标X值为100+100=200同样可以出对应逻辑坐标Y值为300 按照同样思路方法我们也可以把逻辑坐标下点(300400)转换成设备坐标在逻辑坐标下点(300400)和逻辑坐标Y轴距离为200那么在设备坐标体系相应设备坐标和设备坐标Y轴距离也要为200又1个逻辑单位对应1个象素所以对应设备坐标X值为200+200=400同样道理可以求出对应设备坐标Y值为500 在这里逻辑单位和设备单位对应也可以把这个问题看作个很简单坐标平移问题来看其结果是很显然 Windows映射模式及相关问题解决 Windows应用绘制图形时使用是种逻辑单位每个逻辑单位大小由映射模式决定这个逻辑单位既可以和设备单位(屏幕或打印机上个像素点)相同也可以是种物理单 位(如毫米)还可以是用户自定义种单位在Windows应用中只要和输出有关系都要使用映射模式本文目是帮助读者了解映射模式些基本知识并对在使用中经常 出现些问题提出解决方案 、映射模式基本知识 当Windows应用在其客户区绘制图形时必须给出在客户区位置其位置用x和y 两个坐标表示x表示横坐标y表示纵坐标在所有GDI绘制中这些坐标使用是 种\"逻辑单位\"当GDI将输出送到某个物理设备上时Windows将逻辑坐标 转换成设备坐标(如屏幕或打印机像素点)逻辑坐标和设备坐标转换是由映射模式决 定映射模式被储存在设备环境中GetMapMode用于从设备环境得到当前映射模 式SetMapMode用于设置设备环境映射模式 1.逻辑坐标 逻辑坐标是独立于设备它和设备点大小无关使用逻辑单位是实现\"所见即所得\"基础当员在个画线GDILineTo画出25.4mm(1英寸)长线时他并不需要考虑输出是何种设备若设备是VGA显示器Windows自动将其转化为96个像素点;若设备是个300dpi激光打印机Windows自动将其转化为300个像素点 2.设备坐标 Windows将GDI中指定逻辑坐标映射为设备坐标在所有设备坐标系统中单位以像素点为准水平值从左到右增大垂直值从上到下增大 Windows中包括以下3种设备坐标以满足各种区别需要: (1)客户区域坐标包括应用客户区域客户区域左上角为(0,0) (2)屏幕坐标包括整个屏幕屏幕左上角为(0,0)屏幕坐标用在WM_MOVE消息中(对于非子窗口)以及下面Windows中:CreateWindow和MoveWindow(都对于非子窗口)、GetMessage、GetCursorPos、GetWindowRect、WindowFromPo和SetBrushOrg中用ClientToScreen和ScreenToClient可以将客户区域坐标转换成屏幕区域坐标或反的 (3)全窗口坐标包括个整个窗口包括标题条、菜单、滚动条和窗口框窗口左上角为(0,0)使用GetWindowDC得到窗口设备环境可以将逻辑单位转换成窗口坐标 3.逻辑坐标和设备坐标转换方式 映射方式定义了Windows如何将GDI中指定逻辑坐标映射为设备坐标要继续讨论映射方式我们要介绍Windows有关映射模式些术语:我们将逻辑坐标所在坐标系称为\"窗口\"将设备坐标所在坐标系称为\"视口\" \"窗口\"依赖于逻辑坐标可以是像素点、毫米或员想要其他尺度 \"视口\"依赖于设备坐标(像素点)通常视口和客户区域等同但是如果员用GetWindowDC或CreateDC获取了个设备环境则视口也可以指全窗口坐标或屏幕坐标点(0,0)是客户区域左上角x值向右增加y值向上增加 对于所有映射模式Windows都用下面两个公式将窗口坐标转换成视口坐标: xViewport=(xWindow-xWinOrg)*(xViewExt/xWinExt)+xViewOrg yViewport=(yWindow-yWinOrg)*(yViewExt/yWinExt)+yViewOrg 其中(xWindow,yWindows)是待转换逻辑点(xViewport,yViewport)是转换后设备点如果设备坐标是客户区域坐标或全窗口坐标则Windows在画个对象前还必须将这些坐标转换成屏幕坐标 这两个公式使用了分别指定窗口和视口原点点:(xWinOrg,yWinOrg)是逻辑坐标窗口原点;(xViewOrg,yViewOrg)是设备坐标视口原点在缺省设备环境中这两个点均设置为(0,0)但它们可以改变此公式意味着逻辑点(xWinOrg,yWinOrg)总被映射为设备点(xViewOrg,yViewOrg) Windows还能将视口(设备)坐标转换为窗口(逻辑)坐标: xWindow=(xViewport-xViewOrg)*(xWinExt/xViewExt)+xWinOrg yWindow=(yViewport-yViewOrg)*(yWinExt/yViewExt)+yWinOrg 可以使用Windows提供两个DPtoLP和LPtoDP在设备坐标及逻辑坐标的间互相转换 4.映射模式种类 Windows定义了表1所列出8种映射方式 上述映射模式中又可分成以下3类: 映 射 方 式 逻 辑 单 位 X 轴 增 加 Y 轴 增 加 毫 米 MM_TEXT 像 素 点 右 下 和 设 备 有 关 MM_LOMETRIC 0. 1mm 右 上 0.1 MM_HIMETRIC 0. 01mm 右 上 0.01 MM_LOENGLISH 0. 254mm 右 上 0.254 MM_HIENGLISH 0. 0254mm 右 上 0.0254 MM_TWIPS 0.0176mm 右 上 0.0176 MM_ISOTROPIC 任 意(x=y) 可 选 可 选 可 设 MM_ANISOTROPIC 任 意(x!=y) 可 选 可 选 可 设 MM_TEXT映射模式这种映射模式被称为\"文本\"映射方式不是它对 于文本最合适而是轴方向和读文本方向致Windows提供了SetViewportOrg和SetWindowOrg 用来设置视口和窗口原点缺省窗口原点和视口原点均为(00)可以改变;缺省窗 口范围和视口范围均为(11)不可改变 度量映射方式MM_LOMETRIC、MM_HIMETRIC、MM_LOENGLISH、MM_HIENGLISH和MM_TWIPS将1个逻辑单位映射为固定实际单位其中1twip等于0.0176mm(1/1440英寸)其他映射模式对应物理单位参见表1设置了映射模式以后Windows自动设置了窗口及视口范围范围本身值并不重要但范围比是个固定值对于MM_LOMETRICWindows计算范围比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); SetWindowExt(64,64); SetViewportExt(hdc,GetDeviceCaps(hdc,LOGPIXELSX),GetDeviceCaps(hdc,LOGPIXELSY)); 2、和映射模式有关问题解决 实际应用中员会遇到些和显示模式有关问题例如OLEServer中映射模式 设置、如何减少逻辑坐标和设备坐标间相互转换误差等下面笔者就讨论下这两个 问题解决思路方法 1.OLEServer中映射模式设置思路方法 开发OLEServer应用时如果员直接SetMapMode将映射模式设置成度量映射方式中种后在Windows95/98上会正常运行但在WindowsNT上对象显示大小比边框小经过笔者研究后发现WindowsNT上OLEServer应使用基于逻辑英寸映射方式在讨论如何设置基于逻辑英寸映射方式前我们先介绍下逻辑英寸概念 Windows在显示时以\"逻辑英寸\"为单位,逻辑英寸比实际英寸要大如果Windows使用实际英寸,则普通10磅文本在显示器上就会小到几乎难以辨认因此Windows使用放大了\"逻辑英寸\"来表示文本逻辑英寸只影响显示而不影响打印 使用GetDeviceCaps可得到当前设备各种能力其第个参数nIndex指示要获取信息类型当nIndex为HORZSIZE和VERTSIZE时可得到显示区域宽度和高度;当nIndex为HORZRES和VERTRES时可得到每个水平和垂直方向像素数即分辨率;当nIndex值为LOGPIXELSX和LOGPIXELSY时可得到水平和垂直方向每逻辑英寸所含像素数 在介绍了逻辑英寸知识以后很容易将OLEServer设置为基于逻辑英寸映射模式如果员仅仅SetMapMode(hdc,MM_LOENGLISH)来设置映射模式当前映射模式为物理英寸而不是逻辑英寸设置逻辑英寸必须自定义窗口和视口范围使xViewExt/xWinExt=0.01逻辑英寸中水平像素点数当xViewExt=LOGPIXELSX,xWinExt=100时其比值正好满足上述要求 以下是设置映射模式代码 xLogPixPerInch=GetDeviceCaps(hdc,LOGPIXELSX); yLogPixPerInch=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_TWIPSSetWindowExt中参数为应1440 2.逻辑坐标和设备坐标转换时误差处理 表2 映 射 模 式 每 英 寸 所 对 应 逻 辑 单 位 数 MM_LOENGLISH 100 MM_HIENGLISH 1000 MM_LOMETRIC 254 MM_HIMETRIC 2540 MM_TWIPS 1440 当我们将映射模式设置成基于逻辑英寸MM_LOMETRIC时窗口范围设为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倍数转换后就没有精度丢失了 综上所述如果我们能够根据映射模式值特点逻辑坐标和设备坐标都取经简化窗口和视口范围值倍数则逻辑坐标和设备坐标间转化将没有误差 0
相关文章读者评论发表评论 |
|