




已阅读5页,还剩15页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
08GDI编程1-绘图.txt你妈生你的时候是不是把人给扔了把胎盘养大?别把虾米不当海鲜。别把虾米不当海鲜。 文库帮手网 免费帮下载 百度文库积分 资料 本文由Joasea贡献 doc文档可能在WAP端浏览体验不佳。建议您优先选择TXT,或下载源文件到本机查看。 第8章 GDI 编程 1-绘图 GDI(Graphics Device Interface,图形设备接口)是 Windows 操作系统的传统图形子系 统,负责与设备无关的图形绘制,Win32 API 为应用程序提供了丰富的绘图函数和功能, MFC 对它们进行了 C+类封装,参见图 8-1。 Windows 应用程序 MFC Win32 API 执行程序 设备驱动程序 用户界面(User) 内核(Kernel) 硬件抽象层(HAL) 计算机硬件 图 8-1 GDI 与 Windows 操作系统(其中彩色部分为操作系统) GDI+ 图形子系统(GDI) 图形驱动程序 传统 GDI 是随 Windows 1.0 于 1985 年 11 月推出的,新式 GDI+则是随 Windows XP 于 2001 年 10 月推出的 GDI 的改进版,增加了混色、渐变画刷、样条曲线、矩阵变换、图像 处理、持久路径等新功能。随 Windows Vista 及.NET 框架 3.0 微软于 2006 年 11 月又推出了 基于 DirectX 和.NET 框架的全新图形子系统 WPF(Windows Presentation Foundation,视窗 显示/展现基础) ,它统一了桌面和浏览器等客户端应用程序的图形界面,采用 XAML 声明 式编程,将用户界面的设计和编程彻底分离开来,是 Windows 的下一代 GUI 显示系统。 本书从第 8 章到第 11 章, 将详细讨论如何使用 GDI 进行传统的 Windows 图形编程, 包 括绘图、文字、图像、动画、图标、图元文件和打印等内容。GDI+是建立在 GDI 之上的, 计划在第 14 和 15 章中作简单介绍。WPF 则是以.NET 框架为基础的,准备在第 19 上和 20 章中再加以讨论。 在 MFC 应用程序中,绘图一般在视图类的(屏幕/打印机)绘图消息响应函数 OnDraw 中进行,例如: void CDrawView:OnDraw(CDC* /*pDC*/) CDrawDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; 1 / TODO: 在此处为本机数据添加绘制代码 每次需要重绘窗口时(如程序启动、窗口大小改变、全部或部分窗口重现、程序员调用函数 RedrawWindow 或 Invalidate/UpdateWindow) ,应用程序框架都会调用此 CWnd 消息响应成 员函数(的覆盖)来绘制窗口客户区。 在 Windows 中,绘图一般在框架窗口的客户区(对应于视图类 C*View)进行,使用的 是封装在 MFC 的设备上下文(Device-Context,DC)类 CDC 中的各种绘图函数。 在绘图前,一般需先得到客户区大小和 CDC 对象、设置绘图颜色,然后再根据文档数 据或用户操作来绘制各种图形。 8.1 几何对象的结构和类 为了使用绘图函数,应该先了解绘图所用到的几种表示几 何对象的结构和类,包括点、大小和矩形,其中常用的是点和 矩形。这些结构和类被分别定义在头文件 windef.h 和 afxwin.h 中。MFC 中的几何对象类都是独立的类(不是 CObject 的派生类) ,是对 API 中对应结构的 C+封装,参见图 8-2。 图 8-2 GDI 几何对象 的结构与类 8.1.1 8.1.1 点 点(point)在 API 中的结构为 POINT,对应的 MFC 类为 CPoint。 1点结构 POINT API 中的点数据结构 POINT 用来表示一点的 x、y 坐标: typedef struct tagPOINT LONG x; LONG y; POINT; 其中,类型 LONG(32 位整数)的定义为:typedef long LONG; 2点类 CPoint MFC 中的点类 CPoint 为一个没有基类的独立类,封装了 POINT 结构,有成员变量 x 和 y,其构造函数有 5 种: 2 CPoint( ); / 默认 CPoint( int initX, int initY ); / 常用 CPoint( POINT initPt ); CPoint( SIZE initSize ); CPoint( LPARAM dwPoint ); / 低字设 为 x、高字设为 y CPoint 类还定义了 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 对象之间的运算。 8.1.2 8.1.2 大小 大小(size,尺寸)在 API 中的结构为 SIZE,在 MFC 中的类为 CSize。 1大小结构 SIZE 大小结构 SIZE 用来表示矩形的宽 cx 和高 cy: typedef struct tagSIZE LONG cx; LONG cy; SIZE; 2大小类 CSize MFC 中的大小类 CSize 也为一个没有基类的独立类,封装了 SIZE 结构,有成员变量 cx 和 cy,其构造函数也有 5 种: CSize( ); CSize( int initCX, int initCY ); CSize( SIZE initSize ); CSize( POINT initPt ); CSize( DWORD dwSize ); / 低字设为 cx、高字设为 cy CSizet 类也重载了+、-、+=、-=、=、!= 等运算符来支持 CSize 对象和 CSize、POINT、 SIZE、RECT 对象之间的运算。 8.1.3 矩形 矩形(rectangle)在 API 中的结构为 RECT,在 MFC 中的类为 CRect。 3 1矩形结构 RECT API 中的矩形结构 RECT 定义了矩形的左上角与右下角的坐标: typedef struct tagRECT LONG left; LONG top; LONG right; LONG bottom; RECT; 2矩形类 CRect MFC 中的矩形类 CRect 也为一个没有基类的独立类,封装了 RECT 结构,有成员变量 left、top、right 和 bottom,其构造函数有 6 种: CRect( ); / 默认 CRect( int l, int t, int r, int b ); / 常用 CRect( const RECT& srcRect ); CRect( LPCRECT lpSrcRect ); CRect( POINT point, SIZE size ); CRect( POINT topLeft, POINT bottomRight ); CRect 类重载了=,+、-,+=、-=,=、!=,&、|,&=、|= 等运算符来支持 CRect 对象 和 CRect、POINT、SIZE、RECT 对象之间的运算。还定义了转换符 LPCRECT 和 LPRECT 来自动完成 CRect 对象到矩形结构和类指针 LPCRECT 和 LPRECT 的转换。 CRect 类中常用的属性和成员函数有: int Width( ) const; int Height( ) const; CSize Size( ) const; CPoint& TopLeft( ); CPoint& BottomRight( ); CPoint CenterPoint( ) const; void SwapLeftRight(); 3判断点是否在矩形中 BOOL IsRectEmpty( ) const; BOOL PtInRect( POINT point ) const; void SetRect( int x1, int y1, int x2, int y2 ); void SetRect(POINT topLeft, POINT bottomRight); void OffsetRect(int x, int y); void MoveToXY(int x, int y); 有时需要判断某点 (如鼠标位置) 是否在某一矩形区域 (如控件) 中, 这可以调用 CRect 类的 PtInRect 函数来做: BOOL PtInRect( POINT point ) const; 该函数当点 point 在其矩形区域内时,返回真。注意,该矩形区域不包括矩形的右边界和底 边界。例如: CRect rect( 10, 10, 371, 267 ); 4 void CDrawView:OnLButtonUp(UINT nFlags, CPoint point) / TODO: 在此添加消息处理程序代码和/或调用默认值 if ( rect.PtInRect( point ) ) CView:OnLButtonUp(nFlags, point); 8.1. 8.1.4 获得客户区大小 绘图一般都是在框架窗口的客户区(对应于视图类)进行,而客户区的大小在运行时可 由用户动态改变, 为了使绘制的图形能随窗口大小而自动改变, 需先得到当前客户区大小的 数据(宽和高) 。 获取客户区大小的方法有如下两种: 1OnSize 获取客户区大小的第一种方法是通过消息响应函数 OnSize 中获得。 可利用属性窗口的消息页,为视图类添加 WM_SIZE 消息的响应函数 OnSize。该函数 会在窗口第一次显示或窗口大小被改变时被系统调用。 其输入参数中的 cx 和 cy 就是当前客 户区的宽和高,可将它们赋值给类变量(如 m_iW 和 m_iH)供绘图时使用。例如: void CDrawView:OnSize(UINT nType, int cx, int cy) CView:OnSize(nType, cx, cy); / TODO: 在此处添加消息处理程序代码 m_iW = cx; m_iH = cy; 其中,nType 的值为: SIZE_MAXIMIZED(窗口已被最大化) SIZE_MINIMIZED(窗口已被最小化) SIZE_RESTORED(窗口已被改变大小) SIZE_MAXHIDE(其他窗口被最大化) SIZE_MAXSHOW(其他窗口从最大化还原) 5 2GetClientRect 获取客户区大小的第二种方法是调用窗口类的获取客户区矩形成员函数 GetClientRect 来得到。具体做法是,在绘图前定义一个矩形结构变量 rect,然后再调用 CWnd 类的成员函 数 GetClientRect 来得到当前客户区矩形的数据,该函数的原型为: void GetClientRect( LPRECT lpRect ) const; 其中,矩形结构的右(right)与底(bottom)就是客户区的宽与高(其左 left 与顶 top 都为 0) 。例如: RECT rect; GetClientRect(&rect); int iW = rect.right, iH = rect.bottom; 8.2 绘图环境 DC 在 Windows 中,绘图包括绘制图形、显示位图和输出文字,它们都需要使用绘图环境 DC(Device-Context, 设备上下文) 。MFC 将 DC 结构和所有的绘图函数、绘图对象的访问 函数、绘图模式与参数的设置函数都封装到了 CDC 类中。 8.2.1 8.2.1 DC 结构 DC 是 Windows 为设备无关的图形绘制而定义的一种数据结构, 包含了一组图形对象及 关联属性和若干影响输出的图形模式和绘图参数。所有的 GDI 绘图操作,都是采用 DC 中 的当前图形对象作为绘图工具, 并且都是在 DC 中的当前图形模式下使用当前的绘图参数进 行的。 1图形对象 Windows 的图形对象(graphic object)包括画线状图的笔、绘制和填充面状图的刷、用 于复制和滚动部分屏幕的位图、定义可用颜色的调色板、用于裁剪和其他操作的区域、用于 绘制和画图操作的路径、及用于输出文字的字体,参见表 8-1。图像对象所对应的 MFC 类 将在 8.3.6 中介绍,其中笔和刷在 8.3.3 和 8.3.4 中介绍,字体在 9.2 中介绍。 表 8-1 图形对象及 DC 的默认值 6 图形对象 笔 刷 位图 关联属性 风格、宽度、颜色 风格、颜色、图案、原点 大小 (字节) 尺寸 、 (像素) 、 无 颜色格式、压缩方式等 颜色与大小(或颜色数) 定位与尺寸 形状 字体名、宽、高、粗细、字 DC 默认值 实心、单像素、黑色 实心、白色、单色、(0, 0) 调色板 区域 路径 字体 20 种标准系统色 窗口矩形 无 system(宋体) 、7、16、700 (粗体) 、GB2312_CHARSET 符集等 2图形模式 图形模式 (graphics mode) 用于确定颜色如何混合、 输出在何处出现、 输出如何缩放等, 参见表 8-2。 表 8-2 图形模式及 DC 的默认值 图形模式 描述 DC 默认值 介绍章节 定义图形输出如何从逻辑 (或世界) 文本(MM_TEXT) ,即 映射 空间映射到窗口、 屏幕或打印机纸, 设备坐标(单位为像素、 8.4.1 即坐标体系 对笔、刷、位图和文本操作,定义 绘图 前景色如何与已存在的窗口或屏幕 颜色混合 对位图和文本操作,定义背景色如 背景 何与已存在的窗口或屏幕颜色混合 定义在位图被压缩(或缩小)时, 存黑去白 拉伸 定义位图颜色如何与已存在的窗口 (BLACKONWHITE) 或屏幕颜色混合 定义刷图案如何用来填充复杂区域 多边形填充 的内部 即按奇偶规则填充 交替(ALTERNATE) , 8.5.3 9.3.3 不透明(OPAQUE) 8.5.1 覆盖(R2_COPYPEN) 8.5.2 x 向右、y 向下) 7 3图形参数 除了图形对象和图形模式外,DC 中还保存有当前的笔位置(默认值为坐标原点) 、背 景色(默认为白色) 、文本色(默认为黑色) 、文本对齐(默认为左顶) 、画弧方向(逆时针) 等绘图参数。 虽然 DC 是一种结构,但是 Windows 不允许应有程序的代码直接访问它。程序员必须 通过调用各种对应的 Set*和 Get*函数以及 Select*来设置和获取其中的对象、模式和参数。 8.2.2 8.2.2 CDC 类 CDC 类是 MFC 对 DC 结构及其相关绘图和状态设置函数的 C+类封装。 CDC 是 CObject 的直接派生类, CDC 类自己也有若干派生类, 其中包括: 窗口客户区 DC 所对应的 CClientDC 类、OnPaint 和 OnDraw 消息响应函数的输入参数中使用的 CPaintDC 类、图元文件对应的 CMetaFileDC 类和整个窗口所对应的 CWindowDC 类,参见图 8-3。 在普通的 MFC 绘图中,一般直接使用 CDC 类即可。 CDC 类中有许多成员函数,可以用来设置各种绘图环境、属性 和参数,以及绘制各种图形和图像等,将在后面陆续加以介绍。 1获得 DC 图 8-3 DC 类 在 OnDraw 函数中应该使用输入参数 pDC,在其他函数中则可调用从 CWnd 类继承的 成员函数 GetDC 来获得当前窗口(如客户区/视图类)DC 的指针,该函数的原型为: CDC* GetDC( ); 注意,每次从 OnDraw 函数的输入参数或调用 GetDC 所获得的 DC,都是一个全新的临 时默认 DC,具有默认的绘图环境和设置。它不能用类变量来长期保存,而且原来选入的各 种 GDI 对象全都被作废、原来设置的各种状态也失效,一切都必须从头再来。 2释放 DC 因为 Windows 限制可用 DC 的数量,所以 DC 属于稀缺的公用资源。因此,对每次获 得的 DC,在使用完成后必须立即释放。 从 OnDraw 函数的输入参数 pDC 获得的 DC,在该函数运行结束后,系统会自动释放。 8 但由 GetDC 所获得的 DC,则必须自己来手工释放,这可以通过调用从 CWnd 类继承的成 员函数 ReleaseDC 来完成。该函数的原型为: int ReleaseDC( CDC* pDC ); / 成功返回非 0 例如: void CDrawView:OnLButtonUp(UINT nFlags, CPoint point) CDC* pDC = GetDC(); / 获取 DC pDC-SelectObject(&pen); / 选入笔 pDC-Rectangle(&rect); / 绘制矩形 ReleaseDC(pDC); / 释放 DC CView:OnLButtonUp(nFlags, point); 3安全 DC 句柄 可以用 CDC 类的成员函数 GetSafeHdc 来获取 DC 所对应窗口(如客户区)的安全 DC 句柄,该函数的原型为: HDC GetSafeHdc(); 与用 GetDC 函数所得到的临时 DC 不同,该安全 DC 句柄在窗口的存在期间内一直是有效 的 。 例 如 , 可 先 定 义 类 变 量 HDC m_hDC; , 再 在 适 当 的 地 方 给 它 赋 值 m_hDC = GetDC()-GetSafeHdc();,然后就可以放心地使用了。还可以使用 CDC 类的成员函数 Attach 来将一空 CDC 对象与此安全 DC 句柄连接在一起,该函数的原型为: BOOL Attach(HDC hDC); / 成功返回非 0 4屏幕 DC 可以以 NULL 为输入参数,调用全局的 API 函数 GetDC: HDC GetDC(HWND hWnd); 来可获取屏幕 DC 的句柄。例如: HDC hdc = :GetDC(NULL); / 获取屏幕 DC 的句柄 Ellipse(hdc, 0, 0, 150, 100); / 用 API 函数在屏幕左上角画一椭圆 9 也可以利用 CDC 类的成员函数 Attach,将屏幕 DC 的句柄选入自定义的 CDC 类中,来 构造屏幕 CDC 类的对象。例如: HDC hdc = :GetDC(NULL); / 获取屏幕 DC 的句柄 CDC sDC; / 定义屏幕 DC(空)对象 sDC.Attach(hdc); / 粘上屏幕 DC 句柄 sDC.Ellipse(0, 0, 150, 100); / 在屏幕左上角画一椭圆 8.3 绘图颜色与工具 在 Windows API 中用 4 个字节的双字来定义颜色类型 COLORREF, (Red)(Green) 有红 绿 蓝(Blue)三个字节分量,可用 RGB 宏来为颜色赋值。在 GDI 中有画线状图的笔(pen) 、 画填充图的刷(brush) 、画文字的字体(font)等绘图工具。而 GDI 中使用的颜色种类则有 4 种之多,它们分别是像素所对应的点色、笔所对应的线色、刷所对应面色、文字所对应的 文本色。其中的像素和文本色,可以通过调用对应的专门函数来设置和获取。而笔和刷的颜 色,则必须先利用颜色参数创建笔和刷对象,然后调用通用的选择对象函数 SelectObject 将 笔、刷等绘图工具选入 DC,再利用 DC 来绘制各种颜色的图形。 8.3.1 8.3.1 颜色 Windows 中的颜色一般用 4 个字节表示 (0BGR (整数序) RGB0 或 (字节序) 因为 Intel , CPU 的 低 位 字 节 在前) Win32 API 中 定 义 了一 个 专 门 表 示 颜 色 索 引值 的 变 量 类 型 , COLORREF(windef.h) : typedef DWORD COLORREF; / 0x00bbggrr 和一个由红绿蓝三原色构造颜色值的宏 RGB(wingdi.h) : #define RGB(r,g,b) (COLORREF)(BYTE)(r)|(WORD)(BYTE)(g)8)|(DWORD)(BYTE)(b)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); 8.3.3 线色( 8.3.3 线色(笔) 在 Windows 中,线状图必须用笔(pen)来画,所以线的颜色就由笔色来确定。在 MFC 中,笔的属性和功能由 CPen 类提供(CPen 是 CGDIObject 的派生类) 。 笔的创建与使用的步骤为: 1创建笔对象 创建 CPen 类笔对象的方法有如下两种: 11 使用非默认构造函数创建初始笔: CPen( int nPenStyle, int nWidth, COLORREF crColor ); 其中: nPenStyle 为笔的风格,可取值见表 8-3。 表 8-3 笔风格 nPenStyle 值 符号常量 PS_SOLID PS_DASH PS_DOT PS_DASHDOT PS_DASHDOTDOT PS_NULL PS_INSIDEFRAME 数值 0 1 2 3 4 5 6 风格名称 实心 虚线 点线 虚点线 虚点点线 空笔 框内 线例 注意:14 号笔风格只是在笔宽=0 或 1 时有效,笔宽1 时总为实心的。 nWidth 为笔宽,与映射模式有关,使用默认映射时为像素数,若 nWidth = 0, 则不论什么映射模式,笔宽都为一个像素。 crColor 为笔的颜色值。 默认的笔为单像素宽的黑色实心笔。 例如: CPen* pGrayPen = new CPen(PS_SOLID, 0, RGB(128, 128, 128); CPen grayPen(PS_SOLID, 0, RGB(128, 128, 128); 使用成员函数 CreatePen(多次)创建笔: BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor ); 可先用 CPen 类的默认构造函数创建一个空笔对象,然后再调用 CreatePen 创建具 有新内容的笔,例如: CPen grayPen; grayPen.CreatePen(PS_SOLID, 0, RGB(128, 128, 128); 不过在用 CreatePen 创建新笔之前,必须先调用 DeleteObject 函数删除笔对象的内 容。该函数是 CPen 的基类 CGDIObject 的成员函数,下面是它的原型: 12 BOOL DeleteObject( ); 2选笔入 DC 为了能使用我们自己所创建的笔对象,必须先将它选入 DC,这可以调用设备上下文类 CDC 的成员函数 SelectObject 来完成: CPen* SelectObject( CPen* pPen ); 该函数的返回值为指向原来笔对象的指针(一般将其保存下来,供下次选出新笔时使用) 。 例如: pOldPen = pDC-SelectObject(&pen); 另外,Windows 中有一些预定义的笔对象(参见表 8-4) ,可用 CDC 的另一成员函数 SelectStockObject 将其选入 DC,其函数原型为: virtual CGdiObject* SelectStockObject( int nIndex ); 表 8-4 预定义笔 符号常量 WHITE_PEN BLACK_PEN NULL_PEN DC_PEN 数值 6 7 8 19 笔 白色笔 黑色笔 空笔 DC 笔 其中,DC 笔为单色实心笔,默认为黑色。是从 Windows NT/2000 开始新引进的,可用于直 接设置笔色,参见本小节后面的第 6 部分。 例如: pDC-SelectStockObject(BLACK_PEN); 3绘制线状图 在将笔对象选入 DC 后,就可以使用 CDC 类中的绘图函数,利用 DC 中的笔对象,来 画线状图及面状图的边线。如果不创建和选入笔对象,则使用的是 DC 中的默认笔,为单像 素宽的实心黑色笔。 Windows 中的线状图有直线、折线、矩形、 (椭)圆(弧)等,详见 8.4.3。 13 4删除笔 不能直接删除已使用过的笔对象,必须先将它从 DC 中释放出来后才能删除。释放的方 法是装入其他的笔对象(一般是重新装入原来的笔对象) 。例如: pDC-SelectObject(pOldPen); 删除笔对象的方法有如下几种: 删除笔内容:调用笔类 CDC 的成员函数 DeleteObject 删除笔的当前内容(但是未 删除笔对象,以后可再用成员函数 CreatePen 在笔对象中继续创建新的笔内容) 。 例如:pen.DeleteObject(); 删除笔对象:使用删除运算符 delete 将笔对象彻底删除,例如 delete &pen;。 自动删除: 若笔对象为局部变量, 则在离开其作用域时, 笔对象会被系统自动删除。 5例子 下面为一段较完整地创建与使用笔的例子代码: CDC* pDC = GetDC(); / 获取 DC CPen pen, *pOldPen; / 定义笔对象和指针 / 创建 10 单位宽的绿色实心笔 pen.CreatePen(PS_SOLID, 10, RGB(0, 255, 0); pOldPen = pDC-SelectObject(&pen); / 选入绿色笔 pDC-Rectangle(10, 10, 100, 100); / 画矩形 pDC-SelectObject(pOldPen); / 选出绿色笔 pen.DeleteObject(); / 删除绿色笔 / 创建单像素宽的红色虚线笔 pen.CreatePen(PS_DASH, 0, RGB(255, 0, 0); pOldPen = pDC-SelectObject(&pen); / 选入红色笔 pDC-MoveTo(10, 10); pDC-LineTo(100, 100); / 画直线 ReleaseDC(pDC); / 释放 DC 14 6设置 DC 笔颜色 对 Windows NT/2000 及以上的版本,如果只需修改实心笔的颜色,而不需改变笔的粗 细,则可以不用反复创建和选入新笔,而使用 CDC 类的成员函数 SetDCPenColor,来直接 设置 DC 笔的颜色: COLORREF SetDCPenColor( COLORREF crColor ); / 返回原颜色值 对应的获取 DC 三笔颜色的成员函数为: COLORREF GetDCPenColor( ) const; 不过这需要先调用 CDC 的成员函数 SelectStockObject 将 DC 笔选入 DC 后,才能使用 SetDCPenColor 函数来设置 DC 中笔的颜色。例如: pDC-SelectStockObject(DC_PEN); / 选入 DC 笔 pDC-SetDCPenColor(RGB(255, 0, 0); / 设置成红色 8.3.4 面色( 8.3.4 面色(刷) 在 Windows 中,面状图必须用刷(brush)来填充,所以面色是由刷色来确定的。MFC 中的刷类为 CBrush(它也是 CGDIObject 的派生类) ,刷的创建与使用的步骤与笔的相似。 1构造函数 CBrush 类有 4 个构造函数,分别用于创建空刷、实心刷、条纹刷和图案刷: CBrush( ); / 创建一个刷的空对象 CBrush( COLORREF crColor ); / 创建颜色为 crColor 的单色实心刷 CBrush( int nIndex, COLORREF crColor ); / 创建风格由 nIndex 指定且颜色为 crColor 的条纹(hatch,孵化/影线)刷,其中 nIndex 可取条纹风格(Hatch Styles) 值见表 8-5 和图 8-4。 表 8-5 条纹风格 nIndex 值 符号常量 HS_HORIZONTAL HS_VERTICAL HS_FDIAGONAL 数值 0 1 2 风格 水平线 垂直线 正斜线 15 HS_BDIAGONAL HS_CROSS HS_DIAGCROSS 3 4 5 反斜线 十字线(正网格) 斜十字线(斜网格) 水平线 垂直线 正斜线 反斜线 十字线 斜十字线 图 8-4 条纹刷的种类 CBrush(CBitmap* pBitmap); / 创建位图为 pBitmap 的图案(pattern)刷 默认的刷为白色实心刷。 2创建函数 与构造函数相对应,CBrush 类有多个创建不同类型刷的成员函数,如: BOOL CreateSolidBrush( COLORREF crColor ); / 创建(单色)实心刷 BOOL CreateHatchBrush( int nIndex, COLORREF crColor ); / 创建条纹刷 BOOL CreatePatternBrush( CBitmap* pBitmap ); / 创建图案刷 3预定义刷 预定义的刷对象见表 8-6 有: 表 8-6 预定义刷 符号常量 WHITE_BRUSH LTGRAY_BRUSH GRAY_BRUSH DKGRAY_BRUSH BLACK_BRUSH HOLLOW_BRUSH NULL_BRUSH DC_BRUSH 数值 0 1 2 3 4 5 5 18 刷 白刷(默认) 亮灰刷 灰刷 暗灰刷 黑刷 空刷 空刷 DC 刷 其中,DC 刷为单色实心刷,默认为白色。是从 Windows NT/2000 开始新引进的,可用于直 16 接设置刷色,参见本小节后面的第 5 部分。 3选入刷 与笔一样, 可以用函数 SelectObject 或 SelectStockObject 将自定义刷或预定义刷选入 DC 中,供绘面状图时使用。如果未选入任何刷,则系统会使用 DC 中的默认刷来绘图,默认刷 为白色实心刷。 4例子 下面是一个创建、选入并使用自定义实心刷的简单例子代码段: CRect rect(10, 10, 210, 160); CBrush brush(RGB(0, 255, 0); CDC* pDC = GetDC(); pDC-SelectObject(&brush); pDC-Rectangle(&rect); ReleaseDC(pDC); 5设置 DC 刷色 对 Windows NT/2000 及以上的版本,如果只需修改实心刷的颜色,而不改变刷的种类 和风格,则可以不用反复创建和选入新刷,而使用 CDC 类的成员函数 SetDCBrushColor, 来直接设置 DC 刷的颜色: COLORREF SetDCBrushColor( COLORREF crColor ); / 返回原颜色值 对应的获取 DC 中刷颜色的成员函数为: COLORREF GetDCBrushColor( ) const; 与设置 DC 笔类似,也需要先调用 CDC 的成员函数 SelectStockObject 将 DC 刷选入 DC 后,才能使用 SetDCBrushColor 函数来设置 DC 中刷的颜色。例如: pDC-SelectStockObject(DC_BRUSH); / 选入 DC 刷 pDC-SetDCBrushColor(RGB(255, 0, 0); / 设置成红色 17 8.3.5 8.3.5 文本色 可使用 CDC 类的成员函数 SetTextColor/ GetTextColor 和 SetBkColor/ GetBkColor 来分别 设置/获取输出文本的前景色和背景色(默认的前景色为黑色,背景色为空) : COLORREF GetTextColor( ) const; virtual COLORREF SetTextColor( COLORREF crColor ); COLORREF GetBkColor( ) const; virtual COLORREF SetBkColor( COLORREF crColor ); 例如: pDC-TextOut(10, 10, LTest text); pDC-SetTextColor(RGB(0, 255, 0); pDC-TextOut(10, 30, LTest text); pDC-SetBkColor(RGB(255, 0, 0); pDC-TextOut(10, 50, LTest text); 输出结果如图 8-5 所示。 图 8-5 文本色例 8.3.6 8.3.6 绘图工具 Windows 的绘图工具为各种 GDI 对象,被封装在 MFC 对应的 CGDIObject 派生类中。 将 GDI 对象用 SelectObject 函数选入 DC 后,就可利用对应的绘图 工具进行图形绘制。 1GDI 对象 GDI 对象(绘图工具)有笔、刷、位图、字体、调色板、区域 等,对应的 MFC 类为 CPen、CBrush、CBitmap、CFont 等。这些 绘图工具对象类都是 CGDIObject 的派生类, CGDIObject 则是直 而 接从 CObject 类派生的抽象基类,参见图 8-6。 图 8-6 GDI 对象的 类层次结构 其中的 CPen 和 CBrush 类上面已经讲过;CBitmap 和 CFont 将在以后的位图和字体部 分讲;调色板类 CPalette 的使用非常复杂,本书不做介绍;CRgn 为区域(region)类,对应 于窗口中的一个矩形、多边形或(椭)圆区域,可用于移动、拷贝、合并、判断和裁剪,在 GDI 绘图部分也不讲解,但在 GDI+中会做简单的介绍。 18 2选入函数 可用 CDC 类的多态成员函数 SelectObject, 将绘图工具对象选入 DC, 以供绘图时使用: CPen* SelectObject( CPen* pPen ); CBrush* SelectObject( CBrush* pBrush ); virtual CFont* SelectObject( CFont* pFont ); CBitmap* SelectObject( CBitmap* pBitmap ); int SelectObject( CRgn* pRgn ); CGdiObject* SelectObject( CGdiObject* pObject ); 8.4 画图 在 Windows 中,绘图一般在视图窗口的客户区进行,使用的是设备上下文类 CDC 中各 种绘图函数。 为了达到理想的绘图效果, 有时需要先利用 CDC 类设置绘图所用的坐标系 (映 射模式)和各种绘图属性。 8.4.1 8.4.1 映射模式与坐标系 在 Windows 中,绘图都是在当前的映射模式(map mode)下(坐标系中)进行的。而 当前映射模式可以用 CDC 类的成员函数 SetMapMode 来设置。 1默认映射模式 映射模式影响所有的图形和文本绘制函数, 它定义 (将逻辑单位转换为设备单位所使用 的)度量单位和坐标方向,Windows 总是用逻辑单位来绘图。 默认情况下,绘图的默认映射模式为 MM_TEXT,其绘图单位为像素(只要不打印输 出,屏幕绘图使用该模式就够了) 。若窗口客户区的宽和高分别为 w 和 h 像素,则其 x 坐标 是从左到右,范围为 0 w-1;y 坐标是从上到下,范围为 0 h-1,参见图 8-7。 19 图 8-7 默认的 MM_TEXT 图 8-8 非自定义且非 MM_TEXT 映射 映射模式下的窗口坐标系 模式下的(初始)窗口坐标系 (注意 y 在当前窗口中的坐标值为负) 2设置映射模式 可使用 CDC 类的成员函数 GetMapMode 和 SetMapMode 来获得和设置当前映射模式: int GetMapMode( ) const; / 返回当前的映射模式 virtual int SetMapMode( int nMapMode ); / 返回先前的映射模式 映射模式 nMapMode 的取值见表 8-7。 表 8-7 映射模式的 nMapMode 取值与含义 符号常量 MM_TEXT MM_LOMETRIC MM_HIMETRIC MM_LOENGLISH MM_HIENGLISH MM_TWIPS MM_ISOTROPIC MM_ANISOTROPIC 数值 1 2 3 4 5 6 7 8 x 方向 向右 向右 向右 向右 向右 向右 自定义 自定义 y 方向 向下 向上 向上 向上 向上 向上 自定义 自定义 逻辑单位 像素 0.1 mm 0.01 mm 0.01 in 0.001 in 1/1440 in 自定义 自定义 其中,in 为英寸,1 in = 2.54 cm;twips(缇)是一种打印标准单位;isotropic(各向同性的) , 指 x 与 y 方向的单位相同;和 anisotropic(各向异性的) ,则是指 x 与 y 方向的单位可不同。 可见, 除了两种自定义映射模式外, 方向都是向右, 方向也只有 MM_TEXT 的向下, x y 其余的都是向上,与数学上坐标系一致,参见图 8-8。除了 MM_ANISOTROPIC 外,其他所 20 有映射模式的 x 与 y 方向的单位都是相同的。所有映射模式的逻辑坐标的原点(0, 0)最初 都是在窗口的左上角, 但在 CScrollView 的派生类中, MFC 会随用户滚动文档而自动调整逻 辑原点的相对位置(改变视点的原点属性) 。 3单位转换 对所有非 MM_TEXT 映射模式,有如下重要规则: CDC 的成员函数(如各种绘图函数)具有逻辑坐标参数。 CWnd 的成员函数(如各种响应函数)具有设备坐标参数(如鼠标位置 point) 。 位置的测试操作(如 CRect 的 PtInRect 函数)只有使用设备坐标时才有效。 长期使用的值应该用逻辑坐标保存(如窗口滚动后保存的设备坐标就无效了) 。 因此,为了使应用程序能够正确工作,除 MM_TEXT 映射模式外,其他映射模式都需 要进行单位转换。Windows 的 GDI 负责逻辑坐标和设备坐标之间的转换,这可以调用 CDC 类的成员函数 LPtoDP 和 DPtoLP 来进行: void LPtoDP( LPPOINT lpPoints, int nCount = 1 ) const; void LPtoDP( LPRECT lp
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 房地产行业VR看房与智能选房系统方案
- 2026届辽宁省大连市大世界高级中学化学高二上期中综合测试试题含解析
- 节粮节水节电课件
- 市政道路施工安全风险评估与控制措施
- 精准农业智能化技术应用示范区建设计划
- 2025年企业校园招聘流程及面试题目分析大全
- 八下第五单元复习
- 六年级下册科学教材版本对比计划
- 重庆市万州区2023-2024学年高二上学期期中考试物理试题A(原卷版)
- 2025年形状记忆合金项目提案报告
- 模锻工艺培训课件
- 血液透析导管感染
- 静脉溶栓病例汇报
- 国家电投集团招聘考试试题及答案
- 2025届黑龙江省龙东地区数学八下期末学业质量监测试题含解析
- 医疗项目可行性研究报告【范本模板】
- 北京市海淀区师达中学2025年七下数学期末考试试题含解析
- IATF16949:2016内审员培训试卷含答案
- 机械基础教案
- 矿山租用土地协议书
- 美容院入股合同协议范本
评论
0/150
提交评论