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