一,先介绍两者使用方式
方式一

 CWnd* pWnd;pWnd = GetDlgItem(IDC_STATIC_PIC);pWnd->GetWindowRect(&m_PicWindowRect);   //m_PicWindowRect为存储区域大小的CRect

简写为

GetDlgItem(IDC_STATIC_PIC)->GetClientRect(&m_PicClienRect);

方式二 对于GetClientRect

 ::GetClientRect(GetDlgItem(IDC_STATIC_PIC)->GetSafeHwnd(), &m_PicRect);

二,区别
GetWindowRect 为获得控件相对与对话框或者(设备屏幕)的坐标大小。

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

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

1 窗口还没有初始化完成时:原点是整个窗口的左上角 (即将获得坐标的大小写在窗口初始化函数中)

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

GetClientRect为获得控件相自身的坐标大小,top和left都为0;

三,对于static text控件来说
如果不设置border (即无边框),那么通过GetWindowRect和GetClientRect的获得控件区域的长宽大小是一致的,

如果border为true(即有边框),那么两者得到的控件长宽是不一样的,GetClientRect得到的长和宽都要小四像素

四,转载文章
一:关于坐标

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的值一样。不多说了

为什么对话框和控件的转换之间略有差别(两次转换结果不太一样),主要是对话框包含了非客户区,使得相对坐标不一致。
————————————————
版权声明:本文为CSDN博主「御风九天」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011432426/article/details/42874513

GetWindowRect和GetClientRect的区别详解相关推荐

  1. HashTable和HashMap的区别详解

    HashTable和HashMap的区别详解 一.HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同 ...

  2. java mod %区别_Java中 % 与Math.floorMod() 区别详解

    %为取余(rem),Math.floorMod()为取模(mod) 取余取模有什么区别呢? 对于整型数a,b来说,取模运算或者取余运算的方法都是: 1.求 整数商: c = a/b; 2.计算模或者余 ...

  3. 关于numpy中eye和identity的区别详解

    https://www.jb51.net/article/175386.htm np.identity(n, dtype=None) np.eye(N, M=None, k=0, dtype=< ...

  4. php为什么需要配置路由器,laravel 配置路由 api和web定义的路由的区别详解

    1.路由经过中间件方面不同 打开kerenl.php就可以看到区别 protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware ...

  5. python协程详解_对Python协程之异步同步的区别详解

    一下代码通过协程.多线程.多进程的方式,运行代码展示异步与同步的区别. import gevent import threading import multiprocessing # 这里展示同步和异 ...

  6. Jar/War/Ear等包的作用与区别详解

    Jar/War/Ear等包的作用与区别详解 以客户角度来看,jar文件就是一种封装格式,用户不需要知道jar包中有多少个.class格式的文件及每个文件中的功能与作用,也可以得到相应的访问的结果.ja ...

  7. Java中print、printf、println的区别 详解

    Java中print.printf.println的区别详解 printf主要是继承了C语言的printf的一些特性,可以进行格式化输出 print就是一般的标准输出,但是不换行 println和pr ...

  8. axios请求接口http_使用axios请求接口,几种content-type的区别详解

    axios的使用 安装(一般使用框架的话, 脚手架都集成了) $ npm install axios 请求示例 // POST axios.post('/user', { firstName: 'Fr ...

  9. vue 事件调用 传参_对vue下点击事件传参和不传参的区别详解

    如下所示: {{btn_text1}} {{btn_text2}} var _vm = new Vue({ data : { btn_text1 : '点击1' , btn_text2 : '点击2' ...

最新文章

  1. linux定时脚本任务
  2. ajax实现php验证码验证码,PHP验证码之Ajax验证实现方法_PHP教程
  3. “互联网+”下的制造业供应链新挑战
  4. 关于指针,可能是网上最详细的讲解了
  5. leetcode 1178. 猜字谜(位运算)
  6. xss-lab靶场通关writeup(1~6.......在更新)
  7. postgresql报错 :FATAL: no pg_hba.conf entry for host 192.168.163.130,user postgres,database pos
  8. Field _II 仿真 学习笔记
  9. 计算机程序员求职信英语作文,程序员英文求职信范文
  10. 丹佛机场自动行包系统案例
  11. antd去掉table自带的分页条
  12. Cura Engine 源码解析:Settings
  13. 【PostgreSQL】客户端请求处理 PostgresMain()
  14. 机器学习05|一万五字:SVM支持向量机02 【jupyter代码详解篇】
  15. YOLOv5的Tricks | 【Trick13】YOLOv5的detect.py脚本的解析与简化
  16. 持居住证能落户?子女还能在沪高考
  17. WebRTC会成主流吗?P2P流媒体时代到了!
  18. js实现图片粘贴功能
  19. 2019.11.11
  20. SQL_存储过程——获得一棵树的所有叶子节点

热门文章

  1. Btrace入门到熟练小工完全指南
  2. dns在企业网络中的应用
  3. mac 香港购买分享
  4. 轻量级HTTP服务器Nginx(配置与调试Nginx)(转)
  5. expect无密码登陆
  6. c/c++ 修改文件的创建时间,修改时间,访问时间 [和弦]
  7. 深入浅出详细介绍Java异常,让你茅塞顿开般的感觉
  8. Windows上安装Kafka需要注意的几点
  9. 洛谷P1832 A+B Problem(再升级)
  10. 身份证第18位(校验码)的计算方法