http://xqscorpion.bokee.com/5172295.html
最近突然又很有激情的開始看Jeff Prosise的那本"Programming Windows with MFC, 2 ed."。盡管是英文版的,但是感覺這本書上手比喉結(jié)的那本所謂的 深入淺出MFC 要容易理解的多。候同學(xué)給人一種故弄玄虛故作深沉的感覺,而Jeff Prosise的這本書才真正的稱得上是深入淺出。
盡管如此,其中有關(guān)GDI繪圖中的坐標(biāo)映射部分還是有一個問題沒有搞清楚,那就是http://xqscorpion.bokee.com/5172295.html。潘愛民翻譯的那本VC內(nèi)幕沒有講清楚;Jeff Prosise的這本書沒有講清楚;MSDN上的東西看的也是一頭霧水;Charles Petzold的那本書還沒有來得及看。因為這個問題,昨天晚上是帶著遺憾的困惑入睡的。
總的來說,我對這兩個函數(shù)的理解導(dǎo)致的結(jié)果是與實際程序運行的結(jié)果截然相反。依據(jù)MSDN上的解釋,有一個很嚴(yán)重的問題沒有闡述清楚,那就是:所謂的SetWindowOrg(x, y)函數(shù),到底是表示set window origin to (x, y)還是set window origin as (x, y);to和as在執(zhí)行的時候,其操作的效果是截然相反的。
set window origin to (x, y)表示將坐標(biāo)原點設(shè)置到(x, y);即以(x, y)作為坐標(biāo)原點,此時原點坐標(biāo)不再為(0, 0);
set window origin as (x, y)表示將原來的原點(0, 0)的坐標(biāo)改為(x, y);即將所有點的坐標(biāo)增加(+x, +y);
現(xiàn)在我的理解是:應(yīng)該是 set window origin to (x, y)。這種理解基于以下幾個前提:
1. 所有繪圖語句中給出的坐標(biāo),全部是邏輯坐標(biāo),即在 window 中的坐標(biāo)(相對于viewport所表示的設(shè)備坐標(biāo)而言);
2. 所有用戶能看到的點,其設(shè)備坐標(biāo)一定是位于(0, 0)和(1024, 768)范圍內(nèi);(假設(shè)顯示器為輸出設(shè)備,采用MM_TEXT映射方式,且屏幕分辨率為1024*768);
3. 所謂“(0,0)就原點,原點的坐標(biāo)一定就是(0,0)”這種理解,是錯誤的;
4. Viewport中的坐標(biāo)表示設(shè)備坐標(biāo);Window中的坐標(biāo)表示邏輯坐標(biāo);
5. 當(dāng)在邏輯坐標(biāo)中指定新的原點后,在執(zhí)行映射時,設(shè)備坐標(biāo)的原點一定要與邏輯坐標(biāo)的新原點重合;反過來也是一樣,即兩個坐標(biāo)系的原點一定要重合。
下面舉例說明:(MM_TEXT映射模式)
(1)
CRect rect(0, 0, 200, 200);
dc.rectangle(rect);
上面的語句在屏幕的最左上角繪制一個正方形;(因為此時邏輯坐標(biāo)與設(shè)備坐標(biāo)沒有偏移)
(2)
dc.SetViewportOrg(100, 100);
CRect rect(0, 0, 200, 200);
dc.rectangle(rect);
將設(shè)備坐標(biāo)的原點設(shè)置到(100, 100);即設(shè)備坐標(biāo)的原點不在(0, 0)處,而是在(100, 100)處;此時若執(zhí)行映射的話,邏輯坐標(biāo)的原點(0, 0)需要與設(shè)備坐標(biāo)的原點(100, 100)重合(參考前提5);那么此時繪制的矩形(0, 0, 200, 200)的坐標(biāo)(為邏輯坐標(biāo),參考前提1)在設(shè)備坐標(biāo)中就會映射為(100, 100, 300, 300),最終我們在顯示器上看到的會是一個向右下方偏移(100, 100)的一個邊長為200的正方形(用戶看到的點是在設(shè)備坐標(biāo)中的,參考前提2)
(3)
dc.SetWindowOrg(100, 100);
CRect rect(0, 0, 200, 200);
dc.rectangle(rect);
將邏輯坐標(biāo)的原點設(shè)置到(100, 100);即邏輯坐標(biāo)的原點不在(0, 0)處,而是在(100, 100)處;此時若執(zhí)行映射的話,設(shè)備坐標(biāo)的原點(0, 0)需要與邏輯坐標(biāo)的原點(100, 100)重合(參考前提5);那么此時繪制的矩形(0, 0, 200, 200)的坐標(biāo)(為邏輯坐標(biāo),參考前提1)在設(shè)備坐標(biāo)中就會映射為(-100, -100, 100, 100),最終我們在顯示器上看到的會是一個只有1/4個大小的矩形的一部分(事實上相當(dāng)于向左上方偏移(100, 100)的一個邊長為200的正方形。注意:用戶看到的點是在設(shè)備坐標(biāo)中的,參考前提2)