基于对话框的MFC应用程序GetWindowRect(),GetClientRect()探究

来源:互联网 发布:会计帮软件下载 编辑:程序博客网 时间:2024/05/18 00:04

先建一个基于对话框的MFC应用程序,在对话框上放置一个静态文本控件m_plot

用m_rectOldWindow变量保存对话框RECT,用m_rectOldPlotWindow保存静态文本控件RECT

在OnInitDialog()添加如下测试代码

复制代码
GetWindowRect(&m_rectOldWindow);
ScreenToClient(
&m_rectOldWindow);
GetClientRect(
&m_rectOldWindow);
ClientToScreen(
&m_rectOldWindow);

m_plot.GetClientRect(
&m_rectOldPlotWindow);
ClientToScreen(
&m_rectOldPlotWindow);
m_plot.GetWindowRect(&m_rectOldPlotWindow);
ScreenToClient(
&m_rectOldPlotWindow);
复制代码

调试运行 查看变量的值

第一句GetWindowRect(&m_rectOldWindow);

+ &m_rectOldWindow 0x002cfcd4 {top=0 bottom=388 left=0 right=576}CRect *

第二句ScreenToClient(&m_rectOldWindow);

+ &m_rectOldWindow 0x002cfcd4 {top=-30 bottom=358 left=-8 right=568}CRect *

第三句GetClientRect(&m_rectOldWindow);

+ &m_rectOldWindow 0x002cfcd4 {top=0 bottom=350 left=0 right=560}CRect *

第四句ClientToScreen(&m_rectOldWindow);

+ &m_rectOldWindow 0x002cfcd4 {top=30 bottom=380 left=8 right=568}CRect *

第五句 m_plot.GetClientRect(&m_rectOldPlotWindow);

+ &m_rectOldPlotWindow 0x002cfcc4 {top=0 bottom=255 left=0 right=532}CRect *

第六句:ClientToScreen(&m_rectOldPlotWindow);

+ &m_rectOldPlotWindow 0x002cfcc4 {top=30 bottom=285 left=8 right=540}CRect *

第七句:m_plot.GetWindowRect(&m_rectOldPlotWindow);

+ &m_rectOldPlotWindow 0x0023f7dc {top=42 bottom=301 left=20 right=556}CRect *

第八句:ScreenToClient(&m_rectOldPlotWindow);

+ &m_rectOldPlotWindow 0x0023f7dc {top=12 bottom=271 left=12 right=548}CRect *

本来上网查资料的,乱的一团糟,很多都是自己没测试就给别人回答~

实践是检验真理的唯一标准~  恩~  

简要分析:

本来我以为第一句的GetWindowRect得到的应该是这个对话框窗口相对于屏幕坐标的RECT,结果从下面的数值可以看出

这四个函数都没有涉及到窗口坐标和屏幕坐标的转换

GetWindowRect得到的是整个对话框客户区和非客户区的RECT,非客户区就是在xp里面标题部分绿绿的和边框部分,在win7下面半透明的部分

坐标原点在整个窗口的左上角

ScreenToClient为什么会得到负值?因为Client是客户区,坐标原点在客户区的左上角,窗口的左上角当然比客户区的左上角更加的左上,所以出现负数

GetClientRect 得到窗口客户区的RECT,坐标原点在客户区的左上角,比较第一行和第三行的数据 相减,388-350 = 30 +8;576 - 560 = 2*8;

ClientToScreen 坐标原点变成整个窗口的左上角 ,较客户区原点平移了(30,8),这个坐标转换,大家高中都学过的^_^

m_plot.GetClientRect 以静态控件的左上角为原点,得到静态控件的RECT,right即为宽,bottom即为高

ClientToScreen 这句话我纳闷了,难道微软的算法就是平移一个(30,8)? 我的控件左上角并不在客户区的左上角

m_plot.GetWindowRect 以整个窗口的左上角为原点,得到控件的RECT

ScreenToClient 以客户区左上角为原点,得到控件的RECT,我的控件左上角离客户区左上角有(12,12)的平移

还没结束::

重写控件onpaint

添加

GetWindowRect(&rect);
ScreenToClient(
&rect);
GetClientRect(
&rect);
ClientToScreen(
&rect);

GetWindowRect(&rect);

+ &rect 0x0029f348 {top=233 bottom=492 left=372 right=908}CRect *

 ScreenToClient(&rect);

+ &rect 0x0029f348 {top=-2 bottom=257 left=-2 right=534}CRect *

 GetClientRect(&rect);

+ &rect 0x0029f348 {top=0 bottom=255 left=0 right=532}CRect *

 ClientToScreen(&rect);

+ &rect 0x0029f348 {top=235 bottom=490 left=374 right=906}CRect *

神奇的事情发生了!

还记得我前面的一句话不 这四个函数都没有涉及到窗口坐标和屏幕坐标的转换

实践推翻了我的理论

为什么呢?为什么呢?为什么呢?

在对话框中调用GetWindowRec,m_plot.GetWindowRect

在控件中调用GetWindowRec差别为何如此大?

控件中的GetWindowRec以屏幕左上角为原点!谁能告诉我为什么

第二句ScreenToClient(&rect);更加离谱~! -2是相对于什么坐标原点的平移?

第三句GetClientRect(&rect);总算正常,是期望的结果,得到以控件本身的左上角为原点的RECT

第四句ClientToScreen(&rect);以屏幕左上角为原点重写计算RECT,但为何和第一句得到的相差了2个像素的偏差?而这2个像素正是

第二句中莫名冒出来的2个像素!


原创粉丝点击