On
{
根據(jù)窗口大小算出新的圖形坐標;
使用計算出的圖形坐標繪制圖形;
}
這樣每次拖動后,On
*****************************************************************************************************************************************
'視' (View) 是 '窗口' (Window)的一種。像你現(xiàn)在看到的瀏覽器,整個IE就是'窗口'(Screen/Window),而顯示網(wǎng)頁的區(qū)域就是'視口'(Client/View)。視口是顯示文檔的區(qū)域,即客戶區(qū)!
窗口是依據(jù)邏輯坐標的,邏輯坐標可以是圖素、毫米、英寸或者您想要的任何其它單位。您在GDI繪圖函數(shù)中指定邏輯窗口坐標;而視口是相對于設備坐標而言的。
MM_ISOTROPIC --> 長寬比例保持一致,相當于設備長寬比變了后,圖形也不會變形
MM_ANISOTROPIC --> 長寬比例根據(jù)設備坐標的長寬自動調整,可以不成比例
pDC->SetMapMode(MM_ISOTROPIC);
pDC->SetWindowExt(XRange/Rect.width, YRange/Rect.Height); // XRange指x方向需要畫的點數(shù),Rect.width是畫布寬度
pDC->SetViewportExt(1,1); //設置1,意思是指在一個像素點上能畫XRange/Rect.width個點
pDC->SetViewportOrg((rc.right+rc.left)/2, (rc.bottom+rc.top)/2); //將設備坐標點((rc.right+rc.left)/2, (rc.bottom+rc.top)/2)映射為邏輯坐標原點(0, 0)
你定了窗口的大小,視口的大小,那么你在窗口上的畫圖操作映射的視口(也就是顯示設備上)的比例也就確定了 :視口大小/窗口大小,即 XRange/Rect.width 和 YRange/Rect.Height。這樣點的一個像素大小在顯示設備上將按這個比例縮放(即一個像素點能畫幾個點)。從畫圖效果應該就能看出來。
注釋:
0、用設備上下文繪圖的函數(shù),其坐標參數(shù)值都是值邏輯單位,在默認情況下,映射模式為MM_TEXT,也就是說每個邏輯單位1對應1個像素(設備單位)。
1、窗口和視口(viewport)的概念
窗口用邏輯范圍表示大小
視口用設備范圍表示大小
這里所謂的窗口和視圖只是一種大小范圍的描述方式,主要是為了理解MapMode而劃分的概念
2、邏輯單位和設備單位的映射
SetWindowExt() 設定窗口的邏輯范圍
SetViewportExt() 設定視口的物理大小(參數(shù)值為設備單位,也就是像素大小)
SetWindowExt 必須要和SetViewportExt結合使用,并且只用在MM_ISOTROPIC和MM_ANISOTROPIC 模式下。在MM_ISOTROPIC 模式下SetWindowExt 必須在SetViewportExt之前調用。
例如:
pDC->SetMapMode(MM_ISOTROPIC); // 等比例模式
pDC->SetWindowExt(1000, -1000); // 設置窗口設為1000*1000的矩形
pDC->SetViewportExt(500, 500); // 設置視圖設為500*500像素的矩形,
// 由此可計算出每個像素對應2個邏輯單位:
// x坐標 1000/500 = 2, 向左為正向
// y坐標 -1000/500 = -2, 向下為負向
同理如下代碼:
pDC->SetMapMode(MM_ISOTROPIC);
pDC->SetWindowExt(1000, 1000);
pDC->SetViewportExt(500, -500);
產(chǎn)生的效果是和上述代碼的效果是一樣的。
3、坐標原點
默認情況下,邏輯坐標原點和設備坐標原點是一致的,都是(0, 0),即窗口左上角設備坐標原點總是在左上角。
可用如下兩個函數(shù)改變(移動)邏輯坐標原點:
SetWindowOrg() // 將設備坐標原點(0, 0)映射為某個邏輯坐標點
SetViewportOrg() // 將某個設備坐標點映射為邏輯坐標原點(0, 0)
SetWindowOrg 和SetViewportOrg可起到相同的效果,一般只用其中一個。
例如:
pDC->SetMapMode(MM_ISOTROPIC);
pDC->SetWindowExt(1000, 1000);
pDC->SetViewportExt(500, 500); // 由此可計算出每個設備坐標單位和邏輯單位的比例是1:2
// 一下兩句的效果都是一樣的
pDC->SetWindowOrg(-40, -40); // 將設備坐標原點(0, 0)設置映射邏輯坐標點(-40, -40)
// pDC->SetViewportOrg(20, 20); // 將設備坐標點(20, 20)映射為邏輯坐標原點(0, 0)
// 為什么是20 呢?因為每個設備坐標單位和邏輯單位的比例是 1:2
pDC->Rectangle(0, 0, 500, 300);
//若需將某點(x,y)畫到所設置的新的原點(0,0)上,只需使用
pDC->SetPixel(x-x,y-y,RGB(123,25,0));
//如果想畫一個大點的實心點,則可以首先定義一個CBrush對象,之后將它SelectObject到pDC中,最后使用ecllipse函數(shù)。例子具體如下:
CBrush hBrush(RGB(123,25,0)); //定義畫刷
CBrush *pOldBrush = pDC->SelectObject(&hBrush); //選到設備中去
pDC->Ellipse(pt-10,pt-10,pt+10,pt+10); //畫一個半徑為10個設備單位的圓
//鼠標點擊處pt相對于矩形rt中新原點(中心點)的位置(xpt,ypt):
if(pt.x>rt.top && pt.y<rt.bottom && pt.x<rt.right && pt.y>rt.top)
{
// xpt = (pt.x-rt.left)*(XRange/rt.width)-(XRange/rt.width)*(rt.right-rt.left)/2);
// ypt = - ((pt.y-rt.top)*(YRange/rt.Height)-((YRange/rt.Height)*(rt.bottom-rt.top)/2));
// AfxMessageBox(" button in rect ");
UpdateData(FALSE);
}
4、通過SetMapMode 函數(shù)可改變映射模式。
5、用戶坐標值和屏幕坐標值的互相轉化函數(shù)
CWnd::ClientToScreen 和 CWnd::ScreenToClient
6、坐標轉換函數(shù)
CDC::LPtoDP 和 CDC::DPtoLP