關於SetWindowOrg和SetViewportOrg函數的說明!

  關於這兩個函數的解釋,我就不詳細敘述了,我的前兩篇博客關於這兩個函數的內容已經講的比較清楚了,有需要的同學可以找一找!我只是記錄一下我自己使用的心得!

    先確定幾點:

     1.默認的時候,視口座標原點在屏幕顯示部分的左上角。

    先來熱一下身:

  1. void CmfcAppView::OnDraw(CDC* pDC)  
  2. {  
  3.     CmfcAppDoc* pDoc = GetDocument();  
  4.     ASSERT_VALID(pDoc);  
  5.     if (!pDoc)  
  6.         return;  
  7.   
  8.     CRect rect;   
  9.     GetClientRect(&rect);  
  10.     CBrush brush(RGB(255, 0, 0));   /*紅色的畫刷*/  
  11.     CPen pen(PS_SOLID, 3, RGB(0, 0, 255));  /*藍色的筆*/  
  12.     pDC->SelectObject(&brush);  
  13.     pDC->SelectObject(&pen);  
  14.   
  15.     /* 
  16.     *     通常這個SetViewportOrg函數調用多次實際上就只有最後的一次起效果!如同下面的語句。 
  17.     *     pDC->SetWindowOrg(100, 100),這句有或者沒有都不影響結果! 
  18.     *     我是這樣理解的,程序裏記錄着一張邏輯座標表.第一次時,邏輯座標系原點被移至(100, 100)這個點! 
  19.     *當然,這個點是相對於程序記錄的那個邏輯座標系爲準的。第二次時,邏輯座標系被移至原點(-100, -100) 
  20.     *這個點,這個點也是相對於程序記錄的那個邏輯座標系而言的。我們看到,第一次等於沒做。 
  21.     *     (每次調用SetWindowOrg都以這張邏輯座標爲準!) 
  22.     */  
  23.     pDC->SetWindowOrg(100, 100);  
  24.     pDC->SetWindowOrg(-100, -100);  
  25.     pDC->Rectangle(0, 0, 150, 150);  
  26. }  
     結果是:


     

       再來看一看這段: 

  1. void CmfcAppView::OnDraw(CDC* pDC)  
  2. {  
  3.     CmfcAppDoc* pDoc = GetDocument();  
  4.     ASSERT_VALID(pDoc);  
  5.     if (!pDoc)  
  6.         return;  
  7.   
  8.     CRect rect;   
  9.     GetClientRect(&rect);  
  10.   
  11.     CBrush brush(RGB(255, 0, 0));   /*紅色的畫刷*/  
  12.     CPen pen(PS_SOLID, 3, RGB(0, 0, 255));  /*藍色的筆*/  
  13.     pDC->SelectObject(&brush);  
  14.     pDC->SelectObject(&pen);  
  15.   
  16.     pDC->Rectangle(0, 0, 150, 150);  /*先畫一個矩形*/  
  17.   
  18.     pDC->SetWindowOrg(-100, -100);   /*將邏輯座標系原點移至(-100, -100),相對於原來的那個邏輯座標系而言*/  
  19.     pDC->Rectangle(0, 0, 150, 150);  /*再畫一個矩形*/  
  20.   
  21.     /* 
  22.     *   看了結果,有人很疑惑,怎麼上面那個矩形沒有隨着邏輯座標一起移動? 
  23.     *   整個程序的客戶區你可以看做是一塊畫布啦!怎麼會有已經畫好的東西,還可以移動的道理,你說算是吧? 
  24.     * 
  25.     */  
  26. }  
    結果是:


   好吧!接下來搞點有技術含量的:

  1. void CmfcAppView::OnDraw(CDC* pDC)  
  2. {  
  3.     CmfcAppDoc* pDoc = GetDocument();  
  4.     ASSERT_VALID(pDoc);  
  5.     if (!pDoc)  
  6.         return;  
  7.   
  8.     CRect rect;   
  9.     GetClientRect(&rect);  
  10.   
  11.     CBrush brush(RGB(255, 0, 0));   /*紅色的畫刷*/  
  12.     CPen pen(PS_SOLID, 3, RGB(0, 0, 255));  /*藍色的筆*/  
  13.     pDC->SelectObject(&brush);  
  14.     pDC->SelectObject(&pen);  
  15.   
  16.     pDC->SetWindowOrg(100, 100);   /*將邏輯座標系原點移至(-100, -100),相對於原來的那個邏輯座標系而言*/  
  17.     pDC->Rectangle(0, 0, 150, 150);  /*再畫一個矩形*/  
  18.   
  19. }  

     結果是:

    有人奇怪上面的結果了,爲什麼矩形只剩下大約1/4的位置了? 


     看一下這段程序:

  1. void CmfcAppView::OnDraw(CDC* pDC)  
  2. {  
  3.     CmfcAppDoc* pDoc = GetDocument();  
  4.     ASSERT_VALID(pDoc);  
  5.     if (!pDoc)  
  6.         return;  
  7.   
  8.     CRect rect;   
  9.     GetClientRect(&rect);  
  10.   
  11.     CBrush brush(RGB(255, 0, 0));   /*紅色的畫刷*/  
  12.     CPen pen(PS_SOLID, 3, RGB(0, 0, 255));  /*藍色的筆*/  
  13.     pDC->SelectObject(&brush);  
  14.     pDC->SelectObject(&pen);  
  15.   
  16.     pDC->SetViewportOrg(100, 100);   /*將視口座標系原點移至(-100, -100),相對於原來的那個視口座標系而言*/  
  17.     pDC->Rectangle(0, 0, 150, 150);  /*畫一個矩形*/  
  18.   
  19. }  
        想一想結果,然後和真實的結果比對一下:


    我的解釋如下:


     在看一下這段代碼,然後猜一下結果?

  1. void CmfcAppView::OnDraw(CDC* pDC)  
  2. {  
  3.     CmfcAppDoc* pDoc = GetDocument();  
  4.     ASSERT_VALID(pDoc);  
  5.     if (!pDoc)  
  6.         return;  
  7.   
  8.     CRect rect;   
  9.     GetClientRect(&rect);  
  10.   
  11.     CBrush brush(RGB(255, 0, 0));   /*紅色的畫刷*/  
  12.     CPen pen(PS_SOLID, 3, RGB(0, 0, 255));  /*藍色的筆*/  
  13.     pDC->SelectObject(&brush);  
  14.     pDC->SelectObject(&pen);  
  15.   
  16.     pDC->SetViewportOrg(100, 100);   /*將視口座標系原點移至(100, 100),相對於原來的那個視口座標系而言*/  
  17.     pDC->SetWindowOrg(-100, -100); /*將邏輯(窗口)座標系原點移至(100, 100),相對於原來的那個邏輯座標系而言*/  
  18.     pDC->Rectangle(0, 0, 150, 150);  /*畫一個矩形*/  
  19.   
  20. }  
     讓我們來覈對一下:


      是不是感到有些奇怪?看一下我的解釋!

 

     對於上面的第3步,有人感到很奇怪,爲什麼畫矩形的時候是以變換前的邏輯座標爲準的?而不是以變換後的邏輯座標爲準的?

     看一下結果的精確測量:



     看見沒有,測量的結果說明,我上面的原理圖是正確的!

     關於解釋,我的解釋是:SetWindowOrg函數並未實際上改變邏輯座標,只是通知程序應該怎樣映射,該把邏輯座標的這個點映射到視口座標的哪個點!應該比較清楚了吧?

     最好,這兩個函數別同時用,因爲兩個混在一起,很容易糊塗!

     既然都講了這麼多了,順帶提一下SetViewportExt和SetWindowExt兩個函數吧!這兩個函數只在映射模式爲MM_ISOTROPIC和MM_ANISOTROPIC下有效!兩個函數裏面參數的值並不重要,重要的只是他們的比值罷了!

    看這段代碼:

  1. pDC->SetMapMode(MM_ANISOTROPIC);  
  2. pDC->SetWindowExt(1024,768);  
  3. pDC->SetViewportExt(10240,7680); //表示一個窗口單位,也就是在x軸上邏輯單位對應10個視口單位,當然屏幕上表示像素,在y軸上亦然  
  4. pDC->Rectangle(0,0,100,100);  
          和下面這段代碼:

  1. pDC->SetMapMode(MM_ANISOTROPIC);  
  2. pDC->SetWindowExt(10240,7680);  
  3. pDC->SetViewportExt(102400,76800);     //表示一個窗口單位,也就是在x軸上邏輯單位對應10個視口單位,當然屏幕上表示像素,在y軸上亦然  
  4. pDC->Rectangle(0,0,100,100);  
        兩者在效果上沒有區別!

     還有,兩者的正負會影響座標軸的方向!當然,這不是這篇文章的重點!


本文轉載自:

http://blog.csdn.net/lishuhuakai/article/details/18467255

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章