逻辑坐标、设备坐标的比较和关系
本文转载自了凡春秋的博客,http://blog.sina.com.cn/s/blog_6163bdeb0102dx87.html,仅作学术交流。
在Windows中,文档坐标系称作逻辑坐标系,视图坐标系称为设备坐标系。它们之间的关系如下图所示:
逻辑坐标按照坐标设置方式(又成为映射模式)可分为8种,它们在坐标上的特性如下表所示:
映射模式
逻辑单位
x递增方向
y递增方向
MM_TEXT
像素
向右
向下
MM_LOMETRIC
0.1mm
向右
向上
MM_HIMETRIC
0.01mm
向右
向上
MM_LOENGLISH
0.01inch
向右
向上
MM_HIENGLISH
0.001inch
向右
向上
MM_TWIPS
1/1440inch
向右
向上
MM_ISOTROPIC
可调整 (x=y)
可选择
可选择
MM_ANISOTROPIC
可调整(x!=y)
可选择
可选择
我们一般使用的映射模式是MM_TEXT,它也是缺省设置。在该模式下,坐标原点在工作区左上角,而x坐标值是向右递增,y坐标值是向下递增,单位值1代表一个像素。要设置映射模式,可以调用CDC::SetMapMode()函数。
CClientDC dc;
nPreMapMode=dc.SetMapMode(nMapMode);
它将映射模式设置为nMapMode,并返回前一次的映射模式nPreMapMode,GetMapMode可取得当前的映射模式:
CClientDC dc;
nMapMode=dc.GetMapMode();
MFC绘图函数都使用逻辑坐标作为位置参数。比如
CString str(“Hello,world!”);
dc.TextOut(10,10,str,str.GetLength());
这里的(10,10)是逻辑坐标而不是像素点数(只是在缺省映射模式MM_TEXT下,正好与像素点相对应),在输出时GDI函数会将逻辑坐标(10,10)依据当前映射模式转化为“设备坐标”,然后将文字输出在屏幕上。
设备坐标以像素点为单位,且x轴坐标值向右递增,y轴坐标值向下递增,但原点(0,0)位置却不限定在工作区的左上角。依据设备坐标的原点和用途,可以将Windows下使用的设备坐标系统分为三种:工作区坐标系统,窗口坐标系统和屏幕坐标系统。
(1)工作区坐标系统:
工作区坐标系统是最常见的坐标系统,它以窗口客户区左上角为原点(0,0),主要用于窗口客户区绘图输出以及处理窗口的一些消息。鼠标消息WM_LBUTTONDOWN、WM_MOUSEMOVE传给框架的消息参数以及CDC一些用于绘图的成员都是使用工作区坐标。
(2)屏幕坐标系统:
屏幕坐标系统是另一类常用的坐标系统,以屏幕左上角为原点(0,0)。以CreateDC(“DISPLAY” , ...)或GetDC(NULL)取得设备上下文时,该上下文使用的坐标系就是屏幕坐标系。
一些与窗口的工作区不相关的函数都是以屏幕坐标为单位,例如设置和取得光标位置的函数SetCursorPos()和GetCursorPos();由于光标可以在任何一个窗口之间移动,它不属于任何一个单一的窗口,因此使用屏幕坐标。弹出式菜单使用的也是屏幕坐标。另外,CreateWindow、MoveWindow、SetWindowPlacement()等函数用于设置窗口相对于屏幕的位置,使用的也是屏幕坐标系统。
(3)窗口坐标系统:
窗口坐标系统以窗口左上角为坐标原点,它包含了窗口控制菜单、标题栏等内容。一般情况下很少在窗口标题栏上绘图,因此这种坐标系统很少使用。
三类设备坐标系统关系如下图所示:
MFC提供ClientToScreen()、ScreenToClient()两个函数用于完成工作区坐标和屏幕坐标之间的转换工作。
void ScreenToClient( LPPOINT lpPoint ) const;
void ScreenToClient( LPRECT lpRect ) const;
void ClientToScreen( LPPOINT lpPoint ) const;
void ClientToScreen( LPRECT lpRect ) const;
其实,我们在前面介绍弹出式菜单时已经使用了ClientToScreen函数。在那里,由于弹出式菜单使用的是屏幕坐标,因此当处理弹出式菜单快捷键shift+F10时,如果要在窗口左上角(5,5)处显示快捷菜单,就必须先调用ClientToScreen函数将客户区坐标(5,5)转化为屏幕坐标。
CRect rect;
GetClientRect(rect);
ClientToScreen(rect);
point = rect.TopLeft();
point.Offset(5, 5);
在视图滚动后,如果用户在视图中单击鼠标,那么会得到鼠标位置的设备(视图)坐标。在使用这个数据处理文档(比如画点或画线)时,需要把它转化为文档坐标。这是因为利用MFC绘图时,所有传递给MFC作图的坐标都是逻辑坐标。当调用MFC绘图函数绘图时,Windows自动将逻辑坐标转换成设备坐标,然后再绘图。设备上下文类CDC提供了两个成员函数LPToDP和DPToLP完成逻辑坐标和设备坐标之间的转换工作。如其名字所示那样,LPToDP将逻辑坐标转换为设备坐标,DPToLP将设备坐标转换为逻辑坐标。
void LPtoDP( LPPOINT lpPoints, int nCount = 1 ) const;
void LPtoDP( LPRECT lpRect ) const;
void LPtoDP( LPSIZE lpSize ) const;
void DPtoLP( LPPOINT lpPoints, int nCount = 1 ) const;
void DPtoLP( LPRECT lpRect ) const;
void DPtoLP( LPSIZE lpSize ) const;
逻辑坐标、设备坐标的比较和关系
最新推荐文章于 2017-03-08 17:18:26 发布