1、MFC 绘图基础先认识一下 MFC 中的一些和绘图有关的结构体和类1.点(1)点结构 POINT 点数据结构 POINT 用来表示一点的 x、y 坐标:typedef struct tagPOINT LONG x;LONG y; POINT;(2)点类 CPoint点类 CPoint 为一个没有基类的独立类,封装了 POINT 结构,有成员变量 x 和 y其构造函数有 5 种:CPoint( );CPoint( int initX, int initY );CPoint( POINT initPt );CPoint( SIZE initSize );CPoint( LPARAM dwPoint
2、 );/ 低字设为 x、高字设为 yCPoint 类还定义了 4 个平移和设置函数:void Offset(int xOffset, int yOffset);void Offset(POINT point);void Offset(SIZE size);void SetPoint(int X, int Y);CPoint 类还重载了+ 、-、 +=、-=、=、!= 等运算符来支持 CPoint 对象和CPoint、POINT、SIZE 对象之间的运算。2大小(1)大小结构 SIZE大小(size 尺寸)结构 SIZE 用来表示矩形的宽 cx 和高 cy:typedef struct tagS
3、IZE LONG cx;LONG cy; SIZE(2)大小类 CSize大小类 CSize 也为一个没有基类的独立类,封装了 SIZE 结构,有成员变量 cx 和 cy其构造函数也有 5 种:CSize( );CSize( int initCX, int initCY );CSize( SIZE initSize );CSize( POINT initPt );CSize( DWORD dwSize ); / 低字设为 cx、高字设为 cyCSizet 类也重载了+ 、- 、+=、-=、=、!=等运算符来支持 CSize 对象和CSize、POINT、SIZE、RECT 对象之间的运算3矩形
4、(1)矩形结构 RECT矩形结构 RECT 定义了矩形的左上角与右下角的坐标:typedef struct tagRECT LONG left;LONG top;LONG right;LONG bottom; RECT;(2)矩形类 CRect矩形类 CRect 也为一个没有基类的独立类,封装了 RECT 结构,有成员变量left、top、right 和 bottom其构造函数有 6 种:CRect( );CRect( int l, int t, int r, int b );CRect( const RECTCRect( LPCRECT lpSrcRect );CRect( POINT po
5、int, SIZE size );CRect( POINT topLeft, POINT bottomRight );CRect 类重载了= ,+ 、-, +=、-=,=、!= ,该函数当点 point 在其矩形区域内时,返回真。注意,该矩形区域不包括矩形的右边界和底边界然后就是关于 设备描述表 的获取和释放了,前一文章提到过, 这里就不提了只说一个特别点的概念 “安全 DC 句柄”也可以用 CDC 类的成员函数:HDC GetSafeHdc();来获取 CD 所对应窗口(如客户区)的安全 DC 句柄,该句柄在窗口存在期间一直是有效的。例如,可先定义类变量 HDC m_hDC;,再在适当的地方
6、给它赋值 m_hDC = GetDC()-GetSafeHdc();,然后就可以放心地使用了因为不能简单的将这一指针保存在类的数据成员中,而是应该借助 GetSafeHdc 成员函数将它转换为 windows 句柄 (唯一能够持久存在的 GDI 标示)例如,可以使用 CDC 类的成员函数BOOL Attach(HDC hDC); / 成功返回非 0来将 CDC 对象与 DC 句柄连接在一起4.设置绘图颜色(1)颜色Windows 中的颜色一般用 4 个字节表示,Win32 API 中定义了一个专门表示颜色索引值的变量类型 COLORREF:(windef.h)typedef DWORD COL
7、ORREF; / 0x00bbggrr和一个由红绿蓝三原色构造颜色值的宏 RGB:(wingdi.h)#define RGB(r,g,b) (COLORREF)(BYTE)(r)|(WORD)(BYTE)(g) 8)#define GetBValue(rgb) (LOBYTE(rgb)16)(2)点色(像素)在 Windows 中,像素(pixel)的颜色是直接由设备上下文类 CDC 的成员函数 SetPixel 来设置的该函数的原型为:COLORREF SetPixel( int x, int y, COLORREF crColor );COLORREF SetPixel( POINT po
8、int, COLORREF crColor );其中,x 与 y 分别为像素点的横坐标与纵坐标,crColor 为像素的颜色值。例如:pDC-SetPixel(10, 10, RGB(0, 255, 0);另外,也可以用 CDC 的成员函数COLORREF GetPixel( int x, int y ) const;COLORREF GetPixel( POINT point ) const;来获得指定点(x, y)或 point 的颜色。例如:COLORREF col;col = pDC-GetPixel(10, 10);(3)线色(笔)在 Windows 中,线状图必须用笔 (pen)来
9、画,所以线的颜色就由笔色来确定。在 MFC 中,b31.org 笔的属性和功能由 CPen 类提供(CPen 是 CGDIObject 的派生类) 。笔的创建与使用的步骤为:#1 创建笔对象:创建笔类 CPen 对象的方法有如下两种:CPen( int nPenStyle, int nWidth, COLORREF crColor );其中:nPenStyle 为笔的风格,可取值:PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PSDASHDOTDOT注意:14 号笔风格只是在笔宽=0 或 1 时有效,笔宽1 时总为实心的BOOL CreatePen( int n
10、PenStyle, int nWidth, COLORREF crColor );#2 将笔对象选入设备上下文:为了能使用我们所创建的笔对象,必须先将它选入设备上下文,这可以调用设备上下文类 CDC 的成员函数 SelectObject 来完成:CPen* SelectObject( CPen* pPen );返回值为指向原来笔对象的指针(一般将其保存下来,供下次再装入时使用) 。如 pOldPen = pDC-SelectObject(另外,Windows 中有一些预定义的笔对象,可用 CDC 的另一成员函数SelectStockObject 将其选入 DC其函数原型为:virtual CG
11、diObject* SelectStockObject( int nIndex );预定义的笔对象有 BLACK_PEN(黑色笔) 、WHITE_PEN (白色笔) 、NULL_PEN(空笔/无色笔)例如:pDC-SelectStockObject(BLACK_PEN);#3 使用设备上下文画线状图:画线状图以及面状图的边线,所使用的是当前设备上下文中的笔对象。线状图有直线、折线、矩形、 (椭)圆(弧)等,详见#4 将笔对象从设备上下文中放出:为了能删除使用过的笔对象,必须先将它从设备上下文中释放出来后,然后才能删除。释放的方法是装入其他的笔对象(一般是重新装入原来的笔对象) 。例如pDC-S
12、electObject(pOldPen);#5 删除笔对象:为了能删除笔对象,必须先将其从设备上下文中释放。删除方法有如下几种:调用笔类 CDC 的成员函数 DeleteObject 删除笔的当前内容(但是未删除笔对象,以后可再用成员函数 CreatePen 在笔对象中继续创建新的笔内容) 。如pen.DeleteObject();使用删除运算符 delete 将笔对象彻底删除,如 delete pen;自动删除:若笔对象为局部变量,则在离开其作用域时,会被系统自动删除(4)面色(刷)在 Windows 中,面状图必须用刷 (brush)来填充,所以面色是由刷色来确定的。MFC 中的刷类为 C
13、Brush(它也是 CGDIObject 的派生类) ,刷的创建与使用的步骤与笔的相似。构造函数有 4 个:CBrush( ); / 创建一个刷的空对象CBrush( COLORREF crColor ); / 创建颜色为 crColor 的实心刷CBrush( int nIndex, COLORREF crColor ); / 创建风格由 nIndex 指定且颜色为 crColor 的条纹(hatch)刷,其中 nIndex 可取条纹风格(Hatch Styles)值:符号常量 数字常量 风格HS_HORIZONTAL 0 水平线HS_VERTICAL 1 垂直线HS_FDIAGONAL 2
14、 正斜线HS_BDIAGONAL 3 反斜线HS_CROSS 4 十字线(正网格)HS_DIAGCROSS 5 斜十字线(斜网格)CBrush( CBitmap* pBitmap ); / 创建位图为 pBitmap 的图案刷如:pDC-FillRect( 与构造函数相对应,有多个创建不同类型刷的成员函数:BOOL CreateSolidBrush( COLORREF crColor );BOOL CreateHatchBrush( int nIndex, COLORREF crColor );BOOL CreatePatternBrush( CBitmap* pBitmap );BOOL C
15、reateDIBPatternBrush( HGLOBAL hPackedDIB, UINT nUsage );BOOL CreateDIBPatternBrush( const void* lpPackedDIB, UINT nUsage );BOOL CreateBrushIndirect( const LOGBRUSH* lpLogBrush );BOOL CreateSysColorBrush( int nIndex );预定义的刷对象有 BLACK_BRUSH(黑刷) 、DKGRAY_BRUSH(暗灰刷) 、GRAY_BRUSH(灰刷) 、 HOLLOW_BRUSH(空刷) 、LTG
16、RAY_BRUSH (亮灰刷) 、NULL_BRUSH(空刷) 、WHITE_BRUSH(白刷)缺省的刷为空刷与笔一样,可以用函数 SelectObject 或 SelectStockObject 将自定义的刷或预定义的刷选入 DC 中,供绘面状图时使用。(5)文本色可使用 CDC 类的成员函数 SetTextColor 和 SetBkColor 来分别设置输出文本的前景色和背景色:(缺省的前景色为黑色,背景色空)COLORREF GetTextColor( ) const;virtual COLORREF SetTextColor( COLORREF crColor );COLORREF G
17、etBkColor( ) const;virtual COLORREF SetBkColor( COLORREF crColor );例如:pDC-TextOut(10, 10, “Test text“);pDC-SetTextColor(RGB(0, 128, 0);pDC-TextOut(10, 30, “Test text“);pDC-SetBkColor(RGB(0, 0, 128);pDC-TextOut(10, 50, “Test text“);5.清屏Windows 没有提供专门的清屏函数,可以调用 CWnd 的下面两个函数调用来完成该功能:void Invalidate(BOO
18、L bErase = TRUE);void UpdateWindow( );或调用 CWnd 的函数 BOOL RedrawWindow(LPCRECT lpRectUpdate = NULL,CRgn* prgnUpdate = NULL,UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);来完成。5 设置绘图属性除了映射模式外,还有许多绘图属性可以设置如背景、绘图方式、多边形填充方式、画弧方向、刷原点等。#1 背景1)背景色当背景模式为不透明时,背景色决定线状图的空隙颜色(如虚线中的空隙、条纹刷的空隙和文字的空隙)可以使用 CD
19、C 类的成员函数 GetBkColor 和 SetBkColor 来获得和设置当前的背景颜色:COLORREF GetBkColor( ) const; / 返回当前的背景色virtual COLORREF SetBkColor( COLORREF crColor ); / 返回先前的背景色/ 若出错返回 0x800000002)背景模式背景模式影响有空隙的线状图的空隙(如虚线中的空隙、条纹刷的空隙和文字的空隙)用什么办法填充。澳门新濠天地官网 66bb.org可以使用 CDC 类的成员函数 GetBkMode 和 SetBkMode 来获得和设置当前的背景模式:int GetBkMode(
20、) const; / 返回当前背景模式int SetBkMode( int nBkMode ); / 返回先前背景模式背景模式的取值 nBkMode 值 名称 作用OPAQUE 不透明的(缺省值) 空隙用背景色填充TRANSPARENT 透明的 空隙处保持原背景图不变2. 绘图模式绘图模式(drawing mode)指前景色的混合方式,它决定新画图的笔和刷的颜色(pbCol)如何与原有图的颜色 (scCol)相结合而得到结果像素色(pixel) 。1)设置绘图模式可使用 CDC 类的成员函数 SetROP2 (ROP = Raster OPeration 光栅操作)来设置绘图模式:int Se
21、tROP2( int nDrawMode );其中,nDrawMode 可取值:绘图模式 nDrawMode 的取值符号常量 作用 运算结果R2_BLACK 黑色 pixel = blackR2_WHITE 白色 pixel = whiteR2_NOP 不变 pixel = scColR2_NOT 反色 pixel = scColR2_COPYPEN 覆盖 pixel = pbColR2_NOTCOPYPEN 反色覆盖 pixel = pbColR2_MERGEPENNOT 反色或 pixel = scCol | pbColR2_MERGENOTPEN 或反色 pixel = scCol |
22、pbColR2_MASKNOTPEN 与反色 pixel = scCol & pbColR2_MERGEPEN 或 pixel = scCol | pbColR2_NOTMERGEPEN 或非 pixel = (scCol | pbCol)R2_MASKPEN 与 pixel = scCol & pbColR2_NOTMASKPEN 与非 pixel = (scCol & pbCol)R2_XORPEN 异或 pixel = scCol pbColR2_NOTXORPEN 异或非 pixel = (scCol pbCol)其中,R2_COPYPEN (覆盖)为缺省绘图模式,R2_XORPEN(异或)较常用。是