目录
前言
本篇文章介绍图形和文本输出
一、图形与文本
1.1 图形设备接口和设备环境
1.1.1 图形设备接口
Windows提供了一个称为图形设备接口(Graphics Device Interface,GDI)的抽象接口。
GDI负责管理用户绘图操作时功能的转换,实现设备无关性。
应用程序可以使用GDI创建3种类型的图形输出:矢量图形、光栅图形和文本。
1.矢量图形
矢量图形输出是指画线和填充图形,包括点、直线、曲线、多边形、扇形和矩形等。
2.光栅图形
光栅图形输出是指光栅图形函数对以位图形式存储的数据进行操作,它包括各种位图和图标的输出。
3.文本
与DOS字符方式下输出文本不同,Windows中的文本是按图形方式输出的。
1.1.2 设备环境
Windows应用程序的输出不直接面向显示器或打印机等物理设备,而是面向一个称之为设备环境(Device Context,DC)的虚拟逻辑设备。
设备环境DC,也称设备描述表或设备上下文。它是由GDI创建、用来代表设备连接的数据结构。
DC的主要功能有以下几种:
(1) 允许应用程序使用一个输出设备。
(2) 提供Windows应用程序、设备驱动和输出设备之间的连接。
(3) 保存当前信息,例如当前的画笔、画刷、字体和位图等图形对象及其属性,以及颜色和背景等影响图形输出的绘图模式。
(4) 保存窗口剪切区域,限制程序输出到输出设备中窗口覆盖的区域。
1.1.3 设备环境类
1.设备环境类CDC及其功能
2.设备环境类CDC的一些常用函数
1.1.4 颜色的设置
Windows用COLORREF类型的数据存放颜色,它是一个32位整数。
任何一种颜色都是由红、绿、蓝3种基本颜色组成的,COLORREF类型数据的低位字节存放红色强度值,第2个字节存放绿色强度值,第3个字节存放蓝色强度值,高位字节为0,每一种颜色分量的取值范围为0~255。
MFC提供了RGB宏,用于设置颜色,其使用形式为:
RGB(byRed,byGreen,byBlue)
其中参数byRed、byGreen和byBlue分别表示红、绿、蓝分量值(范围0~255)。
下表列出了一些常用颜色的RGB值。
1.1.5 获取设备环境
1.传统的SDK获取设备环境的方法
采用SDK方法编程,获取设备环境的方法有两种:
(1)在WM_PAINT消息处理函数中通过调用API函数BeginPaint( )获取设备环境,在消息处理函数返回前调用API函数EndPaint( )释放设备环境。
(2)如果绘图操作不是在WM_PAINT消息处理函数中,需要通过调用API函数GetDC( )获取设备环境,调用API函数ReleaseDC( )释放设备环境。
2.MFC应用程序获取设备环境的方法
在一个MFC应用程序中获得DC的方法主要有两种:
(1)接受一个参数为指向CDC对象的指针;
(2)声明一个 MFC设备环境类的对象,并使用this指针为该对象赋值。
1.2 GDI对象类CGdiObject
GDI对象是Windows图形设备接口的抽象绘图工具。除了画笔和画刷,其他GDI对象还包括字体、位图和调色板。
MFC对GDI对象进行了很好的封装,提供了封装GDI对象的类,如CPen、CBrush、CFont、CBitmap和CPalette等,这些类都是GDI对象类CGdiObject的派生类,它们的继承关系如图所示。
1.3 画笔和画刷的使用
1.3.1 使用库存(stock)对象
选择库存对象:
- 使用SelectStockObject( )函数
- 如果选择成功,函数SelectStockObject( )将返回以前的CGdiObject对象的指针。
- 利用CGdiObject类的成员函数CreateStockObject( )将GDI对象设置成指定的库存对象。
- 声明一个GDI对象,调用成员函数SelectObject( ),将与库存对象关联的GDI对象选入当前的设备环境,代码如下所示。
CBrush *BrushOld,BrushNew;
//关联库存画刷对象
BrushNew.CreateStockObject(BLACK_BRUSH);
BrushOld=pDC->SelectObject(&BrushNew);
1.3.2 创建和使用自定义画笔
如果要在设备环境中使用自己的画笔绘图,首先需要创建一个指定风格的画笔,然后选择所创建的画笔,最后还原画笔。
1.创建画笔
创建画笔的方法有两种:
(1)定义画笔对象时直接创建
CPen PenNew(PS_DASH,1,RGB(255,0,0));
笔的样式 线的宽度 线的颜色
(2)先定义一个没有初始化的画笔对象,再调用CreatePen( )函数创建指定画笔。
CPen Pen;
pen.CreatePen(PS_DASH,1,RGB(255,0,0));
2.选择创建的画笔
调用CDC类的成员函数SelectOject( ),将创建的画笔选入当前设备环境。选择新的画笔时应该保存以前的画笔对象。
例如:
3.还原画笔
绘图完成后,调用CDC类的成员函数SelectOject( )恢复设备环境以前的画笔工具,并通过调用CGdiObject类的成员函数DeleteObject( )来删除画笔,释放GDI对象所占的内存资源。
1.3.3 创建和使用自定义画刷
包括三个步骤:
- 创建画刷:先构造一个没有初始化的CBrush画刷对象,再调用CBrush类的初始化成员函数创建定制的画刷工具。类型不同的画刷使用不同的函数实现。
- 选择创建的画刷
- 还原画刷。
CBrush类提供的创建函数中常用的有以下几个:
(1)创建指定颜色的实心画刷函数CreateSolidBrush( )
其原型为:
(2)创建阴影画刷函数CreateHatchBrush( )
其原型为:
Bool CreateHatchBrush( int nIndex,COLORREF crColor);
参数nIndex用于指定阴影样式,它的值见下表。
(3)创建位图画刷函数CreatePatternBrush( )
采用8像素×8像素的位图。
1.4 处理文本
1.4.1 设置文本显示属性
在默认情况下输出文本时,字体颜色是黑色,背景颜色是白色,背景模式为不透明模式。
通过调用CDC类成员函数重新设置字体颜色、背景颜色和文本对齐方式等文本显示属性,下表是文本属性显示的常用函数。
1.设置背景模式
SetBkMode( )函数原型为:
int SetBkMode(int nBkMode);
其中,nBkMode指定背景模式,其值是OPAQUE(不透明)或TRANSPARENT(透明)。
2.设置文本对齐方式
SetTextAlign( )函数改变文本对齐方式:
UINT SetTextAlign(UINT nFlags);
其中,nFlag为下表中列出的标志的组合。
1.4.2 设置字体
字体也是一种GDI对象,字体对象的创建、选择、使用和删除的步骤与其他GDI对象类似。
CFont类提供的创建函数中常用的有以下几个:
1.CreatePointFont( )
BOOL CreatePointFont(int nPointSize,
LPCTSTR lpszFaceName,CDC* pDC=NULL);
参数说明:
nPointSize:字体大小,以1/10磅为单位;
lpszFaceName:创建字体对象所使用的字体名称;
pDC:指向一个设备环境对象。
2.CreateFontIndirect( )
BOOL CreateFontIndirect(const LOGFONT *lpLogFont);
参数lpLogFont为指向LOGFONT结构的指针。LOGFONT结构用来说明一种字体的所有属性。
3.CreateFont( )
该函数包括大量参数,其原型为:
BOOL CreateFont(
int nHeight;
int nWidth;
int nEscapement;
int nOrientation;
int nWeight;
BYTE bItalic;
BYTE bUnderline;
BYTE cStrikeOut;
BYTE nCharSet;
BYTE nOutPreclsion;
BYTE nClipPrecision;
BYTE nQuality;
BYTE nPitchAndFamily;
LPCTSTR lpszFacename;
)
可以选择库存字体来重新设置字体。当选择库存字体作为文本输出的字体时,无须创建字体对象,只需简单地调用成员函数CDC::SelectStockObject( ),将库存字体对象选入设备环境。
1.4.3 格式化文本
文本的显示是以像素为单位,在绘制任何文本之前,需要精确地知道文本的详细属性,如高度、宽度等,用来计算文本坐标。
CDC类提供了几个文本测量成员函数:
1.GetTextExtent( )
获得所选字体中指定字符串的宽度和高度。
CSize GetTextExtent(LPCTSTR lpszString,int nCount);
其中,1pszString是字符串的指针,nCount是所包括的字符数。
返回值CSize是包含两个成员的结构,cx是字符串的宽度,cy是字符串的高度。
2.GetTextMetrics( )
获得当前字体TEXTMETRIC结构的数据。
BOOL GetTextMetric(const TEXTMETRIC *lpTextMetric);
参数lpTextMetric为指向结构TEXTMETRIC的指针。TEXTMETRIC结构用来描述字体信息。
1.4.4 常用文本输出函数
MFC CDC类中常用的文本输出函数有以下几种:
1.TextOut( )
该函数使用当前设定的字体、颜色、对齐方式在指定位置上输出文本。
vitual BOOL TextOut(int x,int y,LPCTSTR lpszString,int nCount);
或:
BOOL TextOut(int x, int y,const Cstring &str);
其中,参数(x,y)指定输出文本串的开始位置;参数lpszString和str为输出的文本串;参数nCount指定文本串的长度。
2.DrawText( )
该函数在给定的矩形区域内输出文本,并可调整文本在矩形区域内的对齐方式以及对文本行进行换行处理等。函数原型为:
Virtual int DrawText(LPCTSTR lpszString, int nCount,LPRECT lpRect,UINT nFormat);
或:
int DrawText(const CString&str,LPRECT lpRect,UINT nFormat);
其中,参数lpszString和str为要输出的文本串,可以使用换行符“\n”;参数nCount指定文本串长度;参数lpRect指定用于显示文本串的矩形区域;参数nFormat指定如何格式化文本串。
3.ExtTextOut( )
该函数的功能与TextOut( )相似,但可以根据指定的矩形区域裁剪文本串,并调整字符间距。函数原型为:
Virtual BOOL ExtTextOut(int x,int y,UINT nOptions,LPCRECT lpRect,LPCTSTR lpszString,UINT nCount,LPINT lpDxWidths);
或:
BOOL ExtTextOut(int x, int y,UINT nOptions,LPCRECT lpRect,
const CString &str,LPINT lpDxWidths);
4.TabbedTextOut( )
该函数的功能与TextOut( )相似,但可按指定的制表间距扩展制表符。
1.5 位图
位图是一个由位构成的图像,它是由一系列0和1排列而成的点阵结构。
Windows支持两种不同形式的位图:
- 设备相关位图(Device Dependent Bitmap,DDB)
- 设备无关位图(Device Independent Bitmap,DIB)
1.5.1 设备相关图(DDB)和设备无关图(DIB)
DDB又称GDI位图,它依赖于具体设备,只能存在于内存中。
DIB是不依赖硬件的位图,因为它包含了创建DIB位图时所在设备的颜色格式、分辨率和调色板等信息。
DIB位图不能直接显示,需要先转换为与设备相关的格式,再由具体的设备显示。DIB位图通常以BMP后缀名的文件形式存储在磁盘中,或者以资源的形式存在于EXE或DLL文件中。
1.5.2 位图操作函数
MFC提供了大量的类和函数来处理位图的操作。
1.创建DDB函数
BOOL LoadBitmap(LPCTSTR lpszResourceName);
BOOL LoadBitmap(UINT nlDResource);
其中,参数lpszResourceName或nlDResouree分别为位图资源名称或位图资源标识。
该函数从资源中装入一幅位图,若载入成功,则返回值为真,否则返回值为假。
BOOL CreateCompatibleBitmap(CDC* pDC,int nWidth,int nHeight);
其中参数pDC指向一个设备环境,参数nWidth和nHeight以像素为单位,用来指定位图的宽度和高度。
该函数创建一个与指定设备环境兼容的DDB。若创建成功,函数返回值为真,否则为假。
2.获取位图信息函数
int GetBitmap(BITMAP* pBitMap);
该函数用来获取与DDB有关的信息,参数pBitMap是BITMAP结构的指针。
3.输出位图函数
BOOL BitBlt(int x,int y,int nWidth,int nHeight,CDC* pSrcDC,int xSrc,int ySrc,DWORD dwRop);
该函数共有8个参数:
x、y、nWidth、nHeight:定义当前设备环境的复制区域;pSrcDC:为指向原设备环境对象的指针;
xSrc、ySrc:为原位图的左上角坐标;
dwRop:定义了进行复制时的光栅操作方式。
BOOL PatBlt(int x,int y,int nWidth,int nHeight,DWORD dwRop);
其中,参数DwRop确定画刷类型。
该函数是用当前画刷填充一个矩形。并不是所有的设备环境都支持该函数,使用该函数之前需要对设备环境使用 GetDeviceCaps进行判断,以便确定是否支持该函数调用。
BOOL StretchBlt(int x,int y,int nWidth,int nHeight,CDC* pSrcDC,int xSrc,int ySrc,int nSrcWidth,int nSrcHeight,
DWORD dwRop);
其中,除了参数nSrcWidth和nSrcHeight表示目标图像新的宽度与高度之外,其他参数x、y、nWidth和nHeight等的含义与BitBlt函数中的同名参数相同。
该函数提供了将图形拉伸压缩的复制方式。
1.5.3 位图的显示
采用MFC方法编程时,显示一个DDB位图需要执行以下几个步骤。
(1)声明一个CBitmap类的对象,使用LoadBitmap( )函数将位图装入内存。
(2)声明一个CDC类的对象,使用CreateCompatibleDC( )函数创建一个与显示设备环境兼容的内存设备环境。
CreateCompatibleDC( )函数的原型为:
Virtual Bool CreateCompatibleDC(CDC *pDC);
其中,参数pDC是指向设备环境的指针。如果pDC为NULL,则创建与系统显示器兼容的内存设备环境。
(3)使用CDC::SelectObject( )函数将位图对象选入设备环境中,并保存原来设备环境的指针。
(4)利用CDC的相关输出函数输出位图。
(5)使用CDC::SelectObject( )函数恢复原来设备环境。
总结
百川东到海,壮志不能改;专心做事业,命运我主宰;年轻要努力,追求不停息;成功看自己,收获靠实力;愿你事业顺利,人生精彩!