概述
繪圖操作只能在客戶區中進行。除客戶區以外的部分都叫非客戶區
例如,有的印表機設備水平和垂直解析度不同,其像素實際上是長方形。程式編寫畫一個圓,若不經任何坐標轉換,在印表機上輸出的就是個橢圓。下面程式示範了如何將視窗邏輯坐標的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)始終是客戶區的左上角。