同标题!!!
多多指教。
下面的文章是以前有位网友的,名字给忘了.
Windows编程中的映射模式和坐标转换
一、Windows中的映射模式
1、Windows定义映射模式的目的
经过我的综合,Windows定义映射模的目的又以下几个方面:1、不同人的使用习惯。不同国家的,不同地区,以及不同的人因为习惯喜欢用不同的度量单位,有的人人喜欢用英寸,而有的人喜欢用公制中的厘米,毫米等。其他的人又喜欢用另外一些单位。、2、使软件与硬件向分离开来。让开发的软件能够最大限度的与硬件无关。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英寸。
4、可变比例映射模式
对于可变比例的映射模式用户可以自己定义一个逻辑单位代表的大小,其大小可以任意。也可以让这个大小随环境改变而改变。有MM_ISOTROPIC,MM_ANISOTROPIC这两种映射模式。其逻辑单位的大小等于视口范围和窗口范围的比值。两者的不同在于前者要求X轴和Y轴的度量单位必须相同,而后者没有这样的限制。
二、Windows中的几种坐标体系
1、屏幕坐标
屏幕坐标描述物理设备的一种坐标体系,坐标原点在屏幕的左上角,X轴向右为正,Y轴向下为正。度量单位是象素。原点、坐标轴方向、度量单位都是不能够改变的。
2、设备坐标
设备坐标是描述在屏幕和打印机显示或打印的窗体的一种坐标体系。默认的坐标原点是在其客户区的左上角。X轴向右为正,Y轴向下为正。度量单位为象素。原点和坐标轴方向可以改变,但是度量单位不可以改变。
3、逻辑坐标
逻辑坐标是在程序中控制显示,打印使用的坐标体系。该坐标系与定义的映射模式密切相关。默认的映射模式是MM_TEXT。我们可以通过设置不同的映射模式来改变该坐标体系的默认行为。
三、逻辑坐标和设备坐标之间的转换
现有如下代码:
void CMapModeView::OnPaint()
{
CPaintDC dc(this);
//获取设备类的设置
CPoint 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);//设置视口的坐标原点
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)从逻辑坐标体系映射到设备坐标体系。
CPoint ptMap;
ptMap=CPoint(300,400);
dc.LPtoDP(&ptMap);
strMsg.Format(_T("The Orginal Point(In LP):CPoint(300,400),Convert to DP is:CPoint(%d,%d)"),
ptMap.x,ptMap.y);
TRACE("%s\n",strMsg);
//将点(300,400)从设备坐标体系映射到逻辑坐标体系
ptMap=CPoint(300,400);
dc.DPtoLP(&ptMap);
strMsg.Format(_T("The Orginal Point(In DP):CPoint(300,400),Convert to LP is:CPoint(%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 Point(In LP):CPoint(300,400),Convert to DP is:CPoint(400,500)
The Orginal Point(In DP):CPoint(300,400),Convert to LP is:CPoint(200,300)
按照MSDN上,函数SetWindowOrg(x,y)设定设备坐标下的点对应于逻辑坐标的原点。SetVieportOrg(x,y)设定逻辑坐标下点对应逻辑坐标的原点。而实际上如果同时设置了逻辑坐标和设备坐标原点的话,那么以上的说法是错误的。
在默认映射模式MM_TEXT下,一个逻辑单位对应于设备坐标下的一个象素。改变默认原点以后的坐标体系如下图所示: