注意到CView类在进行显示和打印之前都会调用virtual void OnPrepareDC( CDC* pDC, CPrintInfo* pInfo = NULL )这个虚拟成员函数来准备设备上下文,我们可以在CView类中重载这个虚拟成员函数,进行坐标转换。
首先用VC的ClassWizard实现对OnPrepareDC( CDC* pDC, CPrintInfo* pInfo = NULL )函数的重载,ClassWizard生成的源代码如下:
| void CTempView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) { // TODO: Add your specialized code here and /or call the base class CView::OnPrepareDC(pDC, pInfo); } |
我们只需在源代码中加入以下几行代码即可,如下:
| void CPrintSameView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) { CView::OnPrepareDC(pDC, pInfo); pDC->SetMapMode(MM_ANISOTROPIC); //转换坐标映射方式 CSize size = CSize(800, 560); pDC->SetWindowExt(size); //确定窗口大小 //得到实际设备每逻辑英寸的象素数量 int xLogPixPerInch = pDC-> GetDeviceCaps(LOGPIXELSX); int yLogPixPerInch = pDC- >GetDeviceCaps(LOGPIXELSY); //得到设备坐标和逻辑坐标的比例 long xExt = (long)size.cx * xLogPixPerInch/96 ; long yExt = (long)size.cy * yLogPixPerInch/96 ; pDC->SetViewportExt((int)xExt, (int)yExt); //确定视口大小 } |
如上所示,首先将坐标映射方式改变为MM_ANISOTROPIC方式,即各向异性的意思,在这种坐标方式下,X轴和Y轴的逻辑单位可以进行任意的缩放。改变坐标映射方式后,就要确定窗口大小和视口大小,注意窗口大小就是我们在屏幕上所见的尺寸,而视口大小则是实际设备,如打印机等,和显示器设备每逻辑英寸的象素数量比较所得的比例尺寸。通过函数得到显示器和打印机每逻辑英寸的象素数量,然后对视口大小进行相应的缩放,就可以使得屏幕上的显示和打印机的输出是一致的了。
这样,只通过几行简单的代码,我们就实现了所见即所得的打印。