(映射方式)Mapping modes
(设备坐标)Device coordinatesand (逻辑坐标)logicalcoordinates
设备坐标是依赖设备像素的,逻辑坐标则独立于设备像素。
设备坐标的单位是像素(pixel),逻辑坐标的单位则为1/100毫米。
另外,逻辑坐标的Y坐标随着点的下降而减小(屏幕顶端为0),例如:一个4X4厘米的正方形用逻辑坐标画出的方式为:pDC->Rectangle(CRect(0,0, 4000, -4000));
MM_TEXT Mapping Mode
MM_TEXT Mapping Mode是设备坐标的别名。鼠标右移时,x坐标增大,下移时y坐标增大,可以通过CDC函数设定坐标的原点。
例如
void CMyView::OnDraw(CDC* pDC)
{
pDC->SetMapMode(MM_TEXT);
pDC->SetWindowOrg(CPoint(100, 100));
pDC->Rectangle(CRect(100, 100, 300, 300));
}
画出了一个以(100,100)像素点为原点,边长为200像素的正方形.
The Fixed-Scale Mapping Modes(固定缩放映射)
之所以称之为固定比例缩放,是因为一旦映射模式选定,逻辑单位(Logical Unit)是固定的。具体的模式和对应的逻辑单位如下所示。
Mapping Mode |
Logical Unit |
MM_LOENGLISH |
0.01 inch |
MM_HIENGLISH |
0.001 inch |
MM_LOMETRIC |
0.1 mm |
MM_HIMETRIC |
0.01 mm |
MM_TWIPS |
1/1440 inch |
(Variable-Scale)缩放可变映射
Windows提供了两种缩放可变的映射方式:MM_ISOTROPIC和MM_ANISOTROPIC,
第一种模式下,坐标保持纵横比,即一个圆形无论怎么缩放仍然是圆形。第二种模式下,x、y轴的比例相互独立。一个通过更改坐标的缩放比例,圆形会变成椭圆。
例如:
void CMyView::OnDraw(CDC* pDC)
{
CRect rectClient;
GetClientRect(rectClient);
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetWindowExt(1000, 1000);
pDC->SetViewportExt(rectClient.right, -rectClient.bottom);
pDC->SetViewportOrg(rectClient.right / 2, rectClient.bottom / 2);
pDC->Ellipse(CRect(-500, -500, 500, 500));
}
这段程序在窗口画出一个椭圆,通过更改窗口纵横比的变化,椭圆相应的变化为圆或者更小的椭圆。
(coordinate convention)坐标转换
一旦映射模式选定,大部分的CDC函数可以使用逻辑坐标。
此外,我们还可能需要另一种叫做物理坐标(physical coordinate)的坐标。为什么我们需要物理坐标呢?假设你使用了MM_LOENGLISH映射模式,在这种模式下,一个逻辑单位的长度为0.01英尺,但是屏幕上的一英寸相当于现实世界中的一英尺(12英寸)。假设用户现在使用英寸和十进制分数。现实世界的26.75英寸换算成为屏幕上的223个逻辑单位,最终必须换算成为设备坐标。你会需要一个浮点数或者成比例的长整形来避免四舍五入带来的错误。
你可以自定义物理-逻辑坐标的转换。但是windows的GDI函数负责逻辑-设备的转换。CDC函数LPtoDP和DPtoLP在两个坐标系统间自由转换。假使设备上下文映射方式和相关的参数已经设定好了的话,你需要做的就是决定什么时候用什么样的坐标系统。关于这点,下面有一些规则:
1. 假定CDC函数需要逻辑坐标参数
2. 既定CWnd成员函数需要设备坐标
3. 所有击键测试在设备坐标中完成。以设备坐标定义区域(Defineregions in device coordinates)
4. 长期存在的值需要以逻辑坐标或者无理坐标的形式存储,假设你以设备坐标存储了一个点,那么当你滚动窗口时,那个点就失效了。