窗口与视口,之间的区别,联系,如何理解,越详细越好,谢谢!
解决方案 »
- vc初学,关于线程调用的问题
- 学习《COM技术内幕》组件聚合遇到一些问题~
- 关于文件 保存问题
- CSocket用法与线程同步问题
- 请问一下以asp为后缀的文件用什么可以阅读?
- 求穿防火墙、NAT的技术资料
- 请教:怎样在列表控件中放进度条,并怎样控制
- linking 出错,,高手的高手请进
- debug 的时候每问题,release 的时候,操作却是非法操作???why???
- 寻求杭州市区 VC 高手3名,美工1名
- MsgWaitForMultipleObjects()函数的前两个参数该怎么设置
- #pragma comment(lib, "wsock32") 跟 #pragma comment(lib,"Ws2_32.lib")有啥区别么?
视口可以指客户区,也可以指窗口坐标,还可以指整个屏幕坐标.它是基于设备坐标的.窗口则是基于逻辑坐标的
http://hi.baidu.com/%C5%E1%F6%CE0227/blog/item/5a5d85173cef8356f3de3200.html关于窗口与视口的总结
绘图操作只能在客户区中进行。除客户区以外的部分都叫非客户区
在 Windows的作图函数中,涉及逻辑坐标到设备坐标的转换。这里提到的窗口(window)、视口(viewport)是对应的概念。视口是与设备相关 的一个矩形区域,坐标单位是与设备相关的。窗口的坐标是逻辑坐标,与设备无关。窗口坐标的原点与视口坐标的原点始终对应于同一点。,窗口原点是与视口原点相同的,(也就是说,位于屏幕上的同一个位置),为了体会不窗口坐标与视口坐标的转换,先用SetwindowtOrg(100, -300)将视口移到(100,-300),这相当于把 逻辑点(100,-300)映射到设备点(0,0) (注意:如果改用SetviewportOrg移动原点,则其原点的移动尺寸与映射模式无关,其300个长度单位等于9厘米) (注:这个设备点也是相对于当前的DC而言,如果当前的DC是整个屏幕,那么设备点(100,-300)的原点就在屏幕的左上角,如果当前的DC是某个应用程序的客户区,那么设备点(100,-300)的原点就是应用程序的客户区的左上角,) 现在假设当前DC是某个应用程序的客户区,映射模式为 MM_LOMETRIC
(在这种映射模式下,设备坐标以0.1 毫米为一个长度单位,Y轴的正方向为向上,也就是说,屏幕上的左上角的Y坐标为0,下面的Y坐标均小于0),当使用语句: MoveTo(100,-600);
LineTo(100,-800);//Y轴负方向向下,所以用负值 进行画图时,它的转换过程如下:
1)窗口与视口坐标转换,由于窗口坐标(100,-300 ),映射为设备坐标(0,0),所 以
窗口(100,-600)映射为视口(0,-300)
窗口(100,-800)视映射为视口(0,-500) 2)逻辑与设备坐标转换
由于是 MM_LOMETRIC 映射模式,设备坐标的单位长度为 0.1mm,而在输出时用的是视口坐标,所以视口坐标(100,-600)输出到屏幕上时,该点的位置
距客户区左边 0 厘米,距客户区上边 3厘米。这就是直线的起点;
再把直线终点的视口坐标(100,-800)输出到距客户区左边0厘米,距客户区上边 5厘米处。对于同一个图形,用窗口 坐标系统表达的该区域的长和宽与视口的坐标系统表达的长和宽是不同的。二者就定义了这两个坐标系统的比例关系。程序作图时,使用的坐标总是是窗口坐标。而 实际的显示或输出设备却各有自己的坐标。例如,有的打印机设备水平和垂直分辨率不同,其象素实际上是长方形。程序编写画一个圆,若不经任何坐标转换,在打 印机上输出的就是个椭圆。下面程序示范了如何将窗口逻辑坐标的x,y向象素宽度均映射为输出设备中的 1/64 英寸。
[code]
SetMapMode(hDC, MM_ISOTROPIC);
SetWindowExtEx(hDC, 64, 64, NULL);
SetViewportExtEx(hDC, GetDeviceCaps(hDC, LOGPIXELSX),
GetDeviceCaps(hDC, LOGPIXELSY), NULL);
[/code]
调用SetWindowExt()函数后,紧接着应调用SetViewportExt()函数,它的任务是规定水平及垂直坐标轴的单位。可以这样认为,SetWindowExt()函数对应着“窗口”,SetViewportExt()函数对应着“视口”。几点:
1.窗口是基于逻辑坐标的.
2.视口是基于设备坐标.
3.设备坐标是以像素为单位的,逻辑坐标是以.cm,m,mm,.....
4.系统最后一定要把逻辑坐标变为设备坐标.
5.设备坐标有3种:
a.GetDC() 客户区坐标.
b.GetWindowDC().窗口坐标.
c.GetDC(NULL),or CreateDC() .屏幕坐标.
问题如下:
void CMyView::OnDraw(CDC *pDC)
{
...
(1):pDC->SetMapMode(MM_ISOTROPIC);
(2):pDC->SetWindowExt(4000,3000);
(3):AfxGetMainWnd()->GetClientRect(cRect);
(4):pDC->SetViewportExt(cRect.Width(),-cRect.Height());
(5):pDC->DPtoLP(cRect);
(6):pDC->SetWindowOrg(-(cRect.Width()/2),-(cRect.Height()/2));
(7):pDC->TextOut(-850,1400,"abc");
...
} 第一句:定义逻辑单位和具体的设备单位的映射模式
第二句:设置与设备上下文关联的窗口的X和Y坐标的范围。其中4000和3000是逻辑坐标。此时窗口大小为(4000,3000),视口大小未知。
第三句:得到客户区尺寸。此尺寸就是当前视口尺寸。如果(800,600),在最大化时此尺寸为(800,5XX).
第四句:设置视口的范围,第二个参数为负数,表示视口坐标往下移了cRect高度的一半。
第五句:将设备坐标转换成逻辑坐标。因为GetClientRect得到的设备坐标
第六句:设置设备上下文窗口的起始坐标。
最后一句:在第六句的基础上,在逻辑坐标位置输出文本abc. 记住两个原则:
1.总是由窗口原点映射为视口原点。即无论你窗口的原点和视口的原点怎么变,窗口的原点总是映射到视口的原点。(记住:映射方向是窗口到视口,而不是视口向窗口映射)
2.不管利用函数(如:SetViewportOrgExt和SetWindowOrgEx)对窗口和视口的原点做怎么改变,设备点(0,0)始终是客户区的左上角。