明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線(xiàn)學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

Windows編程中的映射模式與坐標(biāo)轉(zhuǎn)換

[摘要]一、Windows中的映射模式1、Windows定義映射模式的目的經(jīng)過(guò)我的綜合,Windows定義映射模的目的又以下幾個(gè)方面:1、不同人的使用習(xí)慣。不同國(guó)家的,不同地區(qū),以及不同的人因?yàn)榱?xí)慣喜歡用不...
一、Windows中的映射模式
1、Windows定義映射模式的目的
經(jīng)過(guò)我的綜合,Windows定義映射模的目的又以下幾個(gè)方面:1、不同人的使用習(xí)慣。不同國(guó)家的,不同地區(qū),以及不同的人因?yàn)榱?xí)慣喜歡用不同的度量單位,有的人人喜歡用英寸,而有的人喜歡用公制中的厘米,毫米等。其他的人又喜歡用另外一些單位。、2、使軟件與硬件向分離開(kāi)來(lái)。讓開(kāi)發(fā)的軟件能夠最大限度的與硬件無(wú)關(guān)。3、提供邏輯和物理的一種轉(zhuǎn)換。就相當(dāng)于銀行的利率。
2、默認(rèn)的映射模式
默認(rèn)的映射模式使MM_TEXT,它使以象素為單位的。X軸向左為正,Y軸向下為正。默認(rèn)的坐標(biāo)原點(diǎn)在左上角。
3、固定比例映射模式
固定比例的映射模式有MM_LOMETRIC、MM_HIMETRIC、MM_LOENGLISH、MM_HIENGLISH、MM_TWIPS種。它們默認(rèn)的坐標(biāo)原點(diǎn)都使在左上角。其區(qū)別在于每一個(gè)邏輯單位對(duì)應(yīng)的物理大小不一樣。所對(duì)用的邏輯單位分別為0.1毫米,0.01毫米,0.01英寸,0.001英寸,1/1440英寸(0.0007英寸)。
4、可變比例映射模式
對(duì)于可變比例的映射模式用戶(hù)可以自己定義一個(gè)邏輯單位代表的大小,其大小可以任意。也可以讓這個(gè)大小隨環(huán)境改變而改變。有MM_ISOTROPIC,MM_ANISOTROPIC這兩種映射模式。其邏輯單位的大小等于視口范圍和窗口范圍的比值。兩者的不同在于前者要求X軸和Y軸的度量單位必須相同,而后者沒(méi)有這樣的限制。
二、Windows中的幾種坐標(biāo)體系
1、屏幕坐標(biāo)
屏幕坐標(biāo)描述物理設(shè)備(顯示器、打印機(jī)等)的一種坐標(biāo)體系,坐標(biāo)原點(diǎn)在屏幕的左上角,X軸向右為正,Y軸向下為正。度量單位是象素。原點(diǎn)、坐標(biāo)軸方向、度量單位都是不能夠改變的。
2、設(shè)備坐標(biāo)(又稱(chēng)物理坐標(biāo))
設(shè)備坐標(biāo)是描述在屏幕和打印機(jī)顯示或打印的窗體的一種坐標(biāo)體系。默認(rèn)的坐標(biāo)原點(diǎn)是在其客戶(hù)區(qū)的左上角。X軸向右為正,Y軸向下為正。度量單位為象素。原點(diǎn)和坐標(biāo)軸方向可以改變,但是度量單位不可以改變。
3、邏輯坐標(biāo)
邏輯坐標(biāo)是在程序中控制顯示,打印使用的坐標(biāo)體系。該坐標(biāo)系與定義的映射模式密切相關(guān)。默認(rèn)的映射模式是MM_TEXT。我們可以通過(guò)設(shè)置不同的映射模式來(lái)改變?cè)撟鴺?biāo)體系的默認(rèn)行為。
三、邏輯坐標(biāo)和設(shè)備坐標(biāo)之間的轉(zhuǎn)換
現(xiàn)有如下代碼:
void CMapModeView::OnPaint()
{
CPaintDC dc(this);

//獲取設(shè)備類(lèi)的設(shè)置
CPoint ptOrgView,ptOrgWindow;
CSize sizeView,sizeWindow;
CString strMsg;

ptOrgView=dc.GetViewportOrg();//獲取視口原點(diǎn)
ptOrgWindow=dc.GetWindowOrg();//獲取窗口原點(diǎn)
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è)置映射模式以及原點(diǎn)
dc.SetMapMode(MM_TEXT);//設(shè)置映射模式
dc.SetWindowOrg(100,100);//設(shè)置窗口的坐標(biāo)原點(diǎn)
dc.SetViewportOrg(200,200);//設(shè)置視口的坐標(biāo)原點(diǎn)

dc.SetWindowExt(5,10);//改語(yǔ)句僅對(duì)可變比例映射模式有效
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);

//將點(diǎn)(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);

//將點(diǎn)(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)下的點(diǎn)(x,y)對(duì)應(yīng)于邏輯坐標(biāo)的原點(diǎn)。SetVieportOrg(x,y)設(shè)定邏輯坐標(biāo)下點(diǎn)(x,y)對(duì)應(yīng)邏輯坐標(biāo)的原點(diǎn)。而實(shí)際上如果同時(shí)設(shè)置了邏輯坐標(biāo)和設(shè)備坐標(biāo)原點(diǎn)的話(huà),那么以上的說(shuō)法是錯(cuò)誤的。
在默認(rèn)映射模式MM_TEXT下,一個(gè)邏輯單位對(duì)應(yīng)于設(shè)備坐標(biāo)下的一個(gè)象素。改變默認(rèn)原點(diǎ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)。首先看一下如何把點(diǎn)(300,400)如何從設(shè)備坐標(biāo)轉(zhuǎn)換成邏輯坐標(biāo)。
在設(shè)備坐標(biāo)體系下,點(diǎn)(300,400)與Y軸的距離為100個(gè)邏輯單位。那么所對(duì)應(yīng)的邏輯坐標(biāo)也要滿(mǎn)足與邏輯坐標(biāo)Y軸的距離為100個(gè)單位。又1個(gè)邏輯單位對(duì)應(yīng)1個(gè)象素。所以所對(duì)應(yīng)的設(shè)備坐標(biāo)的X值為100+100=200。同樣可以出對(duì)應(yīng)的邏輯坐標(biāo)的Y值為300。
按照同樣的方法,我們也可以把邏輯坐標(biāo)下的點(diǎn)(300,400)轉(zhuǎn)換成設(shè)備坐標(biāo)。在邏輯坐標(biāo)下,點(diǎn)(300,400)與邏輯坐標(biāo)Y軸的距離為200。那么在設(shè)備坐標(biāo)體系,相應(yīng)的設(shè)備坐標(biāo)與設(shè)備坐標(biāo)Y軸的距離也要為200。又1個(gè)邏輯單位對(duì)應(yīng)1個(gè)象素,所以對(duì)應(yīng)的設(shè)備坐標(biāo)X值為200+200=400。同樣的道理,可以求出對(duì)應(yīng)的設(shè)備坐標(biāo)Y值為500。
在這里,因?yàn)檫壿媶挝缓驮O(shè)備單位一一對(duì)應(yīng),也可以把這個(gè)問(wèn)題看作一個(gè)很簡(jiǎn)單的坐標(biāo)平移問(wèn)題來(lái)看。其結(jié)果是很顯然的。