
本文共 1542 字,大约阅读时间需要 5 分钟。
MFC提供了一个框架性的打印和打印预览功能代码,其基本思想是将实际显示和打印文档的代码合二为一,即都由此文档关联的CView中的OnDraw(CDC *pDC)来处理。MFC框架根据用户操作决定传进来的pDC是指向屏幕还是打印机设备。当pDC指向屏幕设备时,在屏幕上显示文档;指向打印机设备时则打印文档。
在打印预览模式中,pDC的性质与屏幕设备的pDC有所不同。虽然打印预览是在屏幕上进行的,但传入的pDC是基于当前默认打印机的属性构造的。例如,计算机上安装的打印机若以A4纸张(210mm X 297mm)和1200dpi分辨率为默认设置时,调用pDC->GetDeviceCaps(HORZSIZE)和pDC->GetDeviceCaps(VERTSIZE)会返回210mm和297mm的值。这与A4纸张的实际尺寸一致。
进一步调用pDC->GetDeviceCaps(HORZRES)和pDC->GetDeviceCaps(VERTRES)会返回9917和14031,这是210mm和297mm长度在1200dpi分辨率下的象素(点)数量计算结果。1英寸等于25.4毫米,因此210mm对应的象素数量为210/25.4×1200≈9917,而297mm对应的象素数量为297/25.4×1200≈14031。
接下来考虑内存DC的情况。当使用MemDC.CreateCompatibleDC(pDC)创建一个与pDC兼容的内存设备DC时,调用GetDeviceCaps(HORZSIZE)等函数会返回320和240,这是Windows系统常见的固定值。同时,1024和768是屏幕分辨率的典型数值。
关于DC的映射模式,需要注意的是MemDC在创建时的默认映射模式是MM_TEXT,而不是与pDC相同的MM_LOMETRIC。尽管在后续操作中可以设置MemDC的映射模式为MM_LOMETRIC,并将pDC的映射模式也设置为MM_LOMETRIC,但对同一CRect进行DPtoLP或LPtoDP坐标转换时结果仍会不同。
这背后的原因在于DC的“视口”(Viewport)和“窗口”(Window)概念的区别。DC的“视口”对应实际输出区域,度量单位为象素;而“窗口”是基于逻辑坐标系的度量单位,具体取决于当前的映射模式。
以MM_LOMETRIC模式为例,假设绘制一个20×20的矩形,单位为0.1mm。在“窗口”坐标系中,这相当于画制一个2mm×2mm的矩形。然而,“视口”坐标系的度量单位是象素,因此实际绘制的矩形大小会根据屏幕或打印机的分辨率而有所不同。
CDC类提供了GetViewportOrg()、GetWindowOrg()、GetViewportExt()和GetWindowExt()等函数来获取“视口”和“窗口”的原点坐标和扩展大小。调用DPtoLP和LPtoDP函数则是执行坐标系转换的操作。DPtoLP(从设备坐标到逻辑坐标)和LPtoDP(从逻辑坐标到设备坐标)的具体公式如下:
xViewport = (xWindow - oxWindow) × cxViewport / cxWindow + oxViewport
yViewport = (yWindow - oyWindow) × cyViewport / cyWindow + oyViewport在pDC和MemDC的例子中,尽管两者的映射模式均为MM_LOMETRIC,且在同一CRect上执行坐标转换,结果仍有所不同。pDC的“视口”大小为9917×14031象素,而MemDC的“视口”大小为1024×768象素。这种差异源于两者对“视口”和“窗口”的定义和度量单位的不同理解。
发表评论
最新留言
关于作者
