基於對話方塊的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(
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_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
第五句 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個畫素!