jasmine214--love

          只有當(dāng)你的內(nèi)心總是充滿快樂、美好的愿望和寧靜時(shí),你才能擁有強(qiáng)壯的體魄和明朗、快樂或者寧靜的面容。
          posts - 731, comments - 60, trackbacks - 0, articles - 0

          http://study.qqcf.com/web/189/21186.htm
          映射模式

             在此篇之前我們已經(jīng)學(xué)會(huì)了在窗口顯示圖形,更準(zhǔn)確的說是在窗口指定位置顯示圖形或文字,我們使用的坐標(biāo)單位是象素,稱之為設(shè)備坐標(biāo)。看下面語句:

          pDC->Rectangle(CRect(0,0,200,200));

             畫一個(gè)高和寬均為200個(gè)象素的方塊,因?yàn)椴捎玫氖悄J(rèn)的MM_TEXT映射模式,所以在設(shè)備環(huán)境不一樣時(shí),畫的方塊大小也不一樣,在1024*768的顯示器上看到的方塊會(huì)比640*480的顯示器上的小(在不同分辨率下的屏幕象素,在WINDOWS程序設(shè)計(jì)一書中有示例程序可以獲得,或者可以用GetClientRect函數(shù)獲得客戶區(qū)的矩形大小。在這里就不說了,大家只要知道就行了),在輸出到打印機(jī)時(shí)也會(huì)有類似的情況發(fā)生。如何做才能保證在不同設(shè)備上得到大小一致的方塊或者圖形、文字呢?就需要我們進(jìn)行選擇模式映射,來轉(zhuǎn)換設(shè)備坐標(biāo)和邏輯坐標(biāo)。

          Windows提供了以下幾種映射模式:

          MM_TEXT
          MM_LOENGLISH
          MM_HIENGLISH
          MM_LOMETRIC
          MM_HIMETRIC
          MM_TWIPS
          MM_ISOTROPIC
          MM_ANISOTROPIC

          下面分別講講這幾種映射模式:

          MM_TEXT:

             默認(rèn)的映射模式,把設(shè)備坐標(biāo)被映射到象素。x值向右方向遞增;y值向下方向遞增。坐標(biāo)原點(diǎn)是屏幕左上角(0,0)。但我們可以通過調(diào)用CDC的SetViewprotOrg和SetWindowOrg函數(shù)來改變坐標(biāo)原點(diǎn)的位置看下面兩個(gè)例子:

          //************************************************
          // 例子6-1
          void CMyView::OnDraw(CDC * pDC)
          {
          pDC->Rectangle(CRect(0,0,200,200));//全部采用默認(rèn)畫一個(gè)寬和高為200象素的方塊
          }

          //**************************************************
          // 例子6-2
          void CMyView::OnDraw(CDC * pDC)
          {
          pDC->SetMapMode(MM_TEXT);//設(shè)定映射模式為MM_TEXT
          pDC->SetWindowOrg(CPoint(100,100));//設(shè)定邏輯坐標(biāo)原點(diǎn)為(100,100)
          pDC->Rectangle(CRect(100,100,300,300));//畫一個(gè)寬和高為200象素的方塊
          }

             這兩個(gè)例子顯示出來的圖形是一樣的,都是從屏幕左上角開始的寬和高為200象素的方塊,可以看出例子2將邏輯坐標(biāo)(100,100)映射到了設(shè)備坐標(biāo)(0,0)處,這樣做有什么用?滾動(dòng)窗口使用的就是這種變換。

          固定比例映射模式:

          MM_LOENGLISH、MM_HIENGLISH、MM_LOMETRIC、MM_HIMETRIC、MM_TWIPS這一組是Windows提供的重要的固定比例映射模式。

          它們都是x值向右方向遞增,y值向下遞減,并且無法改變。它們之間的區(qū)別在于比例因子見下:(我想書上P53頁肯定是印錯(cuò)了,因?yàn)橥ㄟ^程序?qū)嶒?yàn)x值向右方向也是遞增的)

          MM_LOENGLISH 0.01英寸
          MM_HIENGLISH 0.001英寸
          MM_LOMETRIC 0.1mm
          MM_HIMETRIC 0.01mm
          MM_TWIPS 1/1440英寸 //應(yīng)用于打印機(jī),一個(gè)twip相當(dāng)于1/20磅,一磅又相當(dāng)于1/72英寸。

          看例3

          //**************************************************
          // 例子6-3
          void CMyView::OnDraw(CDC * pDC)
          {
          pDC->SetMapMode(MM_HIMETRIC);//設(shè)定映射模式為MM_HIMETRIC
          pDC->Rectangle(CRect(0,0,4000,-4000));//畫一個(gè)寬和高為4厘米的方塊
          }

             還有一種是可變比例映射模式,MM_ISOTROPIC、MM_ANISOTROPIC。用這種映射模式可以做到當(dāng)窗口大小發(fā)生變化時(shí)圖形的大小也會(huì)相應(yīng)的發(fā)生改變,同樣當(dāng)翻轉(zhuǎn)某個(gè)軸的伸展方向時(shí)圖象也會(huì)以另外一個(gè)軸為軸心進(jìn)行翻轉(zhuǎn),并且我們還可以定義任意的比例因子,怎么樣很有用吧。
          MM_ISOTROPIC、MM_ANISOTROPIC兩種映射模式的區(qū)別在于MM_ISOTROPIC模式下無論比例因子如何變化縱橫比是1:1而M_ANISOTROPIC模式則可以縱橫比獨(dú)立變化。

          讓我們看例子4

          //**************************************************
          // 例子6-4
          void CMy002View::OnDraw(CDC* pDC)
          {
          CRect rectClient; //
          GetClientRect(rectClient);//返回客戶區(qū)矩形的大小
          pDC->SetMapMode(MM_ANISOTROPIC);//設(shè)定映射模式為MM_ANISOTROPIC
          pDC->SetWindowExt(1000,1000);
          pDC->SetViewportExt (rectClient.right ,-rectClient.bottom );
          //用SetWindowExt和SetViewportExt函數(shù)設(shè)定窗口為1000邏輯單位高和1000邏輯單位寬
          pDC->SetViewportOrg(rectClient.right/2,rectClient.bottom/2 );//設(shè)定邏輯坐標(biāo)原點(diǎn)為窗口中心
          pDC->Ellipse(CRect(-500,-500,500,500));//畫一個(gè)撐滿窗口的橢圓。
          // TODO: add draw code for native data here
          }

          怎么樣,屏幕上有一個(gè)能跟隨窗口大小改變而改變的橢圓。把 pDC->SetMapMode(MM_ANISOTROPIC);這句改為pDC->SetMapMode(MM_ISOTROPIC)會(huì)怎樣?大家可以試試。那還有一個(gè)問題就是上例的比例因子是多少呢?看下面公式(注意是以例子4為例的)

          x比例因子=rectClient.right/1000 //視窗的寬除以窗口范圍
          y比例因子=-rectClient.bottom/1000 //視窗的高除以窗口范圍

             從Windows的鼠標(biāo)消息可以獲得鼠標(biāo)指針的當(dāng)前坐標(biāo)值(point.x和point.y)此坐標(biāo)值是設(shè)備坐標(biāo)。

          很多MFC庫函數(shù)尤其是CRect的成員函數(shù)只能工作在設(shè)備坐標(biāo)下。
          還有我們有時(shí)需要利用物理坐標(biāo),物理坐標(biāo)的概念就是現(xiàn)實(shí)世界的實(shí)際尺寸。
          設(shè)備坐標(biāo)-邏輯坐標(biāo)-物理坐標(biāo)之間如何進(jìn)行轉(zhuǎn)換便成為我們要考慮的一個(gè)問題,物理坐標(biāo)和邏輯坐標(biāo)是完全要我們自己來做的,但WINDOWS提供了函數(shù)來幫助我們轉(zhuǎn)換邏輯坐標(biāo)和設(shè)備坐標(biāo)。

          CDC的LPtoDP函數(shù)可以將邏輯坐標(biāo)轉(zhuǎn)換成設(shè)備坐標(biāo)
          CDC的DPtoLP函數(shù)可以將設(shè)備坐標(biāo)轉(zhuǎn)換成邏輯坐標(biāo)

          下面列出我們應(yīng)該在什么時(shí)候使用什么樣的坐標(biāo)系一定要記住:

          ◎CDC的所有成員函數(shù)都以邏輯坐標(biāo)為參數(shù)
          ◎CWnd的所有成員函數(shù)都以設(shè)備坐標(biāo)為參數(shù)
          ◎區(qū)域的定義采用設(shè)備坐標(biāo)
          ◎所有的選中測(cè)試操作應(yīng)考慮使用設(shè)備坐標(biāo)。
          ◎需要長(zhǎng)時(shí)間使用的值用邏輯坐標(biāo)或物理坐標(biāo)來保存。因設(shè)備坐標(biāo)會(huì)因窗口的滾動(dòng)變化而改變。
          用書上的例子作為以前幾篇的復(fù)習(xí),如果你能夠獨(dú)立完成它說明前面的內(nèi)容已經(jīng)掌握。另外有些東西是新的,我會(huì)比較詳細(xì)的做出說明,例如客戶區(qū)、滾動(dòng)窗口等。

          下面我們來一步步完成例子6-5:

          ■第一步:用AppWizard創(chuàng)建MyApp6。除了Setp 1 選擇單文檔視圖和Setp 6 選擇基類為CScrollView外其余均為確省。

          ■第二步:在CMyApp6View類中增加m_rectEllipse和m_nColor兩個(gè)私有數(shù)據(jù)成員。你可以手工在myapp6View.h添加,不過雷神建議這樣做,在ClassView中選中CMyApp6View類,擊右鍵選擇Add Member Variable插入它們。

          //**************************
          // myapp6View.h
          private:
          int m_nColor; //存放橢圓顏色值
          CRect m_rectEllipse; //存放橢圓外接矩形

          //***************************************************

          問題1: CRect是什么?
          CRect是類,是從RECT結(jié)構(gòu)派生的,和它類似的還有從POINT結(jié)構(gòu)派生的CPoint、從SIZE派生的CSize。因此它們繼承了結(jié)構(gòu)中定義的公有整數(shù)數(shù)據(jù)成員,并且由于三個(gè)類的一些操作符被重載所以可以直接在三個(gè)類之間進(jìn)行類的運(yùn)算。
          //重載operator +
          CRect operator +( POINT point ) const;
          CRect operator +( LPCRECT lpRect ) const;
          CRect operator +( SIZE size ) const;
          //重載operator -
          CRect operator -( POINT point ) const;
          CRect operator -( SIZE size ) const;
          CRect operator -( LPCRECT lpRect ) const;
          ......
          更多的請(qǐng)?jiān)贛SDN中查看

          ■第三步:修改由AppWizard生成的OnIntitalUpdate函數(shù)

          void CMyApp6View::OnInitialUpdate()
          {
          CScrollView::OnInitialUpdate();
          CSize sizeTotal(20000,30000);
          CSize sizePage(sizeTotal.cx /2,sizeTotal.cy /2);
          CSize sizeLine(sizeTotal.cx /50,sizeTotal.cy/50);
          SetScrollSizes(MM_HIMETRIC,sizeTotal,sizePage,sizeLine);//設(shè)置滾動(dòng)視圖的邏輯尺寸和映射模式
          }

          問題2: 關(guān)于void CMyApp6View::OnInitialUpdate()

          函數(shù)OnInitialUpdate()是一個(gè)非常重要的虛函數(shù),在視圖窗口完全建立后框架用的第一個(gè)函數(shù),框架在第一次調(diào)用OnDraw前會(huì)調(diào)用它。因此這個(gè)函數(shù)是設(shè)置滾動(dòng)視圖的邏輯尺寸和映射模式的最佳地點(diǎn)。

          ■第四步:編輯CMyApp6View構(gòu)造函數(shù)和OnDraw函數(shù)

          //*********************************************
          // CMyApp6View構(gòu)造函數(shù)
          //
          CMyApp6View::CMyApp6View():m_rectEllipse(0,0,4000,-4000)//橢圓矩形為4*4厘米。
          {
          m_nColor=GRAY_BRUSH;//設(shè)定刷子顏色
          }

          //************
          本文來自: 站長(zhǎng)(http://www.qqcf.com) 詳細(xì)出處參考:http://study.qqcf.com/web/189/21186.htm

          主站蜘蛛池模板: 通许县| 瑞丽市| 外汇| 吉安县| 深州市| 汉中市| 土默特右旗| 鲁甸县| 基隆市| 上虞市| 株洲市| 日喀则市| 平陆县| 金华市| 安阳县| 马鞍山市| 响水县| 博客| 察隅县| 荆门市| 阜阳市| 时尚| 贵州省| 石首市| 通州区| 阳朔县| 朝阳区| 江陵县| 温泉县| 武义县| 喜德县| 甘德县| 扎鲁特旗| 涪陵区| 卓尼县| 黑龙江省| 浮梁县| 确山县| 简阳市| 三穗县| 张家界市|