您的位置:首页 > 其它

映射模式/视口(viewport)和窗口(window)

2011-08-22 17:10 330 查看
OnPaint()

{

根据窗口大小算出新的图形坐标;

使用计算出的图形坐标绘制图形;

}

这样每次拖动后,OnPaint()就会被调用,自然就成比例了。

*****************************************************************************************************************************************

'视' (View) 是 '窗口' (Window)的一种。像你现在看到的浏览器,整个IE就是'窗口'(Screen/Window),而显示网页的区域就是'视口'(Client/View)。视口是显示文档的区域,即客户区!

窗口是依据逻辑坐标的,逻辑坐标可以是图素、毫米、英寸或者您想要的任何其它单位。您在GDI绘图函数中指定逻辑窗口坐标;而视口是相对于设备坐标而言的。

MM_ISOTROPIC --> 长宽比例保持一致,相当于设备长宽比变了后,图形也不会变形

MM_ANISOTROPIC --> 长宽比例根据设备坐标的长宽自动调整,可以不成比例

pDC->SetMapMode(MM_ISOTROPIC);

pDC->SetWindowExt(XRange/Rect.width, YRange/Rect.Height); // XRange指x方向需要画的点数,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、用设备上下文绘图的函数,其坐标参数值都是值逻辑单位,在默认情况下,映射模式为MM_TEXT,也就是说每个逻辑单位1对应1个像素(设备单位)。

1、窗口和视口(viewport)的概念

窗口用逻辑范围表示大小

视口用设备范围表示大小

这里所谓的窗口和视图只是一种大小范围的描述方式,主要是为了理解MapMode而划分的概念

2、逻辑单位和设备单位的映射

SetWindowExt() 设定窗口的逻辑范围

SetViewportExt() 设定视口的物理大小(参数值为设备单位,也就是像素大小)

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);

产生的效果是和上述代码的效果是一样的。

3、坐标原点

默认情况下,逻辑坐标原点和设备坐标原点是一致的,都是(0, 0),即窗口左上角设备坐标原点总是在左上角。

可用如下两个函数改变(移动)逻辑坐标原点:

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函数。例子具体如下:

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 函数可改变映射模式。

5、用户坐标值和屏幕坐标值的互相转化函数

CWnd::ClientToScreen 和 CWnd::ScreenToClient

6、坐标转换函数

CDC::LPtoDP 和 CDC::DPtoLP
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: