关于windows编程技术11GDI编程4图元文件与打印.doc
《关于windows编程技术11GDI编程4图元文件与打印.doc》由会员分享,可在线阅读,更多相关《关于windows编程技术11GDI编程4图元文件与打印.doc(30页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第11章 GDI编程4图元文件与打印图元文件是一种矢量图形文件,用于绘图指令序列的文件存储和播放再现。与点阵图像相比,图形文件所占的空间小,且可任意缩放而不产生马赛克效应, 但是绘制图形需要一定的时间。图元文件还可用于交互绘图中的图形重绘和图形软件中的图元编辑。GDI除了支持图形的屏幕绘制外,也支持图形的打印输出。使用传统的API进行Windows的打印编程,异常复杂和艰难。而MFC对打印功能的封装,大大简化了程序员的打印编程工作。本章将对使用MFC进行图元文件和打印编程的具体方法分别做一些简单介绍。11.1 图元文件GDI从一开始就支持(图)元文件(metafile),早期(1985年起)的
2、版本为WMF(Windows MetaFile,视窗元文件),主要针对Win16(Win3.x),后来(1990年起)也支持Win32(Win95/ 98/Me)。以后(1993年)随Windows NT推出了改进的图元文件版本EMF(Enhanced Windows MetaFile,增强型视窗元文件),只支持Win32(Win95/98/Me/NT/2000/XP/Vista/7)。现在(2001年起)又随Windows XP和GDI+推出了加强型图元文件EMFEMF+,可以同时支持GDI和GDI+。表11-1 图元文件所支持的GDI类型元文件类型Win16 GDIWin32 GDIWin
3、32/64 GDI+WMFEMFEMF+本节只介绍GDI中的图元文件格式WMF和EMF,重点介绍在MFC中使用图元文件。至于GDI+中的图元文件格式EMF+和如何在GDI+编程中使用图元文件及其相关类,将在14.4节中介绍。11.1.1 图元文件格式下面分别介绍WMF和EMF的具体文件格式。1WMF文件格式l 元文件结构WMF文件由文件头和若干元文件记录组成,参见图11-1。视窗元文件头元文件记录图11-1 WMF的文件结构l 元文件头WMF的文件头用结构METAHEADER定义:typedef struct tagMETAHEADER WORD mtType; / 元文件类型:内存=0、磁盘
4、文件=1 WORD mtHeaderSize; / 文件头大小的字数 WORD mtVersion; / 系统的版本号:支持DIB=0x0300、不支持DIB=0x0100 DWORD mtSize; / 文件大小的字数 WORD mtNoObjects; / 同时存在于元文件内的最大对象数 DWORD mtMaxRecord; / 元文件中最大记录的字大小 WORD mtNoParameters; / 保留字段 METAHEADER;l 元文件记录WMF的元文件记录用结构METARECORD定义:typedef struct tagMETARECORD DWORD rdSize; / 记录大
5、小的字数 WORD rdFunction; / 功能/函数号(记录类型META_XXX) WORD rdParm1; / 函数参数数组,逆序排列 METARECORD;WMF中的图元文件记录类型共有67种,包含所有的绘图设置和操作(DC函数),例如:设置二元光栅操作(符号常量META_SETROP2,对应数值0x0104)、绘制矩形(META_RECTANGLE,0x041B)和输出文本(META_TEXTOUT,0x0521)等。2EMF文件格式l 元文件结构EMF文件由文件头、可选的描述串和调色板、及若干元文件记录组成,参见图11-2。增强型元文件头描述串调色板元文件记录图11-2 EMF
6、的文件结构l 元文件头EMF的文件头用结构ENHMETAHEADER定义(比WMF的复杂得多):typedef struct tagENHMETAHEADER DWORD iType; / 记录类型,必须 = EMR_HEADER(= 1) DWORD nSize; / 结构的字节大小,可能 sizeof(ENHMETAHEADER) RECTL rclBounds; / 边界矩形(设备单位,含右边和底边) RECTL rclFrame; / 边界矩形(0.01毫米单位HIMETRIC,含右边和底边) DWORD dSignature; / 签名,必须 = ENHMETA_SIGNATURE(
7、= 0x464D4520) DWORD nVersion; / 元文件版本,当前 = 0x10000 DWORD nBytes; / 元文件的字节大小 DWORD nRecords; / 元文件中的记录数 WORD nHandles; / 元文件句柄表中的句柄数(第0个句柄被保留) WORD sReserved; / 保留,必须 = 0 DWORD nDescription; / 描述字符数组中的字符数,无描述串时必须设为0 DWORD offDescription; / 描述串相对于文件头开始处的偏移量,无描述串时必须设为0 DWORD nPalEntries; / 元文件内调色板中的表项数
8、 SIZEL szlDevice; / 以像素为单位的参考设备分辨率 SIZEL szlMillimeters; / 以毫米为单位的参考设备分辨率#if (WINVER = 0x0400) / Win95/WinNT4.0以上 DWORD cbPixelFormat; / 像素格式,无像素格式设置时 = 0、/ 开始设置为DC时 = size0f(PIXELFORMATDESCRIPTOR)、/ 有多个单像素格式设置时 = 指向最后一个像素格式头的指针 DWORD offPixelFormat; / 像素格式的偏移量 DWORD bOpenGL; / 元文件中是否包含OpenGL记录#endi
9、f /* WINVER = 0x0400 */#if (WINVER = 0x0500) / Win98/Win2000以上 SIZEL szlMicrometers; / 以微米表示的参考设备大小#endif /* WINVER = 0x0500 */ ENHMETAHEADER; 其中:typedef struct _RECTL LONG left; LONG top; LONG right; LONG bottom; RECTL;typedef struct tagSIZE LONG cx; LONG cy; SIZE; typedef SIZE SIZEL;l 元文件记录EMF的元文件
10、记录用结构ENHMETARECORD定义(与WMF的METARECORD类似,只是交换了大小和类型的顺序):typedef struct tagENHMETARECORD DWORD iType; / 记录类型(功能/函数号EMR_XXX) DWORD nSize; / 记录的字节大小 DWORD dParm1; / 传递给GDI函数的参数数组 ENHMETARECORD; EMF中的图元文件记录类型共有121种(几乎是WMF的两倍),包含Win32 GDI的所有绘图设置和操作,还包含若干兼容16位GDI的DC函数。例如:设置二元光栅操作(符号常量EMR_SETROP2,对应数值20)、绘制矩
11、形(EMR_RECTANGLE,43)、输出文本(EMR_ EXTTEXTOUTW,84)和绘制多边形(EMR_POLYPOLYGON /EMR_POLYPOLYGON16,8/91)等。11.1.2 图元文件的MFC编程可以直接利用Windows SDK中的有关API函数进行图元文件编程,但是限于篇幅,这里只介绍如何利用MFC的CMetaFileDC类进行图元文件的编程。CMetaFileDC是CDC的派生类,是对图元文件功能的封装。CMetaFileDC类很简单,只有一个默认构造函数CMetaFileDC、两个具体创建函数Create(创建WMF)和CreateEnhanced(创建EMF
12、)、两个关闭函数Close(关闭WMF)和CloseEnhanced(关闭EMF),其他主要是使用其父类CDC的成员函数。1创建CMetaFileDC对象创建CMetaFileDC对象分两步进行,首先调用CMetaFileDC类的唯一(默认)构造函数来构造一个空对象,然后再调用该类的Create成员函数来创建一个WMF图元文件对象、或调用CreateEnhanced成员函数来创建一个EMF图元文件对象。下面是这些函数的原型:CMetaFileDC( );BOOL Create(LPCTSTR lpszFilename = NULL);BOOL CreateEnhanced(CDC* pDCRe
13、f, LPCTSTR lpszFileName, LPCRECT lpBounds, LPCTSTR lpszDescription);其中:l pDCRef参考DC,一般取为当前视图类的指针。为NULL时,使用当前显示设备作为参考DC。l lpszFilename图元文件名串的指针,如果为NULL,则创建内存图元文件。l lpBounds边界矩形(单位是0.01毫米),可以是RECT结构或CRect对象的指针。为NULL时,取包含用户图形的最小矩形。l lpszDescription描述字符串,一般包含应用程序名和图名,也可以为NULL。例如:CMetaFileDC metaDC; / 构造
14、元文件DC空对象/ metaDC.Create(NULL); / 创建内存WMF元文件DC/ metaDC.Create(Ltest.wmf); / 创建WMF元文件DC/ 创建内存EMF元文件DC/ metaDC.CreateEnhanced(NULL, NULL, NULL, NULL);/ 获取屏幕大小HDC hdcRef = GetDC()-m_hDC; int iWidthMM = GetDeviceCaps(hdcRef, HORZSIZE); / 屏幕宽(毫米)int iHeightMM = GetDeviceCaps(hdcRef, VERTSIZE); / 屏幕高(毫米)in
15、t iWidthPels = GetDeviceCaps(hdcRef, HORZRES); / 屏幕宽(像素)int iHeightPels = GetDeviceCaps(hdcRef, VERTRES); / 屏幕高(像素)/ 获取客户区大小,并将像素坐标转换为0.01毫米坐标RECT rect;GetClientRect(&rect); / 像素坐标rect.right = (rect.right * iWidthMM * 100)/iWidthPels; rect.bottom = (rect.bottom * iHeightMM * 100)/iHeightPels; metaDC
16、.CreateEnhanced(GetDC(), Ltest.emf, &rect, LMFCDraw MixGraphics); / 创建EMF元文件DC2添加绘图记录因为CMetaFileDC是CDC的派生类,可以像用普通CDC对象一样地,使用CMetaFileDC来设置绘图环境和执行绘图指令。例如:metaDC.SelectObject(pLinePen);metaDC.MoveTo(point1); metaDC.LineTo(point2); 3播放图元文件播放图元文件是指通过重画图元文件中的所有绘图记录(执行对应的绘图函数指令)来再现整个图形。可以用CMetaFileDC和CDC类
17、的相关成员函数来播放本程序所创建的图元文件,但是需要用Windows SDK的相关图元函数才能装入和播放磁盘上的图元文件,还可以用CImage类来装入和显示磁盘上的图元文件。1)播放本程序所创建的图元文件为了播放在程序中创建的图元文件,必须先关闭图元文件DC,这可交由CMetaFileDC类的成员函数Close或CloseEnhanced来完成,然后用它们的返回值(图元文件的句柄)来调用CDC类的成员函数PlayMetaFile来播放图元文件。这些函数的原型如下:HMETAFILE Close( ); / 关闭WMF图元文件DC,出错返回NULLHENHMETAFILE CloseEnhanc
18、ed( ); / 关闭EMF图元文件DC,出错返回NULLBOOL PlayMetaFile(HMETAFILE hMF); / 播放WMF图元文件/ 播放EMF图元文件BOOL PlayMetaFile(HENHMETAFILE hEnhMetaFile, LPCRECT lpBounds);由于CDC类的两个PlayMetaFile函数不太听话,可能需要使用下面的SDK函数来代替:BOOL PlayMetaFile(HDC hdc, HMETAFILE hmf); / 播放WMF图元文件BOOL PlayEnhMetaFile( / 播放EMF图元文件 HDC hdc,/ DC句柄 HEN
19、HMETAFILE hemf,/ 增强型图元文件的句柄 CONST RECT *lpRect/ 边界矩形(逻辑单位));其中,lpBounds为边界矩形,逻辑单位(默认为像素)。在使用完图元文件句柄后,应该调用SDK函数:BOOL DeleteMetaFile(HMETAFILE hmf);来删除它(对磁盘元文件它只删除句柄,对内存元文件它会删除内存中元文件的所有内容)。例如:HENHMETAFILE hemf = metaDC.CloseEnhanced();/ pDC-PlayMetaFile(hemf, &rectPixel); / 此函数不听话PlayEnhMetaFile(GetDC
20、()-m_hDC, hemf, &rect1); / SDK函数DeleteEnhMetaFile(hemf);2)装入和播放磁盘上的图元文件MFC所封装的图元文件DC类CMetaFileDC,只是用于创建新图元文件,并添加绘图记录。虽然,可以播放自己创建的图元文件,但是却不能播放已经存在的磁盘图元文件。解决办法有两个:l 使用SDK函数来装入和播放图元文件。可以利用SDK函数GetEnhMetaFile和PlayEnhMetaFile来装入和播放磁盘上的图元文件,这两个函数的原型为:HENHMETAFILE GetEnhMetaFile(LPCTSTR lpszMetaFile); / 装入
21、图元文件BOOL PlayEnhMetaFile( / 显示图元文件 HDC hdc,/ DC句柄 HENHMETAFILE hemf,/ 增强型图元文件的句柄 CONST RECT *lpRect/ 边界矩形(逻辑单位));UINT GetEnhMetaFileHeader( / 获取元文件头/ 缓冲区参数为NULL时返回缓冲区大小,否则返回拷贝到缓冲区中的字节数 HENHMETAFILE hemf,/ 增强型图元文件的句柄 UINT cbBuffer,/ 缓冲区大小 LPENHMETAHEADER lpemh/ 数据缓冲区);例如:HENHMETAFILE hemf = GetEnhMet
22、aFile(Ltest.emf);UINT size = GetEnhMetaFileHeader(hemf, 0, NULL);ENHMETAHEADER *emHeader = (ENHMETAHEADER *)malloc(size);GetEnhMetaFileHeader(hemf, size, emHeader);RECTL rectl = emHeader-rclBounds; / 边界矩形RECT rect = rectl.left, rectl.top, rectl.right, rectl.bottom;PlayEnhMetaFile(GetDC()-m_hDC, hemf
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 关于 windows 编程 技术 11 GDI 文件 打印
限制150内