1. 程式人生 > >基於對話方塊的MFC應用程式GetWindowRect(),GetClientRect()探究

基於對話方塊的MFC應用程式GetWindowRect(),GetClientRect()探究

先建一個基於對話方塊的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_rectOldWindow0x002cfcd4 {top=0 bottom=388 left=0 right=576}CRect *

第二句ScreenToClient

(&m_rectOldWindow);

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

第三句GetClientRect(&m_rectOldWindow);

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

第四句ClientToScreen(&m_rectOldWindow);

+&m_rectOldWindow0x002cfcd4 {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);

+&rect0x0029f348 {top=233 bottom=492 left=372 right=908}CRect *

ScreenToClient(&rect);

+&rect0x0029f348 {top=-2 bottom=257 left=-2 right=534}CRect *

GetClientRect(&rect);

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

ClientToScreen(&rect);

+&rect0x0029f348 {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個畫素!