(1)Windows坐标系统
Windows坐标系分为逻辑坐标系和设备坐标系两种,GDI支持这两种坐标系。
一般而言,GDI的文本和图形输出函数使用逻辑坐标,而在客户区移动或按下鼠标的鼠标位置是采用设备坐标。
<1>逻辑坐标系是面向DC的坐标系,这种坐标不考虑具体的设备类型,在绘图时,Windows会根据当前设置的映射模式将逻辑坐标转换为设备坐标。
<2>设备坐标系是面向物理设备的坐标系,这种坐标以像素或设备所能表示的最小长度单位为单位,X轴方向向右,Y轴方向向下,设备坐标系的原点位置(0, 0)不限定在设备显示区域的左上角。
设备坐标系分为屏幕坐标系、窗口坐标系和客户区坐标系三种相互独立的坐标系。
屏幕坐标系以屏幕左上角为原点,一些与整个屏幕有关的函数均采用屏幕坐标,如GetCursorPos()、SetCursorPos()、CreateWindow()、MoveWindow(),弹出式菜单使用的也是屏幕坐标。
窗口坐标系以窗口左上角为坐标原点,它包括窗口标题栏、菜单栏和工具栏等范围。
客户区坐标系以窗口客户区左上角为原点,主要用于客户区的绘图输出和窗口消息的处理。鼠标消息的坐标参数使用客户区坐标,CDC类绘图成员函数使用与客户区坐标对应的逻辑坐标。
下面三种都是
显示设备的物理坐标
,它们在屏幕上用真实的物理像素表示:
屏幕坐标 Screen coordinates: 原点(0,0)位于屏幕的左上角
窗口坐标 Window coordinates: 原点(0,0)位于窗口的左上角(包括非客户区,如标题条)
客户区坐标 Client-window 原点(0,0)位于客户窗口的左上角
逻辑坐标
是GDI函数在屏幕上显示数据所用的坐标,逻辑坐标除非与物理坐标相关联,否则没有义.windows依靠映射模式解释逻辑坐标.比如缺省的模式为MM_TEXT,该模式下,物理坐标与逻辑坐标是一对一的关系.
(2)坐标之间的相互转换
编程时,有时需要根据当前的具体情况进行三种设备坐标之间或与逻辑坐标的相互转换。
MFC提供了两个函数CDC::DPtoLP()和CDC:: LPtoDP()用于设备坐标与逻辑坐标之间的相互转换。
MFC提供了两个函数CWnd::ScreenToClient()和CWnd::ClientToScreen()用于屏幕坐标与客户区坐标的相互转换。
GetWindowRect是取得窗口在屏幕坐标系下的RECT坐标(包括客户区和非客户区),这样可以得到窗口的大小和相对屏幕左上角(0,0)的位置。
GetClientRect取得窗口客户区(不包括非客户区)在客户区坐标系下的RECT坐标,可以得到窗口的大小,而不能得到相对屏幕的位置,因为这个矩阵是在客户区坐标系下(相对于窗口客户区的左上角)的
。
Windows绘图是在逻辑平面上进行的,是以逻辑坐标作为参数,这个逻辑平面很大,坐标值可以是无限的,我们的窗口只能显示一小部分,而我们为了看到逻辑平面的其它部分,我们可以移动设备平面或者移动逻辑平面,设备点(0,0)始终是客户区的左上角,默认情况,逻辑坐标系和客户区坐标系都是Y轴向下递增,X轴向右递增,两者的原点是重合的。
红色方框内,就是我们在设备能看到的内容,默认情况下,逻辑坐标系里-x,-y 的内容在设备上是看不到1 CRect rect(-100,-100,100,100);
2 dc.Rectangle(rect) ;
3 dc.Ellipse(rect) ;
我们可以通过移动原点来显示出(-x,-y)的内容
SetWindowOrg: 移动逻辑坐标的原点,即通知操作系统,把逻辑点(x,y)映射成设备点(0,0)
SetViewportOrg: 移动设备坐标的原点,即通知操作系统把 设备点(x,y)映射成逻辑点(0,0) 1 CPaintDC dc(this);
2
3 CRect rect;
4 GetClientRect(&rect);//返回以设备单位表示的窗口尺寸(即像素)
5 CPoint point(rect.Width()/2,rect.Height()/2);
6
7 dc.SetViewportOrg(point);
8
9 CRect rect2(-100,-100,100,100);
10 dc.Rectangle(rect2) ;
11 dc.Ellipse(rect2) ;
1 CPaintDC dc(this);
2 CPoint point(-100,-100);
3
4 dc.SetWindowOrg(point);
5
6 CRect rect2(-100,-100,100,100);
7 dc.Rectangle(rect2) ;
8 dc.Ellipse(rect2) ;