三种坐标系统:
屏幕坐标
全窗口坐标
客户区坐标
ClientToScreen 把客户区坐标转换到屏幕坐标
ScreenToClient 把屏幕坐标转换到客户区坐标
GetWindowRect 以屏幕坐标形式获取整个窗口的位置和大小
GetClientRect (hwnd, &rect);
DPtoLP (HDC hdc, POINT * pPoints, int iNumber); 多个设备点转换为逻辑点
LPtoDP (HDC hdc, POINT * pPoints, int iNumber); 多个逻辑点转换为设备点
映射模式
MM_TEXT 默认
MM_LOMETRIC
0.1mm
0.00394 in.
MM_HIMETRIC
0.01mm
0.000394 in.
MM_HIENGLISH
0.001 in.
0.0254 mm
MM_LOENGLISH
0.01 in.
0.254 mm
MM_TWIPS
1/1440 in.
0.0174 mm
MM_ISOTROPIC
任意(x=y)
MM_ANISOTROPIC
任意(x!=y)
窗口原点(0,0)
可以改变
视图原点(0,0)
可以改变
窗口范围(?,?)
不可改变
视图范围(?,?)
不可改变
MM_TEXT 映射模式下范围全为 1
xViewport = (xWindow - xWinOrg)* xViewExt/xWinExt + xViewOrg
yViewport = (yWindow - yWinOrg)* yViewExt/yWinExt + yViewOrg
例如,在MM_LOENGLISH 映射模式下,windows使用如下公式计算范围
xViewExt/xWinExt = 0.01英寸中的水平像素数
yViewExt/yWinExt = 0.01英寸中的垂直像素数
5 种度量映射模式
当首次改变为 5 种映射模式之一时,坐标系统 从左到右x正向,从上到下y负向,原点(0,0)
SetMapMode (hdc, iMapMode);
//设置映射模式
iMapMode = GetMapMode (hdc);
//获得映射模式
设置完后可用 SetViewportOrgEx() 改变逻辑点
但使用 SetWindowOrgEx() 改变逻辑点时由于参数必须为逻辑坐标,需要用 DPtoLP函数把(cxClient,cyClient)转换为逻辑坐标
但windows对所有的非GDI函数,都继续使用设备坐标,如WM_MOVE、WM_SIZE、WM_MOUSEMOVE
可以把映射模式理解为设备环境的一种属性,因此,只有使用以设备环境句柄作为参数的GDI函数时,映射模式才会有效
但尽管GetDeviceCaps是需要环境句柄的GDI函数,但Windows继续为HORZERS和VERTRES索引返回设备单位(像素)
GetTextMetrics是逻辑单位
SetViewportOrgEx (x,y)
改变视口原点 逻辑点(0,0)映射到设置点(设备)
SetWindowOrgEx (x,y)
改变窗口原点 设置的逻辑点被映射到设备点(0,0)
GetViewportOrgEx (hdc, &pt);
以设备坐标形式给出
GetWindowOrgEx (hdc, &pt);
以逻辑坐标形式给出
自定义的映射模式
MM_ISOTROPIC
各向同性,同比例缩放两个坐标轴,半受限,会调整以便同比例
MM_ANISOTROPIC
各向异性,不受限制,windows不会调整它们的值
第一次设置映射模式为MM_ISOTROPIC 时,windows 使用与MM_LOMETRIC 映射模式相同的窗口和视口范围。可以用
SetWindowExtEx()
SetViewportExtEx()
参数设置为客户区的实际高度和宽度
来改变范围,之后windows会调整范围以使两个轴逻辑单位表示相同的物理距离,调整时,它必须让逻辑窗口可以容纳再对应的物理视口之内,这就可能导致一部分的客户区落在逻辑窗口之外
SetMapMode (hdc, MM_ISOTROPIC);
SetWindowExtEx (hdc, 100, 100, NULL); 每英寸逻辑单位的个数
SetViewportExtEx (hdc, cxClient, -cyClient, NULL); 每英寸物理单位(像素)的个数
SetViewportOrgEx (hdc, 0, cyClient, NULL);
GetWindowExtEx (hdc, &lp); lp是SIZE结构
GetViewportExtEx (hdc, &lp);
SetMapMode (hdc, MM_ANISOTROPIC); 不锁定范围
第一次设置为此模式时,会继承前面所设定的映射方式的范围,方便改变模式,改变y轴方向的例子:
SIZE size;
SetMapMode (hdc, MM_TEXT);
SetMapMode (hdc, MM_ANISOTROPIC);
GetViewportExtEx (hdc, &size);
SetViewportExtEx (hdc, size.cx, -size.cy, NULL);