windows编程技术11GDI编程4图元文件与打印.docx

上传人:b****3 文档编号:4566054 上传时间:2023-05-07 格式:DOCX 页数:44 大小:272.35KB
下载 相关 举报
windows编程技术11GDI编程4图元文件与打印.docx_第1页
第1页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第2页
第2页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第3页
第3页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第4页
第4页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第5页
第5页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第6页
第6页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第7页
第7页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第8页
第8页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第9页
第9页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第10页
第10页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第11页
第11页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第12页
第12页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第13页
第13页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第14页
第14页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第15页
第15页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第16页
第16页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第17页
第17页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第18页
第18页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第19页
第19页 / 共44页
windows编程技术11GDI编程4图元文件与打印.docx_第20页
第20页 / 共44页
亲,该文档总共44页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

windows编程技术11GDI编程4图元文件与打印.docx

《windows编程技术11GDI编程4图元文件与打印.docx》由会员分享,可在线阅读,更多相关《windows编程技术11GDI编程4图元文件与打印.docx(44页珍藏版)》请在冰点文库上搜索。

windows编程技术11GDI编程4图元文件与打印.docx

windows编程技术11GDI编程4图元文件与打印

第11章GDI编程4—图元文件与打印

图元文件是一种矢量图形文件,用于绘图指令序列的文件存储和播放再现。

与点阵图像相比,图形文件所占的空间小,且可任意缩放而不产生马赛克效应,但是绘制图形需要一定的时间。

图元文件还可用于交互绘图中的图形重绘和图形软件中的图元编辑。

GDI除了支持图形的屏幕绘制外,也支持图形的打印输出。

使用传统的API进行Windows的打印编程,异常复杂和艰难。

而MFC对打印功能的封装,大大简化了程序员的打印编程工作。

本章将对使用MFC进行图元文件和打印编程的具体方法分别做一些简单介绍。

11.1图元文件

GDI从一开始就支持(图)元文件(metafile),早期(1985年起)的版本为WMF(WindowsMetaFile,视窗元文件),主要针对Win16(Win3.x),后来(1990年起)也支持Win32(Win95/98/Me)。

以后(1993年)随WindowsNT推出了改进的图元文件版本——EMF(EnhancedWindowsMetaFile,增强型视窗元文件),只支持Win32(Win95/98/Me/NT/2000/XP/Vista/7)。

现在(2001年起)又随WindowsXP和GDI+推出了加强型图元文件EMF——EMF+,可以同时支持GDI和GDI+。

表11-1图元文件所支持的GDI类型

元文件类型

Win16GDI

Win32GDI

Win32/64GDI+

WMF

×

EMF

×

×

EMF+

×

本节只介绍GDI中的图元文件格式WMF和EMF,重点介绍在MFC中使用图元文件。

至于GDI+中的图元文件格式EMF+和如何在GDI+编程中使用图元文件及其相关类,将在14.4节中介绍。

11.1.1图元文件格式

下面分别介绍WMF和EMF的具体文件格式。

1.WMF文件格式

●元文件结构——WMF文件由文件头和若干元文件记录组成,参见图11-1。

视窗元文件头

元文件记录

……

图11-1WMF的文件结构

●元文件头——WMF的文件头用结构METAHEADER定义:

typedefstructtagMETAHEADER{

WORDmtType;//元文件类型:

内存=0、磁盘文件=1

WORDmtHeaderSize;//文件头大小的字数

WORDmtVersion;//系统的版本号:

支持DIB=0x0300、不支持DIB=0x0100

DWORDmtSize;//文件大小的字数

WORDmtNoObjects;//同时存在于元文件内的最大对象数

DWORDmtMaxRecord;//元文件中最大记录的字大小

WORDmtNoParameters;//保留字段

}METAHEADER;

●元文件记录——WMF的元文件记录用结构METARECORD定义:

typedefstructtagMETARECORD{

DWORDrdSize;//记录大小的字数

WORDrdFunction;//功能/函数号(记录类型META_XXX)

WORDrdParm[1];//函数参数数组,逆序排列

}METARECORD;

WMF中的图元文件记录类型共有67种,包含所有的绘图设置和操作(DC函数),例如:

设置二元光栅操作(符号常量META_SETROP2,对应数值0x0104)、绘制矩形(META_RECTANGLE,0x041B)和输出文本(META_TEXTOUT,0x0521)等。

2.EMF文件格式

●元文件结构——EMF文件由文件头、可选的描述串和调色板、及若干元文件记录组成,参见图11-2。

增强型元文件头

[描述串]

[调色板]

元文件记录

……

图11-2EMF的文件结构

●元文件头——EMF的文件头用结构ENHMETAHEADER定义(比WMF的复杂得多):

typedefstructtagENHMETAHEADER{

DWORDiType;//记录类型,必须=EMR_HEADER(=1)

DWORDnSize;//结构的字节大小,可能>sizeof(ENHMETAHEADER)

RECTLrclBounds;//边界矩形(设备单位,含右边和底边)

RECTLrclFrame;//边界矩形(0.01毫米单位HIMETRIC,含右边和底边)

DWORDdSignature;//签名,必须=ENHMETA_SIGNATURE(=0x464D4520)

DWORDnVersion;//元文件版本,当前=0x10000

DWORDnBytes;//元文件的字节大小

DWORDnRecords;//元文件中的记录数

WORDnHandles;//元文件句柄表中的句柄数(第0个句柄被保留)

WORDsReserved;//保留,必须=0

DWORDnDescription;//描述字符数组中的字符数,无描述串时必须设为0

DWORDoffDescription;//描述串相对于文件头开始处的偏移量,无描述串时必须设为0

DWORDnPalEntries;//元文件内调色板中的表项数

SIZELszlDevice;//以像素为单位的参考设备分辨率

SIZELszlMillimeters;//以毫米为单位的参考设备分辨率

#if(WINVER>=0x0400)//Win95/WinNT4.0以上

DWORDcbPixelFormat;//像素格式,无像素格式设置时=0、

//开始设置为DC时=size0f(PIXELFORMATDESCRIPTOR)、

//有多个单像素格式设置时=指向最后一个像素格式头的指针

DWORDoffPixelFormat;//像素格式的偏移量

DWORDbOpenGL;//元文件中是否包含OpenGL记录

#endif/*WINVER>=0x0400*/

#if(WINVER>=0x0500)//Win98/Win2000以上

SIZELszlMicrometers;//以微米表示的参考设备大小

#endif/*WINVER>=0x0500*/

}ENHMETAHEADER;

其中:

typedefstruct_RECTL{LONGleft;LONGtop;LONGright;LONGbottom;}RECTL;

typedefstructtagSIZE{LONGcx;LONGcy;}SIZE;typedefSIZESIZEL;

●元文件记录——EMF的元文件记录用结构ENHMETARECORD定义(与WMF的METARECORD类似,只是交换了大小和类型的顺序):

typedefstructtagENHMETARECORD{

DWORDiType;//记录类型(功能/函数号EMR_XXX)

DWORDnSize;//记录的字节大小

DWORDdParm[1];//传递给GDI函数的参数数组

}ENHMETARECORD;

EMF中的图元文件记录类型共有121种(几乎是WMF的两倍),包含Win32GDI的所有绘图设置和操作,还包含若干兼容16位GDI的DC函数。

例如:

设置二元光栅操作(符号常量EMR_SETROP2,对应数值20)、绘制矩形(EMR_RECTANGLE,43)、输出文本(EMR_EXTTEXTOUTW,84)和绘制多边形(EMR_POLYPOLYGON/EMR_POLYPOLYGON16,8/91)等。

11.1.2图元文件的MFC编程

可以直接利用WindowsSDK中的有关API函数进行图元文件编程,但是限于篇幅,这里只介绍如何利用MFC的CMetaFileDC类进行图元文件的编程。

CMetaFileDC是CDC的派生类,是对图元文件功能的封装。

CMetaFileDC类很简单,只有一个默认构造函数——CMetaFileDC、两个具体创建函数——Create(创建WMF)和CreateEnhanced(创建EMF)、两个关闭函数——Close(关闭WMF)和CloseEnhanced(关闭EMF),其他主要是使用其父类CDC的成员函数。

1.创建CMetaFileDC对象

创建CMetaFileDC对象分两步进行,首先调用CMetaFileDC类的唯一(默认)构造函数来构造一个空对象,然后再调用该类的Create成员函数来创建一个WMF图元文件对象、或调用CreateEnhanced成员函数来创建一个EMF图元文件对象。

下面是这些函数的原型:

CMetaFileDC();

BOOLCreate(LPCTSTRlpszFilename=NULL);

BOOLCreateEnhanced(CDC*pDCRef,LPCTSTRlpszFileName,

LPCRECTlpBounds,LPCTSTRlpszDescription);

其中:

●pDCRef——参考DC,一般取为当前视图类的指针。

为NULL时,使用当前显示设备作为参考DC。

●lpszFilename——图元文件名串的指针,如果为NULL,则创建内存图元文件。

●lpBounds——边界矩形(单位是0.01毫米),可以是RECT结构或CRect对象的指针。

为NULL时,取包含用户图形的最小矩形。

●lpszDescription——描述字符串,一般包含应用程序名和图名,也可以为NULL。

例如:

CMetaFileDCmetaDC;//构造元文件DC空对象

//metaDC.Create(NULL);//创建内存WMF元文件DC

//metaDC.Create(L"test.wmf");//创建WMF元文件DC

//创建内存EMF元文件DC

//metaDC.CreateEnhanced(NULL,NULL,NULL,NULL);

//获取屏幕大小

HDChdcRef=GetDC()->m_hDC;

intiWidthMM=GetDeviceCaps(hdcRef,HORZSIZE);//屏幕宽(毫米)

intiHeightMM=GetDeviceCaps(hdcRef,VERTSIZE);//屏幕高(毫米)

intiWidthPels=GetDeviceCaps(hdcRef,HORZRES);//屏幕宽(像素)

intiHeightPels=GetDeviceCaps(hdcRef,VERTRES);//屏幕高(像素)

//获取客户区大小,并将像素坐标转换为0.01毫米坐标

RECTrect;

GetClientRect(&rect);//像素坐标

rect.right=(rect.right*iWidthMM*100)/iWidthPels;

rect.bottom=(rect.bottom*iHeightMM*100)/iHeightPels;

metaDC.CreateEnhanced(GetDC(),L"test.emf",&rect,

L"MFCDrawMixGraphics");//创建EMF元文件DC

2.添加绘图记录

因为CMetaFileDC是CDC的派生类,可以像用普通CDC对象一样地,使用CMetaFileDC来设置绘图环境和执行绘图指令。

例如:

metaDC.SelectObject(pLinePen);

metaDC.MoveTo(point1);

metaDC.LineTo(point2);

……

3.播放图元文件

播放图元文件是指通过重画图元文件中的所有绘图记录(执行对应的绘图函数指令)来再现整个图形。

可以用CMetaFileDC和CDC类的相关成员函数来播放本程序所创建的图元文件,但是需要用WindowsSDK的相关图元函数才能装入和播放磁盘上的图元文件,还可以用CImage类来装入和显示磁盘上的图元文件。

1)播放本程序所创建的图元文件

为了播放在程序中创建的图元文件,必须先关闭图元文件DC,这可交由CMetaFileDC类的成员函数Close或CloseEnhanced来完成,然后用它们的返回值(图元文件的句柄)来调用CDC类的成员函数PlayMetaFile来播放图元文件。

这些函数的原型如下:

HMETAFILEClose();//关闭WMF图元文件DC,出错返回NULL

HENHMETAFILECloseEnhanced();//关闭EMF图元文件DC,出错返回NULL

BOOLPlayMetaFile(HMETAFILEhMF);//播放WMF图元文件

//播放EMF图元文件

BOOLPlayMetaFile(HENHMETAFILEhEnhMetaFile,LPCRECTlpBounds);

由于CDC类的两个PlayMetaFile函数不太听话,可能需要使用下面的SDK函数来代替:

BOOLPlayMetaFile(HDChdc,HMETAFILEhmf);//播放WMF图元文件

BOOLPlayEnhMetaFile(//播放EMF图元文件

HDChdc,//DC句柄

HENHMETAFILEhemf,//增强型图元文件的句柄

CONSTRECT*lpRect//边界矩形(逻辑单位)

);

其中,lpBounds为边界矩形,逻辑单位(默认为像素)。

在使用完图元文件句柄后,应该调用SDK函数:

BOOLDeleteMetaFile(HMETAFILEhmf);

来删除它(对磁盘元文件它只删除句柄,对内存元文件它会删除内存中元文件的所有内容)。

例如:

HENHMETAFILEhemf=metaDC.CloseEnhanced();

//pDC->PlayMetaFile(hemf,&rectPixel);//此函数不听话

PlayEnhMetaFile(GetDC()->m_hDC,hemf,&rect1);//SDK函数

DeleteEnhMetaFile(hemf);

2)装入和播放磁盘上的图元文件

MFC所封装的图元文件DC类CMetaFileDC,只是用于创建新图元文件,并添加绘图记录。

虽然,可以播放自己创建的图元文件,但是却不能播放已经存在的磁盘图元文件。

解决办法有两个:

●使用SDK函数来装入和播放图元文件。

可以利用SDK函数GetEnhMetaFile和PlayEnhMetaFile来装入和播放磁盘上的图元文件,这两个函数的原型为:

HENHMETAFILEGetEnhMetaFile(LPCTSTRlpszMetaFile);//装入图元文件

BOOLPlayEnhMetaFile(//显示图元文件

HDChdc,//DC句柄

HENHMETAFILEhemf,//增强型图元文件的句柄

CONSTRECT*lpRect//边界矩形(逻辑单位)

);

UINTGetEnhMetaFileHeader(//获取元文件头

//缓冲区参数为NULL时返回缓冲区大小,否则返回拷贝到缓冲区中的字节数

HENHMETAFILEhemf,//增强型图元文件的句柄

UINTcbBuffer,//缓冲区大小

LPENHMETAHEADERlpemh//数据缓冲区

);

例如:

HENHMETAFILEhemf=GetEnhMetaFile(L"test.emf");

UINTsize=GetEnhMetaFileHeader(hemf,0,NULL);

ENHMETAHEADER*emHeader=(ENHMETAHEADER*)malloc(size);

GetEnhMetaFileHeader(hemf,size,emHeader);

RECTLrectl=emHeader->rclBounds;//边界矩形

RECTrect={rectl.left,rectl.top,rectl.right,rectl.bottom};

PlayEnhMetaFile(GetDC()->m_hDC,hemf,&rect);

DeleteEnhMetaFile(hemf);

●使用CImage类来装入和播放图元文件。

由于CImage类所支持的图像文件格式中包含了WMF和EMF两种图元文件:

⏹ImageFormatWMF——WMF(WindowsMetaFile,视窗元文件)。

⏹ImageFormatEMF——EMF(EnhancedMetaFile,增强型元文件)。

所以可以利用来装入和播放磁盘上的图元文件,例如:

CImageimg;

img.Load(L"test.emf");

img.Draw(pDC->m_hDC,0,0);

4.动态重放图元文件

只有在OnDraw函数中绘制的图形才能被自动重绘。

而鼠标交互绘图程序中,在左鼠标键松开的响应函数OnLButtonUp中所绘制的图形,并不能被自动重绘。

现在我们可以用图元文件来解决这个问题,下面是相关的例子代码,过程参见图11-3。

图11-3利用图元文件在视图类中实现自动重绘的主要步骤

●在视图类中定义类变量:

RECTrectHimm,rectPixel;

CMetaFileDCmetaDC;

●在视图类的初始化函数OnInitialUpdate中,创建EMF元文件DC:

//获取参考HDC与屏幕大小

HDChdcRef=GetDC()->m_hDC;

intiWidthMM=GetDeviceCaps(hdcRef,HORZSIZE);//屏幕宽(毫米)

intiHeightMM=GetDeviceCaps(hdcRef,VERTSIZE);//屏幕高(毫米)

intiWidthPels=GetDeviceCaps(hdcRef,HORZRES);//屏幕宽(像素)

intiHeightPels=GetDeviceCaps(hdcRef,VERTRES);//屏幕高(像素)

//计算屏幕大小的HIMETRIC单位(0.01毫米)值和逻辑单位(像素)值

rectHimm.left=0;

rectHimm.top=0;

rectHimm.right=iWidthMM*100;

rectHimm.bottom=iHeightMM*100;

rectPixel.left=0;

rectPixel.top=0;

rectPixel.right=iWidthPels;

rectPixel.bottom=iHeightPels;

//创建内存EMF文件DC(也可将首个NULL改成文件的路径名串

//[如L"draw.emf"]来创建磁盘图元文件)

metaDC.CreateEnhanced(GetDC(),NULL,&rectHimm,NULL);

●在视图类的OnLButtonUp等函数中,利用图元文件DC,向图元文件添加各种绘图记录。

如:

metaDC.SelectObject(pLinePen);

metaDC.MoveTo(point1);

metaDC.LineTo(point2);

……

●在视图类的OnDraw函数中,关闭元文件DC,同时获取元文件句柄,播放元文件。

然后再创建新的元文件DC,并将老元文件中现有的记录,通过新的元文件DC的播放,加入到新元文件中,最后删除老元文件的句柄。

如:

//关闭元文件DC,获取句柄

HENHMETAFILEhemf=metaDC.CloseEnhanced();

//播放元文件(SDK函数)

PlayEnhMetaFile(GetDC()->m_hDC,hemf,&rectPixel);

//pDC->PlayMetaFile(hemf,&rectPixel);//此函数不太听话

//创建新元文件DC

metaDC.CreateEnhanced(GetDC(),NULL,&rectHimm,NULL);

//将老元文件的纪录加入到新元文件中

metaDC.PlayMetaFile(hemf,&rectPixel);

DeleteEnhMetaFile(hemf);//删除元文件句柄(SDK函数)

●可以在视图类的某个消息响应函数中利用SDK函数CopyMetaFile或CopyEnhMetaFile来将内存中的图元文件保存到磁盘文件中。

这两个函数的原型为:

HMETAFILECopyMetaFile(HMETAFILEhmfSrc,LPCTSTRlpszFile);

HENHMETAFILECopyEnhMetaFile(HENHMETAFILEhemfSrc,LPCTSTRlpszFile);

例如:

//关闭元文件,获取句柄

HENHMETAFILEhemf=CloseEnhMetaFile(hdcMeta);

CopyEnhMetaFile(hemf,L"draw.emf");//复制到磁盘文件(SDK函数)

DeleteEnhMetaFile(hemf);//删除元文件句柄(SDK函数)

●最后,在视图类的析构函数中,关闭图元文件DC并删除图元文件句柄。

例如:

HENHMETAFILEhemf=metaDC.CloseEnhanced();

DeleteEnhMetaFile(hemf);

5.播放图元文件中的记录

CMetaFileDC类和其父类CDC中都没有播放图元文件记录的成员函数,但是可以利用CMetaFileDC类的Close或CloseEnhanced成员函数所获得的图元文件句柄,再调用SDK的有关函数PlayEnhMetaFileRecord、EnumEnhMetaFile和EnhMetaFileProc等来绘制图元文件中的指定记录。

这些函数的原型为:

BOOLPlayEnhMetaFileRecord(//显示元文件中的记录

HDChdc,//DC句柄

LPHANDLETABLElpHandletable,//元文件句柄表

CONSTENHMETARECORD*lpEnhMetaRecord,//元文件记录

UINTnHandles//句柄计数

);

BOOLEnumEnhMetaFile(//枚举图元

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 职业教育 > 职业技术培训

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2