坐标系统、映射模式

三种坐标系统:
屏幕坐标
全窗口坐标
客户区坐标
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);

你可能感兴趣的:(坐标系统,映射模式)