視口

視口

在 Windows的作圖函式中,涉及邏輯坐標到設備坐標的轉換。這裡提到的視窗(window)、視口(viewport)是對應的概念。視口是與設備相關的一個矩形區域,坐標單位是與設備相關的“像素”,大多數情況下,視口與客戶區相同。視窗的坐標是邏輯坐標,與設備無關,可能是像素、毫米或者英寸。視窗坐標的原點與視口坐標的原點始終對應於同一點。對於同一個圖形,用視窗坐標系統表達的該區域的長和寬與視口的坐標系統表達的長和寬是不同的。二者就定義了這兩個坐標系統的比例關係。程式作圖時,使用的坐標總是是視窗坐標。而實際的顯示或輸出設備卻各有自己的坐標。

概述

繪圖操作只能在客戶區中進行。除客戶區以外的部分都叫非客戶區

例如,有的印表機設備水平和垂直解析度不同,其像素實際上是長方形。程式編寫畫一個圓,若不經任何坐標轉換,在印表機上輸出的就是個橢圓。下面程式示範了如何將視窗邏輯坐標的x,y向象素寬度均映射為輸出設備中的 1/64 英寸。

代碼

[code]

SetMapMode(hDC, MM_ISOTROPIC);

SetWindowExt(hDC, 64, 64, NULL);

SetViewportExt(hDC, GetDeviceCaps(hDC, LOGPIXELSX),

GetDeviceCaps(hDC, LOGPIXELSY), NULL);

[/code]

代碼解釋

調用SetWindowExt()函式後,緊接著應調用SetViewportExt()函式,它的任務是規定水平及垂直坐標軸的單位。可以這樣認為,SetWindowExt()函式對應著“視窗”,SetViewportExt()函式對應著“視口”。幾點:

1.視窗是基於邏輯坐標的.

2.視口是基於設備坐標.

3.設備坐標是以像素為單位的,邏輯坐標是以.cm,m,mm,.....

4.系統最後一定要把邏輯坐標變為設備坐標.

5.設備坐標有3種:

a.GetDC() 客戶區坐標.

b.GetWindowDC().視窗坐標.

c.GetDC(NULL),or CreateDC() .螢幕坐標.

問題

問題如下:

void CMyView::OnDraw(CDC *pDC)

{

...

(1):pDC->SetMapMode(MM_ISOTROPIC);

(2):pDC->SetWindowExt(4000,3000);

(3):AfxGetMainWnd()->GetClientRect(cRect);

(4):pDC->SetViewportExt(cRect.Width(),-cRect.Height ()/2);

(5):pDC->DPtoLP(cRect);

(6):pDC->SetWindowOrg(-(cRect.Width()/2),-(cRect.Height()/2));

(7):pDC->TextOut(-850,1400,"abc");

...

}

我想問一下:上面每一步執行完後,視窗和視口的原點、範圍分別是多少?螢幕解析度是(800,600)。謝謝!

---------------------------------------------------------------

問題解釋

第一句:定義邏輯單位和具體的設備單位的映射模式

第二句:設定與設備上下文關聯的視窗的X和Y坐標的範圍。其中4000和3000是邏輯坐標。此時視窗大小為(4000,3000),視口大小未知。

第三句:得到客戶區尺寸。此尺寸就是當前視口尺寸。如果(800,600),在最大化時此尺寸為(800,600).

第四句:設定視口的範圍,第二個參數為負數,表示視口坐標往下移了cRect高度的一半。

第五句:將設備坐標轉換成邏輯坐標。因為GetClientRect得到的設備坐標

第六句:設定設備上下文視窗的起始坐標。

最後一句:在第六句的基礎上,在邏輯坐標位置輸出文本abc. 記住兩個原則:

1.總是由視窗原點映射為視口原點。即無論你視窗的原點和視口的原點怎么變,視窗的原點總是映射到視口的原點。(記住:映射方向是視窗到視口,而不是視口向視窗映射)

2.不管利用函式(如:SetViewportOrgExt和SetWindowOrgEx)對視窗和視口的原點做怎么改變,設備點(0,0)始終是客戶區的左上角。

相關詞條

相關搜尋

熱門詞條

聯絡我們