一
、Windows中的映射模式 1、Windows定義映射模式的目的
經(jīng)過我的綜合,Windows定義映射模的目的又以下幾個方面:1、不同人的使用習(xí)慣。不同國家的,不同地區(qū),以及不同的人因為習(xí)慣喜歡用不同的度量單位,有的人人喜歡用英寸,而有的人喜歡用公制中的厘米,毫米等。其他的人又喜歡用另外一些單位。、2、使軟件與硬件向分離開來。讓開發(fā)的軟件能夠最大限度的與硬件無關(guān)。3、提供邏輯和物理的一種轉(zhuǎn)換。就相當(dāng)于銀行的利率。
2、默認(rèn)的映射模式
默認(rèn)的映射模式使MM_TEXT,它使以象素為單位的。X軸向左為正,Y軸向下為正。默認(rèn)的坐標(biāo)原點在左上角。
3、固定比例映射模式
固定比例的映射模式有MM_LOMETRIC、MM_HIMETRIC、MM_LOENGLISH、MM_HIENGLISH、MM_TWIPS種。它們默認(rèn)的坐標(biāo)原點都使在左上角。其區(qū)別在于每一個邏輯單位對應(yīng)的物理大小不一樣。所對用的邏輯單位分別為0.1毫米,0.01毫米,0.01英寸,0.001英寸,1/1440英寸(0.0007英寸)。
4、可變比例映射模式
對于可變比例的映射模式用戶可以自己定義一個邏輯單位代表的大小,其大小可以任意。也可以讓這個大小隨環(huán)境改變而改變。有MM_ISOTROPIC,MM_ANISOTROPIC這兩種映射模式。其邏輯單位的大小等于視口范圍和窗口范圍的比值。兩者的不同在于前者要求X軸和Y軸的度量單位必須相同,而后者沒有這樣的限制。
二、Windows中的幾種坐標(biāo)體系
1、屏幕坐標(biāo)
屏幕坐標(biāo)描述物理設(shè)備(顯示器、打印機等)的一種坐標(biāo)體系,坐標(biāo)原點在屏幕的左上角,X軸向右為正,Y軸向下為正。度量單位是象素。原點、坐標(biāo)軸方向、度量單位都是不能夠改變的。
2、設(shè)備坐標(biāo)(又稱物理坐標(biāo))
設(shè)備坐標(biāo)是描述在屏幕和打印機顯示或打印的窗體的一種坐標(biāo)體系。默認(rèn)的坐標(biāo)原點是在其客戶區(qū)的左上角。X軸向右為正,Y軸向下為正。度量單位為象素。原點和坐標(biāo)軸方向可以改變,但是度量單位不可以改變。
3、邏輯坐標(biāo)
邏輯坐標(biāo)是在程序中控制顯示,打印使用的坐標(biāo)體系。該坐標(biāo)系與定義的映射模式密切相關(guān)。默認(rèn)的映射模式是MM_TEXT。我們可以通過設(shè)置不同的映射模式來改變該坐標(biāo)體系的默認(rèn)行為。
三、邏輯坐標(biāo)和設(shè)備坐標(biāo)之間的轉(zhuǎn)換
現(xiàn)有如下代碼:
void CMapModeView::OnPaint()
{
CPaintDC dc(this);
//獲取設(shè)備類的設(shè)置
CPoint ptOrgView,ptOrgWindow;
CSize sizeView,sizeWindow;
CString strMsg;
ptOrgView=dc.GetViewportOrg();//獲取視口原點
ptOrgWindow=dc.GetWindowOrg();//獲取窗口原點
sizeView=dc.GetViewportExt();//獲取視口范圍
sizeWindow=dc.GetWindowExt();//獲取窗口范圍
strMsg.Format(_T("Viewport Extent:(%d,%d),\tViewport Org:(%d,%d)\tWindow Extent:(%d,%d)\tWindow Org(%d,%d)"),
sizeView.cx,sizeView.cy,ptOrgView.x,ptOrgView.y,
sizeWindow.cx,sizeWindow.cy,ptOrgWindow.x,ptOrgWindow.y);
TRACE("%s\n",strMsg);
//設(shè)置映射模式以及原點
dc.SetMapMode(MM_TEXT);//設(shè)置映射模式
dc.SetWindowOrg(100,100);//設(shè)置窗口的坐標(biāo)原點
dc.SetViewportOrg(200,200);//設(shè)置視口的坐標(biāo)原點
dc.SetWindowExt(5,10);//改語句僅對可變比例映射模式有效
dc.SetViewportExt(1,1);//同上
ptOrgView=dc.GetViewportOrg();
ptOrgWindow=dc.GetWindowOrg();
sizeView=dc.GetViewportExt();
sizeWindow=dc.GetWindowExt();
strMsg.Format(_T("Viewport Extent:(%d,%d),\tViewport Org:(%d,%d)\tWindow Extent:(%d,%d)\tWindow Org(%d,%d)"),
sizeView.cx,sizeView.cy,ptOrgView.x,ptOrgView.y,
sizeWindow.cx,sizeWindow.cy,ptOrgWindow.x,ptOrgWindow.y);
TRACE("%s\n",strMsg);
//將點(300,400)從邏輯坐標(biāo)體系映射到設(shè)備坐標(biāo)體系。
CPoint ptMap;
ptMap=CPoint(300,400);
dc.LPtoDP(&ptMap);
strMsg.Format(_T("The Orginal Point(In LP):CPoint(300,400),Convert to DP is:CPoint(%d,%d)"),
ptMap.x,ptMap.y);
TRACE("%s\n",strMsg);
//將點(300,400)從設(shè)備坐標(biāo)體系映射到邏輯坐標(biāo)體系
ptMap=CPoint(300,400);
dc.DPtoLP(&ptMap);
strMsg.Format(_T("The Orginal Point(In DP):CPoint(300,400),Convert to LP is:CPoint(%d,%d)"),
ptMap.x,ptMap.y);
TRACE("%s\n",strMsg);
}
以上代碼最后調(diào)試輸出結(jié)果為:
Viewport Extent:(1,1), Viewport Org:(0,0) Window Extent:(1,1) Window Org(0,0)
Viewport Extent:(1,1), Viewport Org:(200,200) Window Extent:(1,1) Window Org(100,100)
The Orginal Point(In LP):CPoint(300,400),Convert to DP is:CPoint(400,500)
The Orginal Point(In DP):CPoint(300,400),Convert to LP is:CPoint(200,300)
按照MSDN上,函數(shù)SetWindowOrg(x,y)設(shè)定設(shè)備坐標(biāo)下的點(x,y)對應(yīng)于邏輯坐標(biāo)的原點。SetVieportOrg(x,y)設(shè)定邏輯坐標(biāo)下點(x,y)對應(yīng)邏輯坐標(biāo)的原點。而實際上如果同時設(shè)置了邏輯坐標(biāo)和設(shè)備坐標(biāo)原點的話,那么以上的說法是錯誤的。
在默認(rèn)映射模式MM_TEXT下,一個邏輯單位對應(yīng)于設(shè)備坐標(biāo)下的一個象素。改變默認(rèn)原點以后的坐標(biāo)體系如下圖所示:
(0,0) Dx,Lx (0,0)
(100,100) Lx
(200,200) Dx
.(300,400)
Dy,Ly Ly Dy
在VC中坐標(biāo)系的轉(zhuǎn)換和數(shù)學(xué)中的數(shù)學(xué)轉(zhuǎn)化是不一樣的。在這里是以距離為標(biāo)準(zhǔn)。首先看一下如何把點(300,400)如何從設(shè)備坐標(biāo)轉(zhuǎn)換成邏輯坐標(biāo)。
在設(shè)備坐標(biāo)體系下,點(300,400)與Y軸的距離為100個邏輯單位。那么所對應(yīng)的邏輯坐標(biāo)也要滿足與邏輯坐標(biāo)Y軸的距離為100個單位。又1個邏輯單位對應(yīng)1個象素。所以所對應(yīng)的設(shè)備坐標(biāo)的X值為100+100=200。同樣可以出對應(yīng)的邏輯坐標(biāo)的Y值為300。
按照同樣的方法,我們也可以把邏輯坐標(biāo)下的點(300,400)轉(zhuǎn)換成設(shè)備坐標(biāo)。在邏輯坐標(biāo)下,點(300,400)與邏輯坐標(biāo)Y軸的距離為200。那么在設(shè)備坐標(biāo)體系,相應(yīng)的設(shè)備坐標(biāo)與設(shè)備坐標(biāo)Y軸的距離也要為200。又1個邏輯單位對應(yīng)1個象素,所以對應(yīng)的設(shè)備坐標(biāo)X值為200+200=400。同樣的道理,可以求出對應(yīng)的設(shè)備坐標(biāo)Y值為500。
在這里,因為邏輯單位和設(shè)備單位一一對應(yīng),也可以把這個問題看作一個很簡單的坐標(biāo)平移問題來看。其結(jié)果是很顯然的。
另外又找到一篇:
一、映射模式基本知識
當(dāng)windows應(yīng)用程序在其客戶區(qū)繪制圖形時,必須給出在客戶區(qū)的位置,其位置用x和y 兩個坐標(biāo)表示,x表示橫坐標(biāo),y表示縱坐標(biāo)。在所有的gdi繪制函數(shù)中,這些坐標(biāo)使用的是一 種"邏輯單位"。當(dāng)gdi函數(shù)將輸出送到某個物理設(shè)備上時,windows將邏輯坐標(biāo) 轉(zhuǎn)換成設(shè)備坐標(biāo)(如屏幕或打印機的像素點)。邏輯坐標(biāo)和設(shè)備坐標(biāo)的轉(zhuǎn)換是由映射模式?jīng)Q 定的。映射模式被儲存在設(shè)備環(huán)境中。getmapmode函數(shù)用于從設(shè)備環(huán)境得到當(dāng)前的映射模 式,setmapmode函數(shù)用于設(shè)置設(shè)備環(huán)境的映射模式。
1.邏輯坐標(biāo)
邏輯坐標(biāo)是獨立于設(shè)備的,它與設(shè)備點的大小無關(guān)。使用邏輯單位,是實現(xiàn)"所 見即所得"的基礎(chǔ)。當(dāng)程序員在調(diào)用一個畫線的gdi函數(shù)lineto,畫出25.4mm(1英寸) 長的線時,他并不需要考慮輸出的是何種設(shè)備。若設(shè)備是vga顯示器,windows自動將其轉(zhuǎn)化 為96個像素點;若設(shè)備是一個300dpi的激光打印機,windows自動將其轉(zhuǎn)化為300個像素點。
2.設(shè)備坐標(biāo)
windows將gdi函數(shù)中指定的邏輯坐標(biāo)映射為設(shè)備坐標(biāo),在所有的設(shè)備坐標(biāo)系統(tǒng)中, 單位以像素點為準(zhǔn),水平值從左到右增大,垂直值從上到下增大。
windows中包括以下3種設(shè)備坐標(biāo),以滿足各種不同需要:
(1)客戶區(qū)域坐標(biāo),包括應(yīng)用程序的客戶區(qū)域,客戶區(qū)域的左上角為(0,0)。
(2)屏幕坐標(biāo),包括整個屏幕,屏幕的左上角為(0,0)。屏幕坐標(biāo)用在wm_move消息 中(對于非子窗口)以及下面的windows函數(shù)中:createwindow和movewindow(都對于非子窗 口)、getmessage、getcursorpos、getwindowrect、windowfrompoint和setbrushorg中。用函 數(shù)clienttoscreen和screentoclient可以將客戶區(qū)域坐標(biāo)轉(zhuǎn)換成屏幕區(qū)域坐標(biāo),或反之。
(3)全窗口坐標(biāo),包括一個程序的整個窗口,包括標(biāo)題條、菜單、滾動條和窗口框,窗 口的左上角為(0,0)。使用getwindowdc得到的窗口設(shè)備環(huán)境,可以將邏輯單位轉(zhuǎn)換成窗口 坐標(biāo)。
3.邏輯坐標(biāo)與設(shè)備坐標(biāo)的轉(zhuǎn)換方式
映射方式定義了windows如何將gdi函數(shù)中指定的邏輯坐標(biāo)映射為設(shè)備坐標(biāo)。要繼續(xù) 討論映射方式我們要介紹windows有關(guān)映射模式的一些術(shù)語:我們將邏輯坐標(biāo)所在的坐標(biāo) 系稱為"窗口",將設(shè)備坐標(biāo)所在的坐標(biāo)系稱為"視口"。
"窗口"依賴于邏輯坐標(biāo),可以是像素點、毫米或程序員想要的其他尺度。
"視口"依賴于設(shè)備坐標(biāo)(像素點)。通常,視口和客戶區(qū)域等同。但是,如 果程序員用getwindowdc或createdc獲取了一個設(shè)備環(huán)境,則視口也可以指全窗口坐標(biāo)或 屏幕坐標(biāo)。點(0,0)是客戶區(qū)域的左上角。x的值向右增加,y的值向上增加。
對于所有映射模式,windows都用下面兩個公式將窗口坐標(biāo)轉(zhuǎn)換成視口坐標(biāo):
xviewport=(xwindow-xwinorg)*(xviewext/xwinext)+xvieworg
yviewport=(ywindow-ywinorg)*(yviewext/ywinext)+yvieworg
其中,(xwindow,ywindows)是待轉(zhuǎn)換的邏輯點,(xviewport,yviewport)是轉(zhuǎn)換后 的設(shè)備點。如果設(shè)備坐標(biāo)是客戶區(qū)域坐標(biāo)或全窗口坐標(biāo),則windows在畫一個對象前,還必 須將這些坐標(biāo)轉(zhuǎn)換成屏幕坐標(biāo)。
這兩個公式使用了分別指定窗口和視口原點的點:(xwinorg,ywinorg)是邏輯坐標(biāo) 的窗口原點;(xvieworg,yvieworg)是設(shè)備坐標(biāo)的視口原點。在缺省的設(shè)備環(huán)境中,這兩個 點均設(shè)置為(0,0),但它們可以改變。此公式意味著,邏輯點(xwinorg,ywinorg)總被映射 為設(shè)備點(xvieworg,yvieworg)。
windows還能將視口(設(shè)備)坐標(biāo)轉(zhuǎn)換為窗口(邏輯)坐標(biāo):
xwindow=(xviewport-xvieworg)*(xwinext/xviewext)+xwinorg
ywindow=(yviewport-yvieworg)*(ywinext/yviewext)+ywinorg
可以使用windows提供的兩個函數(shù)dptolp和lptodp在設(shè)備坐標(biāo)及邏輯坐標(biāo)之間互相 轉(zhuǎn)換。
4.映射模式的種類
windows定義了表1所列出的8種映射方式。
上述映射模式中又可分成以下3類:
映 射 方 式 邏 輯 單 位 x 軸 增 加 y 軸 增 加 毫 米 mm_text 像 素 點 右 下 與 設(shè) 備 有 關(guān) mm_lometric 0. 1mm 右 上 0.1 mm_himetric 0. 01mm 右 上 0.01 mm_loenglish 0. 254mm 右 上 0.254 mm_hienglish 0. 0254mm 右 上 0.0254 mm_twips 0.0176mm 右 上 0.0176 mm_isotropic 任 意(x=y) 可 選 可 選 可 設(shè) mm_anisotropic 任 意(x!=y) 可 選 可 選 可 設(shè)
posted on 2008-02-03 13:10
cpsprogramer 閱讀(2224)
評論(1) 編輯 收藏 引用 所屬分類:
VC++