所谓视口代表设备,比如屏幕。 窗口代表我们的思维。
我们对windows说在(5,6)处画个点(调用GDI函数)。windows认为是在我们的思维的(5,6)处画了个点。(也就是说5,6是逻辑坐标,GDI函数中的大部分都是逻辑坐标) 那么,要把它映射到屏幕上,必须作一些解释。 解释包括: 原点在哪里?5,6代表什么?
注意,解释5,6时不光是距离问题,还有方向呢!
SetViewportOrgEx和SetWindowOrgEx是管第一个问题的。设置原点和设置X轴Y轴方向(SetMapMode)。<<>>
SetViewportExtEx和SetWindowExtEx是管第二个问题的。 设置比率。 其实想象一下也可以知道,5和6应该是乘上一个比率来变成像素单位。而后根据原点并按照X轴Y轴方向去画就可以了。 SetViewportExtEx和SetWindowExtEx就是决定比率的函数。(他们的第二个和第三个参数分别相除来代表横纵坐标的比率。)
SetWindowExtEx用于设置逻辑坐标范围。SetViewportExtEx用于设置设备坐标范围。必须在呼叫SetViewportExtEx之前呼叫SetWindowExtEx,以便最有效地使用显示区域中的空间。举个例子:
SetMapMode(hdc,MM_ANISOTROPIC); SetWindowExtEx(hdc,1,1,NULL); SetViewportExtEx(hdc,cxChar,cyChar,NULL); TextOut(hdc,3,2,TEXT( "Hello "),5);
由于TextOut的坐标值是3和2,在Windows98允许的范围32767之内,所以还是可以显示出 "Hello "字符串。 又因为程序把窗口的范围(逻辑坐标范围)定义为1,而视口的范围(设备坐标范围)定义为cxChar和cyChar(字符的平均宽度和平均高度),因此在显示时,Windows会在(3*(cxChar/1),2*(cyChar/1))的地方(也就是第二行的第三个字符处)显示字符串 "Hello "。
windows使用设备坐标进行显示,逻辑被转换为设备坐标:
设备坐标点X = (待转换的逻辑点X - 逻辑坐标的窗口原点X) * (设备坐标的视端口范围X / 逻辑坐标的窗口范围X) + 设备坐标的视端口原点X
我们通过改一改数值来证明一下: SetMapMode(hdc,MM_ANISOTROPIC); SetWindowExtEx(hdc,4,4,NULL); //设窗口范围(逻辑坐标范围)为4个逻辑单位 SetViewportExtEx(hdc,8,8,NULL); //设视口范围(设备坐标范围)为8个物理单位(也就是8个像素) TextOut(hdc,1,1,TEXT( "Hello "),5); //在逻辑坐标(1,1)处显示 "Hello "
从上面的代码我们得出X轴的逻辑与物理比值为2,Y轴的逻辑与物理比值也为2,1*(8/4)=2,因此,Windows事实上会在客户区的左上角往右2个像素、往下2个像素的地方显示 "Hello "。
我们仍然可以把TextOut中的值进行修改: TextOut(hdc,10,10,TEXT( "Hello "),5);
10明显超出了我们定义的逻辑范围4,但是因为它并没有超过坐标值的上限32767,因此,10*(8/4)=20,Windows仍然会在客户区的左上角往右20个像素、往下20个像素的地方显示 "Hello "。