如何用mfc绘图_第1页
如何用mfc绘图_第2页
如何用mfc绘图_第3页
如何用mfc绘图_第4页
如何用mfc绘图_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 几何对象的结构和类 为了使用绘图函数,应该先了解绘图所用到的几种表示几何对象的结构和 类。这些结构和类分别定义在头文件 windef.h 和 afxwin.h 中。 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 ); / 低字设为 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 对象之间的运算。 2大小 1)大小结构 SIZE 大小(size 尺寸)结构 SIZE 用来表示矩形的宽 cx 和高 cy: typedef struct tagSIZE 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、高字设为 cy CSizet 类也重载了+、-、+=、-=、=、!=等运算符来支持 CSize 对象和 CSize、POINT、SIZE、RECT 对象之间的运算。 3矩形 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 RECT CRect( LPCRECT lpSrcRect ); CRect( POINT point, SIZE size ); CRect( POINT topLeft, POINT bottomRight ); CRect 类重载了=,+、-,+=、-=,=、!=, int Height( ) const; CSize Size( ) const; CPoint CPoint CPoint CenterPoint( ) const; void SwapLeftRight(); 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); 3) 判断点是否在矩形中 有时需要判断某点(如鼠标位置)是否在某一矩形区域中,这可以调用 CRect 类的 PtInRect 函数来做: BOOL PtInRect( POINT point ) const; 该函数当点 point 在其矩形区域内时,返回真。注意,该矩形区域不包括矩形 的右边界和底边界。例如: CRect rect( 10, 10, 371, 267 ); void CDrawView:OnLButtonUp(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call default if ( rect.PtInRect( point ) ) . . . . CView:OnLButtonUp(nFlags, point); 2 客户区大小和 DC 在绘图前,必须先得到客户区大小和设备上下文 DC。 1获得客户区 绘图一般都是在视图窗口的客户区进行,而客户区的大小在运行时可由用 户改变,为了使绘制的图形能随窗口大小自动改变,必须先得到当前客户区大 小的数据(宽 w 和高 h)。 获取客户区大小的方法有如下两种: 1)在消息响应函数 OnSize 中获得 利用属性窗口的信息页,在视图类中添加 WM_SIZE 消息的响应函数 OnSize。该函数在窗口第一次显示或窗口大小被改变时会被 Windows 系统调用。 其输入参数中的 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 的值为: l SIZE_MAXIMIZED(窗口已 被最大化) l SIZE_MINIMIZED(窗口已 被最小化) l SIZE_RESTORED(窗口已被 改变大小) l SIZE_MAXHIDE(其他窗口 被最大化) l SIZE_MAXSHOW(其他窗口 从最大化还原) 2)调用成员函数 GetClientRect 得到 可在绘图前,定义一个矩形变量 rect,然后再调用 CWnd 类的成员函数 GetClientRect: void GetClientRect( LPRECT lpRect ) const; 得到当前客户区矩形的数据,其中的右(right)与底(bottom)就是客户区的宽与 高(其左 left 与顶 top 都为 0)。例如: RECT rect; GetClientRect( int w = rect.right, h = rect.bottom; 2DC 在 Windows 中,绘图使用的是 MFC 的 DC(Device-Context, 设备上下文)类 CDC 中各种绘图函数。 0)CDC 类 CDC 是 CObject 的直接派生类,CDC 类自己也有若干派生类,其中包括窗口 客户区 DC 所对应的 CClientDC 类、OnPaint 和 OnDraw 消息响应函数的输入参 数中使用的 CPaintDC 类、图元文件对应的 CMetaFileDC 类和整个窗口所对应的 CWindowDC 类。 CDC 类中有许多成员函数,可以用来设置各种绘图环境、属性和参数,以及 绘制各种图形和图像等,将在后面陆续加以介绍。 1)获得 DC 可以从 OnDraw 函数的输入参数 pDC 或调用 CWnd 的成员函数 GetDC: CDC* GetDC( ); 来获得 DC 的指针。 2)释放 DC 因为 Windows 限制可用 DC 的数量,所以 DC 属于稀缺的公用资源。因此, 对每次获得的 DC,在使用完成后必须立即释放。 从 OnDraw 函数的输入参数 pDC 获得的 DC,在该函数运行结束后,系统会自 动释放。但由 GetDC 所获得的 DC,必须自己来释放,这可以通过调用 CWnd 的 成员函数 ReleaseDC 来完成: int ReleaseDC( CDC* pDC ); / 成功返回非 0 例如: void CDrawView:OnLButtonUp(UINT nFlags, CPoint point) ReleaseCapture(); if (m_bLButtonDown) CDC* pDC = GetDC(); pDC-SelectObject(new CPen(PS_SOLID, 0, RGB(255, 0, 0); pDC-SelectStockObject(NULL_BRUSH); pDC- Ellipse (rect); ReleaseDC(pDC); m_bLButtonDown = FALSE; CView:OnLButtonUp(nFlags, point); 3)类 DC 每次从 OnDraw 函数的输入参数或调用 GetDC 所获得的 DC,都是一个全新的 临时缺省 DC。它不能用类变量来长期保存,而且原来选入的各种 GDI 对象全都 被作废,必须从头再来。 为了使选入的各种 GDI 对象一直有效,必须在视图类的 PreCreateWindow 函数中调用 CWnd 类的成员函数 AfxRegisterWndClass: LPCTSTR AFXAPI AfxRegisterWndClass( UINT nClassStyle, HCURSOR hCursor = 0, HBRUSH hbrBackground = 0, HICON hIcon = 0 ); 来修改窗口类的风格属性中的 DC 为类 DC:CS_CLASSDC。如 BOOL CDrawView:PreCreateWindow(CREATESTRUCT return CView:PreCreateWindow(cs); 4)安全 DC 句柄 也可以用 CDC 类的成员函数: HDC GetSafeHdc(); 来获取 CD 所对应窗口(如客户区)的安全 DC 句柄,该句柄在窗口存在期间一 直是有效的。例如,可先定义类变量 HDC m_hDC;,再在适当的地方给它赋值 m_hDC = GetDC()-GetSafeHdc();,然后就可以放心地使用了。例如,可以使 用 CDC 类的成员函数 BOOL Attach(HDC hDC); / 成功返回非 0 来将 CDC 对象与 DC 句柄连接在一起。 3 设置绘图颜色 1颜色 Windows 中的颜色一般用 4 个字节表示(0BGR(整数) = R G B 0(字节序) 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) #define GetBValue(rgb) (LOBYTE(rgb)16) 其中: typedef unsigned long ULONG_PTR; typedef ULONG_PTR DWORD_PTR; #define LOBYTE(w) (BYTE)(DWORD_PTR)(w) / DWORD rgb COLORREF col BYTE GetGValue(DWORD rgb); BYTE GetBValue(DWORD rgb); 2点色(像素) 在 Windows 中,像素(pixel)的颜色是直接由设备上下文类 CDC 的成员函数 SetPixel 来设置的,该函数的原型为: COLORREF SetPixel( int x, int y, COLORREF crColor ); COLORREF SetPixel( POINT point, 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)来画,所以线的颜色就由笔色来确定。 在 MFC 中,笔的属性和功能由 CPen 类提供(CPen 是 CGDIObject 的派生类)。 笔的创建与使用的步骤为: l 创建笔对象:创建笔 类 CPen 对象的方法有如下两种: n 使用构造函数 CPen CPen( int nPenStyle, int nWidth, COLORREF crColor ); 其中: u nPenStyle 为笔 的风格,可取值: PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PSDASHDOTDOT 注意:14 号笔风格只是在笔宽=0 或 1 时有效,笔宽1 时总为实心的。 u nWidth 为笔宽, 与映射模式有关,使用缺省映射时为像素数,若 nWidth = 0, 则不论什么映射模式,笔宽都为一个像素; u crColor 为笔的 颜色值。 例如 CPen* pGrayPen = new CPen(PS_SOLID, 0, RGB(128, 128, 128); CPen grayPen(PS_SOLID, 0, RGB(128, 128, 128); n 使用成员函数 CreatePen BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor ); 如: CPen grayPen; grayPen.CreatePen(PS_SOLID, 0, RGB(128, 128, 128); n 缺省的笔为单像素 宽的实心黑色笔 l 将笔对象选入设备上 下文:为了能使用我们所创建的笔对象,必须先将它选入设备上下文, 这可以调用设备上下文类 CDC 的成员函数 SelectObject 来完成: CPen* SelectObject( CPen* pPen ); 返回值为指向原来笔对象的指针(一般将其保存下来,供下次再装入时使 用)。如 pOldPen = pDC-SelectObject( 另外,Windows 中有一些预定义的笔对象,可用 CDC 的另一成员函数 SelectStockObject 将其选入 DC,其函数原型为: virtual CGdiObject* SelectStockObject( int nIndex ); 预定义的笔对象有 BLACK_PEN(黑色笔)、WHITE_PEN (白色笔)、 NULL_PEN(空笔/无色笔)。例如: pDC-SelectStockObject(BLACK_PEN); l 使用设备上下文画线 状图:画线状图以及面状图的边线,所使用的是当前设备上下文中的笔 对象。线状图有直线、折线、矩形、(椭)圆(弧)等,详见 4)(2) l 将笔对象从设备上下 文中放出:为了能删除使用过的笔对象,必须先将它从设备上下文中释 放出来后,然后才能删除。释放的方法是装入其他的笔对象(一般是重 新装入原来的笔对象)。例如 pDC-SelectObject(pOldPen); l 删除笔对象:为了能 删除笔对象,必须先将其从设备上下文中释放。删除方法有如下几种: n 调用笔类 CDC 的成 员函数 DeleteObject 删除笔的当前内容(但是未删除笔对象,以 后可再用成员函数 CreatePen 在笔对象中继续创建新的笔内容)。 如 pen.DeleteObject(); n 使用删除运算符 delete 将笔对象彻底删除,如 delete pen; n 自动删除:若笔对 象为局部变量,则在离开其作用域时,会被系统自动删除 下面为一段较完整地创建与使用笔的例子代码: CPen pen, *pOldPen; for (int j = 0; j SelectObject( pDC-MoveTo(0, j); pDC-LineTo(40, j); pDC-SelectObject(pOldPen); pen.DeleteObject(); 4面色(刷) 在 Windows 中,面状图必须用刷(brush)来填充,所以面色是由刷色来确定 的。MFC 中的刷类为 CBrush(它也是 CGDIObject 的派生类),刷的创建与使用 的步骤与笔的相似。 l 构造函数有 4 个: n CBrush( ); / 创 建一个刷的空对象 n CBrush( COLORREF crColor ); / 创建颜色为 crColor 的实心刷 n CBrush( int nIndex, COLORREF crColor ); / 创建风格由 nIndex 指定且颜色 为 crColor 的条纹(hatch 孵化)刷,其中 nIndex 可取条纹风格 (Hatch Styles)值: 符号常量 数字常量 风格 HS_HORIZONTAL 0 水平线 HS_VERTICAL 1 垂直线 HS_FDIAGONAL 2 正斜线 HS_BDIAGONAL 3 反斜线 HS_CROSS 4 十字线(正网格) HS_DIAGCROSS 5 斜十字线(斜网格) n CBrush( CBitmap* pBitmap ); / 创建位图为 pBitmap 的图案刷 如:pDC-FillRect( l 与构造函数相对应, 有多个创建不同类型刷的成员函数: n BOOL CreateSolidBrush( COLORREF crColor ); n BOOL CreateHatchBrush( int nIndex, COLORREF crColor ); n BOOL CreatePatternBrush( CBitmap* pBitmap ); n BOOL CreateDIBPatternBrush( HGLOBAL hPackedDIB, UINT nUsage ); n BOOL CreateDIBPatternBrush( const void* lpPackedDIB, UINT nUsage ); n BOOL CreateBrushIndirect( const LOGBRUSH* lpLogBrush ); n BOOL CreateSysColorBrush( int nIndex ); l 预定义的刷对象有 BLACK_BRUSH(黑刷)、DKGRAY_BRUSH(暗灰刷)、GRAY_BRUSH(灰刷) 、HOLLOW_BRUSH(空刷)、LTGRAY_BRUSH(亮灰刷)、NULL_BRUSH(空 刷)、WHITE_BRUSH(白刷) l 缺省的刷为空刷 l 与笔一样,可以用函 数 SelectObject 或 SelectStockObject 将自定义的刷或预定义的刷选 入 DC 中,供绘面状图时使用。 5文本色 可使用 CDC 类的成员函数 SetTextColor 和 SetBkColor 来分别设置输出文 本的前景色和背景色:(缺省的前景色为黑色,背景色空) COLORREF GetTextColor( ) const; virtual COLORREF SetTextColor( COLORREF crColor ); COLORREF GetBkColor( ) 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“); 6绘图工具 1)GDI 对象 Windows 的图形设备接口(GDI = graphics device interface)对象指各种绘图 工具,如笔、刷、位图、字体、调色板、区域等,对应的 MFC 类为 CPen、CBrush、CBitmap、CFont 等。这些图形绘制对象类都是 CGDIObject 的 派生类,而 CGDIObject 则是直接从 CObject 类派生的抽象基类。其中,Windws CE 不支持调色板类 CPalette;CRgn 为区域类,对应于窗口中 的一个矩形、多边形或(椭)圆区域(region),可用于移动、拷贝、合并、判断 和裁剪。 2)选入 可用设备上下文类 CDC 的多态成员函数 SelectObject,来将绘图工具对象 选入设备上下文,以供绘图时使用: 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 ); 3)获取 可用 API 函数 GetCurrentObject 来获得当前在 DC 中的指定类型的绘图对 象: HGDIOBJ GetCurrentObject( HDC hdc, / handle to device context UINT uObjectType / specifies the object-type ); 其中,参数 uObjectType 可取值: OBJ_PEN / Returns the current selected pen. OBJ_BRUSH / Returns the current selected brush. OBJ_PAL / Returns the current selected palette. OBJ_FONT / Returns the current selected font. OBJ_BITMAP / Returns the current selected bitmap. 也可分别调用 CDC 类的下列成员函数来做同样的事: CPen* GetCurrentPen( ) const; CBrush* GetCurrentBrush( ) const; CFont* GetCurrentFont( ) const; CBitmap* GetCurrentBitmap( ) const; CPalette* GetCurrentPalette( ) const; 如: HPEN hPen = (HPEN)GetCurrentObject(pDC-m_hDC, OBJ_PEN); CPen* pPen = CPen:FromHandle(hPen); 等价于: CPen* pPen = pDC- GetCurrentPen( ); 4 画图 在 Windows 中,绘图一般在视图窗口的客户区进行,使用的是设备上下文 类 CDC 中各种绘图函数。 1. 映射模式与坐标系 1)默认映射模式 映射模式(map mode)影响所有的图形和文本绘制函数,它定义(将逻辑单 位转换为设备单位所使用的)度量单位和坐标方向,Windows 总是用逻辑单位 来绘图。 缺省情况下,绘图的默认映射模式为 MM_TEXT,其绘图单位为像素(只要不 打印输出,屏幕绘图使用该模式就够了)。若窗口客户区的宽和高分别为 w 和 h 像素,则其 x 坐标是从左到右,范围为 0 w-1;y 坐标是从上到下,范围为 0 h-1。 2)设置映射模式 可以使用 CDC 类的成员函数 GetMapMode 和 SetMapMode 来获得和设置当前 的映射模式: int GetMapMode( ) const; / 返回当前的映射模式 virtual int SetMapMode( int nMapMode ); / 返回先前的映射模式 映射模式的 nMapMode 取值与含义 符号常量 数字常 量 x 方向 y 方向 逻辑单位的大 小 MM_TEXT 1 向右 向下 像素 MM_LOMETRIC 2 向右 向上 0.1 mm MM_HIMETRIC 3 向右 向上 0.01 mm MM_LOENGLISH 4 向右 向上 0.01 in MM_HIENGLISH 5 向右 向上 0.001 in MM_TWIPS 6 向右 向上 1/1440 in MM_ISOTROPIC 7 自定义 自定义 自定义 MM_ANISOTROPIC 8 自定义 自定义 自定义 可见,除了两种自定义映射模式外,x 方向都是向右,y 方向也只有 MM_TEXT 的向下,其余的都是向上,与数学上一致。除了 MM_ANISOTROPIC 外, 其他所有映射模式的 x 与 y 方向的单位都是相同的。所有映射模式的逻辑坐标 的原点(0, 0)最初都是在窗口的左上角,但在 CScrollView 的派生类中,MFC 会随用户滚动文档而自动调整逻辑原点的相对位置(改变视点的原点属性)。 3)自定义映射模式 自定义映射模式 MM_ISOTROPIC(各向同性,x 与 y 方向的单位必须相同) 和 MM_ANISOTROPIC(各向异性,x 与 y 方向的单位可以不同)的单位和方向, 可以通过用 CDC 类的成员函数 G/SetWindowExt 和 G/SetViewportExt 来获取/设 置窗口和视口的大小来确定: CSize GetWindowExt( ) const; virtual CSize SetWindowExt( int cx, int cy ); virtual CSize SetWindowExt( SIZE size ); CSize GetViewportExt( ) const; virtual CSize SetViewportExt( int cx, int cy ); virtual CSize SetViewportExt( SIZE size ); 其中,cx 或 size.cx 和 cy 或 size.cy 分别为窗口/视口的宽度与高度(逻辑单 位)。 还可以用 CDC 类的成员函数 SetViewportOrg 来设置坐标原点的位置: virtual CPoint SetViewportOrg( int x, int y ); CPoint SetViewportOrg( POINT point ); 例如 void CDrawView:OnDraw(CDC* pDC) CRect rect; GetClientRect(rect); pDC-SetMapMode(MM_ANISOTROPIC); pDC-SetWindowExt(1000,1000); pDC-SetViewportExt(rect.right, -rect.bottom); pDC-SetViewportOrg(rect.right / 2, rect.bottom /2); pDC-Ellipse(CRect(-500, -500, 500, 500); 将当前的映射模式设置为各向异性自定义映射模式,窗口大小为 1000 个逻辑单 位宽和 1000 个逻辑单位高,视口大小同当前客户区,视口的坐标原点设置在当 前客户区的中央。由于使用了负数作为 SetViewportExt 函数的第 2 个参数,所 以 y 轴方向是向上的。 可见,圆被画成了椭圆,x 与 y 方向上的逻辑单位不相同。 4)单位转换 对所有非 MM_TEXT 映射模式,有如下重要规则: l CDC 的成员函数(如各种 绘图函数)具有逻辑坐标参数 l CWnd 的成员函数(如各种 响应函数)具有设备坐标参数(如鼠标位置 point) l 位置的测试操作(如 CRect 的 PtInRect 函数)只有使用设备坐标时才有效 l 长期使用的值应该用逻辑 坐标保存(如窗口滚动后保存的设备坐标就无效了) 因此,为了使应用程序能够正确工作,除 MM_TEXT 映射模式外,其他映射 模式都需要进行单位转换。下面是逻辑单位到设备单位(如像素)的转换公式: x 比例因子 = 视口宽度 / 窗口宽度 y 比例因子 = 视口高度 / 窗口高度 设备 x = 逻辑 x * x 比例因子 + x 原点偏移量 设备 y = 逻辑 y * y 比例因子 + y 原点偏移量 Windows 的 GDI 负责逻辑坐标和设备坐标之间的转换,这可以调用 CDC 类的 成员函数 LPtoDP 和 DPtoLP 来进行: void LPtoDP( LPPOINT lpPoints, int nCount = 1 ) const; void LPtoDP( LPRECT lpRect ) const; void LPtoDP( LPSIZE lpSize ) const; void DPtoLP( LPPOINT lpPoints, int nCount = 1 ) const; void DPtoLP( LPRECT lpRect ) const; void DPtoLP( LPSIZE lpSize ) const; 例如: void CDrawView:OnLButtonDown(UINT nFlags, CPoint point) CRect rect = m_rect; / 逻辑坐标 CClientDC dc(this); dc.SetMapMode(MM_LOENGLISH); dc.LPtoDP(rect); / 转化成设备坐标 if (rect.PtInRect(point) / 位置的测试操作只有使用设备坐 标时才有效 void CDrawView: OnMouseMove (UINT nFlags, CPoint point) float t,y; char buf40; CDC* pDC = GetDC(); pDC-SetMapMode(MM_HIMETRIC); pDC-DPtoLP( / 转化成逻辑坐标 t = t1 + (point.x * dt) / w; sprintf(buf, “%.4fs“, t); pSB- SetPaneText(xV, buf); y = (y0 - point.y) / dy; sprintf(buf, “%.4f“, y); pSB- SetPaneText(yV, buf); 2. 画像素点 画像素点就是设置像素点的颜色,从前面 3)(2)已知道这可由 CDC 的成员 函数 SetPixel 来做,该函数的原型为: COLORREF SetPixel( int x, int y, COLORREF crColor ); 或 COLORREF SetPixel( POINT point, COLORREF crColor ); 其中,x 与 y 分别为像素点的横坐标与纵坐标,crColor 为像素的颜色值。例如 pDC-SetPixel(i, j, RGB(r, g, b); 3画线状图 在 Windows 中,线状图必须用笔来画(笔的创建与使用见前面的 3)(3)), 下面是 CDC 类中可以绘制线状图的常用成员函数: l 当前位置:设置当前 位置为(x, y)或 point:(返回值为原当前位置的坐标) CPoint MoveTo( int x, int y ); 或 CPoint MoveTo( POINT point ); l 画线:使用 DC 中的笔 从当前位置画线到点(x, y)或 point:(若成功返回非 0 值): BOOL LineTo( int x, int y ); 或 BOOL LineTo( POINT point ); l 画折线:使用 DC 中的 笔,依次将点数组 lpPoints 中的 nCount(2)个点连接起来,形成一 条折线: BOOL Polyline( LPPOINT lpPoints, int nCount ); l 画多边形:似画折线, 但还会将最后的点与第一个点相连形成多边形,并用 DC 中的刷填充其 内部区域: BOOL Polygon( LPPOINT lpPoints, int nCount ); l 画矩形:使用 DC 中的 笔画左上角为(x1, y1)、右下角为(x2, y2)或范围为*lpRect 的矩形的 边线,并用 DC 中的刷填充其内部区域: BOOL Rectangle( int x1, int y1, int x2, int y2 ); 或 BOOL Rectangle( LPCRECT lpRect ); 有时需要根据用户给定的两个任意点来重新构造左上角和右下角的点, 例如: rect = CRect(min(p0.x, point.x), min(p0.y, point.y), max(p0.x, point.x), max(p0.y, point.y); l 画圆角矩形:使用 DC 中的笔画左上角为(x1, y1)、右下角为(x2, y2)或范围为*lpRect 的矩 形的边线,并用宽 x3 或 point.x 高 y3 或 point.y 矩形的内接椭圆倒角, 再用 DC 中的刷填充其内部区域: BOOL RoundRect( int x1, int y1, int x2, int y2, int x3, int y3 ); BOOL RoundRect( LPCRECT lpRect, POINT point ); 例如: int d = min(rect.Width(), rect.Height() / 4; pDC- RoundRect(rect, CPoint(d, d); l 画(椭)圆:使用 DC 中的笔在左上角为(x1, y1)、右下角为(x2, y2)或范围为*lpRect 的矩 形中画内接(椭)圆的边线,并用 DC 中的刷填充其内部区域: BOOL Ellipse( int x1, int y1, int x2, int y2 ); BOOL Ellipse( LPCRECT lpRect ); 注意,CDC 中没有画圆的专用函数。在这里,圆是作为椭圆的(宽高相等)特 例来画的。 l 画弧:(x1, y1)与(x2, y2)或 lpRect 的含义同画(椭)圆,(x3, y3)或 ptStart 为弧的起点, (x4, y4)或 ptEnd 为弧的终点:(逆时针方向旋转) BOOL Arc( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ); BOOL Arc( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); BOOL ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4); BOOL ArcTo(LPCRECT lpRect, POINT ptStart, POINT ptEnd); 画圆弧:(其中(x, y)为圆心、nRadius 为半径、fStartAngle 为起始角、 fSweepAngle 为弧段跨角) BOOL AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle); l 画弓弦:参数的含义 同上,只是用一根弦连接弧的起点和终点,形成一个弓形,并用 DC 中 的刷填充其内部区域: BOOL Chord( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ); BOOL Chord( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); 4画填充图 在 Windows 中,面状图必须用刷来填充(刷的创建与使用见前面的 3)(4)) 。上面(2)中的 Polygon、Rectangle、Ellipse 和 Chord 等画闭合线状图的函数, 只要 DC 中的刷不是空刷,都可以用来画对应的面状图(边线用当前笔画,内部 用当前刷填充)。下面介绍的是 CDC 类中只能绘制面状图的其他常用成员函数: l 画填充矩形:用指定 的刷 pBrush 画一个以 lpRect 为区域的填充矩形,无边线,填充区域包 括矩形的左边界和上边界,但不包括矩形的右边界和下边界: void FillRect( LPCRECT lpRect, CBrush* pBrush ); l 画单色填充矩形:似 FillRect,但只能填充单色,不能填充条纹和图案: void FillSolidRect( LPCRECT lpRect, COLORREF clr ); void FillSolidRect( int x, int y, int cx, int cy, COLORREF clr ); l 画饼图(扇形):参 数含义同 Arc,但将起点和终点都与外接矩形的中心相连接,形成一个 扇形区域,用 DC 中的刷填充整个扇形区域,无另外的边线: BOOL Pie( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ); BOOL Pie( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); l 画拖动的矩形:先擦 除线宽为 sizeLast、填充刷为 pBrushLast 的原矩形 lpRectLast,然后 再以线宽为 size、填充刷为 pBrush 画新矩形 lpRectLast。矩形的边框 用灰色的点虚线画,缺省的填充刷为空刷: void DrawDragRect( LPCRECT lpRect, SIZE size, LPCRECT lpRectLast, SIZE sizeLast, CBrush* pBrush = NULL, CBrush* pBrushLast = NULL ); 如:pDC-DrawDragRect(rect, size, rect0, size); l 填充区域: n 用当前刷从点(x, y) 开始向四周填充到颜色为 crColor 的边界: BOOL FloodFill(int x, int y, COLORREF crColor); / 成功返回非 0 n 用当前刷从点(x, y) 开始向四周填充: BOOL ExtFloodFill(int x, int y, COLORREF crColor, UINT nFillType); / 成功返回非 0 u nFillType = FLOODFILLBORDER: 填充到颜色为 crColor 的边界(同 FloodFill);(用于填充内部颜色不同但 边界颜色相同的区域) u nFillType = FLOODFILLSURFACE: 填充所有颜色为 crColor 的点,直到碰到非 crColor 颜色的点为止。(点(x, y)的 颜色也必须为 crColor),(用于填充内部颜色相同但边界颜色可以不同的区 域)。例如: pDC-ExtFloodFill(point.x, point.y, pDC-GetPixel(point), FLOODFILLSURFACE); 5清屏 Windows 没有提供专门的清屏函数,可以调用 CWnd 的下面两个函数调用来 完成该功能: void Invalidate(BOOL bErase = TRUE); void UpdateWindow( ); 或调用 CWnd 的函数 BOOL RedrawWindow( LPCRECT lpRectUpdate = NULL, CRgn* prgnUpdate = NULL, UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE ); 来完成。 例如(菜单项 ID_CLEAR 的事件处理函数): CDrawView:OnClear() / 调用 OnDraw 来清屏 /Invalidate(); /UpdateWindow( ); RedrawWindow( ); 也可以用画填充背景色矩形的方法来清屏,如: RECT rect; GetClientRect( pDC-FillSolidRect( 6在控件上绘图 可以在对话框资源中放置图片控件,并对其类型属性选 Frame。可在对话框 的绘图消息响应函数 OnPaint 或其他函数中,用 CWnd 类的函数 GetDlgItem: CWnd* GetDlgItem( int nID ) const; 来获得图片控件的窗口对象,再用函数 GetDC: CDC* GetDC( ); 由窗口对象得到 DC,然后就可以用该 DC 在控件中画图。如(在 ID 为 IDC_HUESAT 的图片控件上画调色板) void CColorDlg:OnPaint() if (IsIconi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论