“窗口”和“视口”这两个词用得并不恰当。在其他图形界面语言中,视口通常包含有剪裁区域的意思,并且,我们以及用窗口来指程序在屏幕上占据的区域。
在这里的讨论中,我们必须把关于这些词的先入之见抛到一边。
映射方式用于定义从“窗口”(逻辑坐标)到“视口”(设备坐标)的映射。
“视口”是基于设备坐标(像素)的。
通常,视口和客户区相同,但是,如果你已经用 GetWindowDC 或 CreateDC 获取了一个设备描述表,则视口也可以是整窗口坐标或者屏幕坐标。
点(0,0)是客户区(或者整个窗口或屏幕)的左上角,x的值向右增加,y的值向下增加。
“窗口”是基于逻辑坐标的,逻辑坐标可以是像素、mm、英寸,或者你想要的任何其他单位。您在 GDI 绘图函数中指定逻辑窗口坐标。
对于所有的映射方式,Windows 都用下面两个公式来将窗口(逻辑)坐标转化为视口(设备)坐标:
xViewport = (xWindow - xWinOrg) *(xViewExt/xWinExt) + xViewOrg
yViewPort = (yWindow - yWinOrg) * (yViewExt/yWinExt) + yViewOrg
其中,(xWindow,yWindow)是带转换的逻辑点,(xViewport,yViewport)是转换后的设备坐标点,更像客户区坐标。(xWinOrg,yWinOrg)是逻辑坐标的窗口原点;(xViewOrg,yViewOrg)是设备坐标的视口原点。在默认的设备描述表中,这两个点均被设置为(0,0),但是他们可以改变。
设备点与逻辑点相互转换的函数:
// 设备点转换为逻辑点
DPtoLP(hdc,pPoints,iNumber);
// 将逻辑点转换为设备点
LPtoDP(hdc,pPoints,iNumber);
// pPoints是一个指向 POINT 结构数组的指针,而 iNumber 是要转换的点的个数。
// 将 GetClientRect(它总是使用设备单位)获取的客户区大小转换为逻辑坐标
GetClientRect(hwnd,&rect);
DPtoLP(hdc,(POINT)&rect,2);
Windows 提供了函数 SetViewportOrgEx 和 SetWindowOrgEx,用来改变视口和窗口的原点。
可以使用下面两个函数来获取当前视口和窗口的原点:
GetViewportOrgEx(hdc,&pt);
GetWindowOrgEx (hdc,&pt);