现在的位置: 首页 > 综合 > 正文

ScreenToClient和ClientToScreen

2018年01月31日 ⁄ 综合 ⁄ 共 2196字 ⁄ 字号 评论关闭

  我们知道,显示器只是一个显示根据,它以像素为单位,一个像素就是一个点。显示器的分辨率就代表了它的像素个数,比如我的电脑分辨率是:1024*768。如下图:

图1
就是说我的显示器有768行,1024列。其中每行1024个像素,每列768个像素。
  显示屏幕有一个屏幕的坐标系,它的左上角坐标为原点(0,0),原点向下为正,向右为正,它的右下角坐标为为(1024,768),如下图:
  
图2
  
  我们知道,坐标系是相对的,对于显示屏幕来说,以显示器的左上角为原点(0,0);而对于应用程序来说,它(应用程序)的的左上角为原点(0,0)。
  从抽象的角度看,应用程序不过是一个矩形(长方形) (当然是对大多数应用程序而言,有些程序不是矩形),MFC有一个类CRect 就是描述一个矩形的。
  它有6个构造函数,其中一个就是:
  CRect  rc(295,168,765,521);四个参数分表代表矩形的左边、上边、右边和底边。如下图:
  
图3

  对于应用程序来说,它还有一个客户坐标系,它是以应用程序的客户区的左上角为坐标原点的,什么是客户区呢?如上图的应用程序:它的白色的部分就是客户区,非客户区就是应用程序外围的一些空间,包括标题栏,系统菜单区,最小化,最大化,关闭按钮等部分,以及一点点的边框。
  
图4
  
  获取一个应用程序的客户区的大小的函数是:GetClientRect;
如:
CRect rc;//定义一个矩形保存客户区坐标
GetClientRect(&rc);//客户区坐标系
如上图,我们就是如此得到了客户区的矩形为(0,0,545,392),它的意思是此应用程序的客户区左上角坐标为(0,0),右下角坐标为:(545,392)。就是说客户区的长度为545像素,宽度为392像素。
  还有一个函数是获取应用程序的屏幕坐标系的坐标(以屏幕左上角为原点):
CRect rc;
GetWindowRect(&rc); 得到的坐标为(274,175,750,560);注意,它的坐标是以整个应用程序的左上角来看的(而不是客户区的左上角)。它的大小就是整个应用程序窗口的大小。 
  
图5
  
  
 

函数ClientToScreen用于将客户区坐标转化为屏幕坐标。

ClientToScreen(myRect);//转换为屏幕坐标 把对话框的大小变成客户区的大小 

MoveWindow(myRect.leftmyRect.topmyRect.Width(), myRect.Height());

当我们转化后,并movewindow到转换后的坐标系后,发现 左右底 每次减少了3个像素,说明应用程序的 左右底 的边框(非客户区)大小均为3个像素。如下图,

而 “上”每次减少了29个像素,说明标题栏上面的宽度为29个像素。


6


7

有些函数必须要使用屏幕坐标系,所以必须用函数ClientToScreen进行转换。

函数ScreenToClient相反,是把屏幕坐标系转换为客户区坐标系。

////////////////////////////////////////////////////////////////////////////////////////////////////


8

9

如上2图:应用程序的客户区宽度为470,高度为353非客户区左边,右边和下面的边框均为3,就是绿色部分。上面的边框(标题系统菜单区宽度)29.

所以整个应用程序的宽度为470+3+3 = 476,高度为353+29+3 = 385.

应用程序的客户坐标系坐标为(0,0,470,353). (宽470,高353

应用程序的屏幕坐标系坐标为(274,175,750,560). 其中274代表应用程序左上角到屏幕左边的距离,175代表应用程序左上角到屏幕顶端的距离,750代表应用程序左下角到屏幕左边的距离,560代表应用程序左下角到屏幕顶端的距离。

750 = 应用程序左上角到屏幕左边的距离274+应用程序的宽度476

560 = 应用程序左上角到屏幕顶端的距离175+应用程序的高度385

如上图8所示。

执行ClientToScreen后,就是要得到客户区矩形的屏幕坐标系。

就是在应用程序屏幕坐标系的基础上,减去非客户区的宽度而已。

见图8

= 274+边框3=277

= 175+标题栏宽度29=204

= 750-边框3 = 747

=560-边框3 = 557.

随意拖动程序的位置,发现均是+-边框的宽度而已。

CRect myRect

GetWindowRect(&myRect); //274,175,750,560

ScreenToClient(myRect); //-3 ,-29,473,356

为什么是-3 ,-29,473,356呢,应该求的是整个应用程序矩形相对于客户区的坐标,

客户区的坐标是(0,0,470,353). (宽470,高353

如图8,整个应用程序矩形的左上角相对客户区坐标就是(0-3,0-29)(减去边框的宽度),

因为向左向上为负,向下向右为正。而整个应用程序矩形的左下角相对客户区坐标就是(470+3,353+3),即加上边框宽度。见图8

无论怎样拖动窗体,客户区的坐标和.ScreenToClient后的坐标都是不变的,应该客户区的大小没有改变。而屏幕坐标是变化的。

抱歉!评论已关闭.