1概述编辑
绘图操作只能在客户区中进行。除客户区以外的部分都叫非客户区
例如,有的打印机设备水平和垂直分辨率不同,其象素实际上是长方形。程序编写画一个圆,若不经任何坐标转换,在打印机上输出的就是个椭圆。下面程序示范了如何将窗口逻辑坐标的x,y向象素宽度均映射为输出设备中的 1/64 英寸。
2代码编辑
[code]
SetMapMode(hDC, MM_ISOTROPIC);
SetWindowExt(hDC, 64, 64, NULL);
SetViewportExt(hDC, GetDeviceCaps(hDC, LOGPIXELSX),
GetDeviceCaps(hDC, LOGPIXELSY), NULL);
[/code]
3代码解释编辑
调用SetWindowExt()函数后,紧接着应调用SetViewportExt()函数,它的任务是规定水平及垂直坐标轴的单位。可以这样认为,SetWindowExt()函数对应着“窗口”,SetViewportExt()函数对应着“视口”。几点:
1.窗口是基于逻辑坐标的.
2.视口是基于设备坐标.
3.设备坐标是以像素为单位的,逻辑坐标是以.cm,m,mm,.....
4.系统最后一定要把逻辑坐标变为设备坐标.
5.设备坐标有3种:
a.GetDC() 客户区坐标.
b.GetWindowDC().窗口坐标.
c.GetDC(NULL),or CreateDC() .屏幕坐标.
4问题编辑
问题如下:
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()/2);
(5):pDC->DPtoLP(cRect);
(6):pDC->SetWindowOrg(-(cRect.Width()/2),-(cRect.Height()/2));
(7):pDC->TextOut(-850,1400,"abc");
...
}
我想问一下:上面每一步执行完后,窗口和视口的原点、范围分别是多少?屏幕分辨率是(800,600)。谢谢!
---------------------------------------------------------------
5问题解释编辑
第一句:定义逻辑单位和具体的设备单位的映射模式
第二句:设置与设备上下文关联的窗口的X和Y坐标的范围。其中4000和3000是逻辑坐标。此时窗口大小为(4000,3000),视口大小未知。
第三句:得到客户区尺寸。此尺寸就是当前视口尺寸。如果(800,600),在最大化时此尺寸为(800,600).
第四句:设置视口的范围,第二个参数为负数,表示视口坐标往下移了cRect高度的一半。
第五句:将设备坐标转换成逻辑坐标。因为GetClientRect得到的设备坐标
第六句:设置设备上下文窗口的起始坐标。
最后一句:在第六句的基础上,在逻辑坐标位置输出文本abc. 记住两个原则:
1.总是由窗口原点映射为视口原点。即无论你窗口的原点和视口的原点怎么变,窗口的原点总是映射到视口的原点。(记住:映射方向是窗口到视口,而不是视口向窗口映射)
2.不管利用函数(如:SetViewportOrgExt和SetWindowOrgEx)对窗口和视口的原点做怎么改变,设备点(0,0)始终是客户区的左上角。