理解SetWindowOrg,SetViewportOrg,SetWindowExt,SetViewportExt
按習(xí)慣,(0,0)就原點(diǎn),原點(diǎn)就是(0,0),但是如果用此來理解windows的map mode,就會(huì)走彎路。其實(shí),稍微改變一下觀念,windows的map mode就比較好理解了。舉例說明:page space---->device spacepDC->SetMapMode(MM_LOMETRIC);pDC->SetWindowOrg(40,0); //這句“設(shè)定”page space的原點(diǎn)為(40,0),注意,//這時(shí)(40,0)就是原點(diǎn),原點(diǎn)就是(40,0)這個(gè)點(diǎn),其實(shí),(0,0)與原點(diǎn)沒有必然聯(lián)系。這//一句對(duì)下面的畫圖函數(shù)在page space中所作的圖不會(huì)有任何影響。一句話:SetWindowOrg //就是指定一下,page space中哪個(gè)點(diǎn)為原點(diǎn)。pDC->Rectangle(0,0,100,-100);pDC->Rectangle(0,-100,50,-200);同理,SetViewportOrg也是指定一下,device space中哪個(gè)點(diǎn)為原點(diǎn),兩個(gè)坐標(biāo)系映射時(shí),兩個(gè)原點(diǎn)重合。SetWindowExt設(shè)定page space的大小,SetViewportOrg設(shè)定device space的大小,其實(shí),真正有意義的只是兩者的比例關(guān)系,例如,在一個(gè)1024*768的顯示屏上:pDC->SetMapMode(MM_ISOTROPIC);pDC->SetWindowExt(10240,7680);pDC->SetViewportExt(1024,768);pDC->Rectangle(0,0,100,100); 就會(huì)畫一個(gè)10 pixels*10 pixels的矩形。其本質(zhì)就是,X方向,每個(gè)邏輯單位有1024/10240個(gè)象素,Y方向每個(gè)邏輯單位有768/7680個(gè)象素。因此,下面的代碼有相同的作用:pDC->SetMapMode(MM_ISOTROPIC);pDC->SetWindowExt(102400,76800);pDC->SetViewportExt(10240,7680);pDC->Rectangle(0,0,100,100);兩者本質(zhì)一樣,前者更易于理解?
?
?
最近突然又很有激情的開始看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è)邊長為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è)邊長為200的正方形。注意:用戶看到的點(diǎn)是在設(shè)備坐標(biāo)中的,參考前提2)
---------------------?
作者:benny5609?
來源:CSDN?
原文:https://blog.csdn.net/benny5609/article/details/1845645?
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!
總結(jié)
以上是生活随笔為你收集整理的理解SetWindowOrg,SetViewportOrg,SetWindowExt,SetViewportExt的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STM32的独立看门狗(IWDG)看门狗
- 下一篇: _tcscpy_s函数引发的问题