一:关于坐标

  MFC中绘图时经常涉及到坐标计算,GetWindowRect和GetClientRect这两个函数,是获取逻辑坐标系中窗口或控件(其实也是窗口)大小和坐标的常用函数了,有什么不一样的?

先说说什么叫逻辑坐标?讲到逻辑坐标,它相对的一个概念是设备坐标,是为了屏蔽掉不同设备属性差别而设置的抽象坐标系,说白了,就是独立于设备坐标的统一接口,程序员不需要去在具体的设备上进行绘图操作,而只需要在虚拟的环境下进行绘图,就是CDC。

然后由设备驱动去负责虚拟坐标到实际设备坐标之间的转换。通常逻辑坐标与设备坐标之间有不同的映射转换关系,缺省模式下的映射方式是MM_TEXT,这种方式下的逻辑坐标的方向和单位与设备坐标的相同,也是以像素为单位来表示,X轴向右为正,Y轴向下为正,坐标原点位于窗口的左上角

然后再说上面的两个函数之间的差别:

GetWindowRect得到的是相对于当前界面的整个窗口左上角的坐标,比如一个对话框程序,那就是相对于对话框左上角的坐标,从左往右是X方向,从上往下是Y方向。

注意:这个函数的相对坐标原点分两种情况:

1 窗口还没有初始化完成时:原点是整个窗口的左上角

2 初始化完成后,原点是设备屏幕左上角

GetClientRect得到的是相对于窗口客户区左上角的坐标。

二:验证

下面通过一段代码来理解:

新建一个MFC对话框程序,在Dialog资源中,把一个静态框加入进来。OnInitDialog中添加如下代码:

BOOL CmfcdialogtestDlg::OnInitDialog()
{
/*.............其它代码.............*/ /*****************for testing***************/
CRect wndRect1;
CRect wndRect2; /****首先看对话框的******/
this->GetWindowRect(&wndRect1); //PrintRect("Dialog:GetWindowRect", wndRectScreen1);
this->ScreenToClient(&wndRect1); //PrintRect("Dialog:ScreenToClient", wndRectClient1); this->GetClientRect(&wndRect2); //PrintRect("Dialog:GetClientRect", wndRectClient2);
this->ClientToScreen(&wndRect2); //PrintRect("Dialog:ClientToScreen", wndRectScreen2); /****再看控件的**********/
CRect ctrlRect1;
CRect ctrlRect2;
CStatic *pCtrl = (CStatic*)GetDlgItem(IDC_STC_TEST);
pCtrl->GetClientRect(&ctrlRect1); //PrintRect("static:GetClientRect", ctrlRectClient1);
pCtrl->ClientToScreen(&ctrlRect1); //PrintRect("static:ClientToScreen", ctrlRectScreen1); pCtrl->GetWindowRect(&ctrlRect2); //PrintRect("static:GetWindowRect", ctrlRectScreen2);
pCtrl->ScreenToClient(&ctrlRect2); //PrintRect("static:ScreenToClient", ctrlRectClient2); /*****************ending********************/
/*.............其它代码.............*/ }

三:分析

我们分别观察对整个对话框和静态控件,分别调用这两个函数的效果。首先看看对话框的:

(1)对话框部分的程序运行结果:

对话框:
GetWindowRect: + &wndRect1 0x0017f410 {top=0 bottom=378 left=0 right=566} CRect *
ScreenToClient:+ &wndRect1 0x0017f410 {top=-25 bottom=353 left=-3 right=563} CRect * GetClientRect: + &wndRect2 0x0017f3f8 {top=0 bottom=350 left=0 right=560} CRect *
ClientToScreen:+ &wndRect2 0x0017f3f8 {top=25 bottom=375 left=3 right=563} CRect *

我们给出一份图片分析:

第一个GetWindowRect得到的是整个窗口相对于窗口左上角的坐标,实际上就是这个对话框的大小。

然后ScreenToClient,注意了,我们发现top和left都变成了负值?为什么呢,因为这个时候的转换是基于Client的原点进行的,即客户区的左上角。因为原来的窗口左上角位于Client原点的左上方,所以是负值。

第二个GetClientRect得到的是客户区的大小,因为不包含窗口周边的蓝色区域,所以比第一个的窗口大小要小。

然后ClientToScreen,这个就很好解释了,计算相对于窗口左上角的坐标。你可以自己动手算一下。

(2)控件的程序运行结果:

控件:
GetClientRect: + &ctrlRect1 0x0017f3e0 {top=0 bottom=170 left=0 right=285} CRect *
ClientToScreen:  + &ctrlRect1 0x0017f3e0 {top=127 bottom=297 left=73 right=358} CRect * GetWindowRect: + &ctrlRect2 0x0017f3c8 {top=127 bottom=297 left=73 right=358} CRect *
ScreenToClient:  + &ctrlRect2 0x0017f3c8 {top=0 bottom=170 left=0 right=285} CRect *

还是图片分析:

同理,第一个GetClientRect得到是控件的大小。

然后ClientToScreen,可以看到这个时候,控件相对于对话框窗口左上角的位移是(127,73)。

第二个GetWindowRect,得到的值与上面的值相同,这个很好理解了,他们的含义是一样的,就是控件在窗口中的坐标。

然后ScreenToClient,得到的值与第一个GetClientRect的值一样。不多说了

为什么对话框和控件的转换之间略有差别(两次转换结果不太一样),主要是对话框包含了非客户区,使得相对坐标不一致

GetWindowRect和GetClientRect比较学习的更多相关文章

  1. GetWindowRect和GetClientRect的区别详解

    一:关于坐标 MFC中绘图时经常涉及到坐标计算,GetWindowRect和GetClientRect这两个函数,是获取逻辑坐标系中窗口或控件(其实也是窗口)大小和坐标的常用函数了,有什么不一样的? ...

  2. GetWindowRect和GetClientRect的注意事项

    发现GetClientRect()函数取值不正确,特此找来了些资料以供参考,具体如下,就可以明白怎么回事了. 一:关于坐标 MFC中绘图时经常涉及到坐标计算,GetWindowRect和GetClie ...

  3. GetWindowRect与GetClientRect 的区别

    GetWindowRect 函数功能:该函数返回指定窗口的边框矩形的尺寸.该尺寸以相对于屏幕坐标左上角的屏幕坐标给出. 函数原型:BOOL GetWindowRect(HWND hWnd,LPRECT ...

  4. GetWindowRect和GetClientRect的异同

    由于项目需要,需要学习CGridCtrl控件的使用,测试控件时发现了一个问题,我无法将控件放在对话框的制定位置. 该问题的原因很容易发现,其实就是GetWindowRec()函数和GetClientR ...

  5. GetWindowRect、GetClientRect、ScreenToClient与ClientToScreen

    GetWindowRect是取得窗口在屏幕坐标系下的RECT坐标(包括客户区和非客户区),这样可以得到窗口的大小和相对屏幕左上角(0,0)的位置. GetClientRect取得窗口客户区(不包括非客 ...

  6. VC:GetWindowRect、GetClientRect、ScreenToClient与ClientToScreen

    GetWindowRect是取得窗口在屏幕坐标系下的RECT坐标(包括客户区和非客户区),这样可以得到窗口的大小和相对屏幕左上角(0,0)的位置. GetClientRect取得窗口客户区(不包括非客 ...

  7. MFC特定函数的应用20160720(SystemParametersInfo,GetWindowRect,WriteProfileString,GetSystemMetrics)

    1.SystemParametersInfo函数可以获取和设置数量众多的windows系统参数 MFC中可以用 SystemParametersInfo(……) 函数来获取和设置系统信息,如下面例子所 ...

  8. vc++ mfc中拖动效果的实现 借助于CImageList

    拖动是界面编程频繁使用的一个效果,在windows系统下可谓大行其道.纵观时下的应用软件几乎各个都支持各种各样拖动的效果,windows7更是把拖动做到了极致.其实说起来拖动的实现也很简单,对于有句柄 ...

  9. VC++的菜单控制和自绘菜单

    菜单控制为什么即使调用EnableMenuItem菜单项后,菜单项还处于禁止状态 需要将CFrameWnd:: m_bAutomenuEnable设置为FALSE,如果该数据成员为TRUE(缺省值), ...

随机推荐

  1. stage3D基础四----Stage3D和透视投影的使用(转)

    原文地址: http://www.adobe.com/cn/devnet/flashplayer/articles/perspective-projection.html 引言 在本教程中,你将了解透 ...

  2. 机器学习14—SVD学习笔记

    test14.py #-*- coding:utf-8 import sys sys.path.append("svdRec.py") import svdRec from num ...

  3. python视频教程大全(转载)

    python3英文视频教程(全87集) http://pan.baidu.com/s/1dDnGBvV python从入门到精通视频(全60集)链接:http://pan.baidu.com/s/1e ...

  4. 从零开始搭建android框架系列(转)

    网址:从零开始搭建android框架系列 githup:https://github.com/CameloeAnthony/Ant

  5. 【转】使用Python学习selenium测试工具

    出处:https://my.oschina.net/u/1433482/blog/633231?fromerr=vaxqh9bn

  6. POJ2396 Budget 【带下界的最大流】

    Budget Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5962   Accepted: 2266   Special ...

  7. 网页上10秒倒计时,完了后就自动跳转到另一个网页上html代码

    用html代码的话就这样: <meta http-equiv="Refresh" content="10;URL=http://www.baidu.com" ...

  8. [原创]css设置禁止中文换行

    white-space: nowrap;   如有需要还可以设置word-break,word-wrap配合.

  9. Xshell连接不上行Linux系统

    之前出现了.我的Linux系统上的主机可以ping通windows的一台电脑, windows也可以ping的通Linux.但是Xshell不能连接. 第一,我感觉是不是我Linux系统的端口被防火墙 ...

  10. python爬虫之request and BeautifulSoup

    1.爬虫的本质是什么? 模仿浏览器的行为,爬取网页信息. 2.requests 1.get请求 无参数实例 import requests ret = requests.get('https://gi ...