首页 > 编程知识 正文

mfc cdc 绘,mfc怎么画

时间:2023-05-04 12:15:29 阅读:283890 作者:2957

Windows的GDI(设备图形接口),提供了绘图的基本工具,如:画点、线、多边形、位图以及文本输出等。MFC的设备环境类CDC封装了全部的绘图函数,使得绘制的图形即可以显示,又可以打印。

概述

   Visual C++的CDC(Device Context,设备环境)类是MFC中最重要的类之一,它封装了 绘图所需要的操作,是用户编写图形和文字处理程序必不可少的。当然,绘制图形和文字时还必须指定相应的设备环境。设备环境是由Windows保存的一个数据结构,该结构包含应用程序向设备输出时所需要的信息。

1、 设备环境类CDC

设备环境是由Windows保存的一个数据结构,该结构包含应用程序向设备输

出时所需要的信息,例如:图形是在屏幕上显示还是通过打印机输出。为了能让用户使用一些特殊的设备环境,基类CDC还派生了以下各类:

(1)CPaintDC类,此类比较特殊,它的构造函数和析构函数都是针对OnPaint进

行的。用户一旦获得相关的CDC指针,就可以将它当做任何设备环境(包括屏幕、打印机)指针来使用,CPaintDC类的构造函数会自动调用BeginPaint,而它的析构函数则会自动调用EndPaint。

(2)CClientDC和CWindowDC

A、CClientDC只能在窗口的客户区(不包括边框、标题栏、选单栏以及状态栏)进行绘图,点(0,0)通常指的是客户区的左上角。其构造函数调用GetDC,析构函数调用ReleaseDC函数

B、CWindowDC允许在窗口的任意位置中进行绘图,点(0,0)指整个窗口的左上角。其构造函数调用GetWindowDC,析构函数调用ReleaseDC函数。

(3)CMetaFileDC封装了在一个Windows图元文件中绘图的方法。图元文件是一系列与设备无关的图片的集合,由于它对图像的保存比像素更精确,因而往往在要求较高的场合下使用,例如:AutoCAD的图像保存等。目前的Windows已使用增强格式(enhanced-format)的32位图元文件来进行操作。

 

2、 图形设备接口

Windows为设备环境提供了各种各样的绘图工具,例如:画笔、画刷、字体等。MFC封装了这些工具,并提供相应的类来作为应用程序的图形设备接口(GDI,Graphics Device Interface),这些类有一个共同的抽象基类CGdiObject,如下所示:

类  名      说   明

CBitmap   “位图”是一种位矩阵,每一个显示像素都对应于其中的一个或多个位,用户可以利用位图来表示图象,也可以利用它来创建画刷

CBrush    “画刷”定义了一种位图形式的像素,利用它可对区域内部填充颜色或样式

CFont     “字体”是一种具有某种风格和尺寸的所有字符的完整集合,它常常

被当做资源存于磁盘中,其中有一些还依赖于某种设备

CPalette   “调色板”是一种颜色映射接口,它允许应用程序在不干扰其它应用

程序的前提下,充分利用输出设备的颜色描绘能力

CPen      “画笔”是一种用于画线及绘制有形边框的工具,用户可以指定它的

颜色及宽度,并且可以指定它实线、点线或虚线等

CRgn      “区域”是由多边形、椭圆或二者组合形成的一种范围,可以利用它来进行填充、裁剪以及鼠标点中测试等

 

2.1、使用GDI对象

   选择GDI对象进行绘图时,一般要遵循下列步骤:

(1)定义一个GDI对象(如CPen、CBrush对象),然后用相应的函数(如CreatePen、CreateSolidBrush)创建此GDI对象。但要注意;有些GDI派生类的构造函数允许用户提供足够的信息,从而一步即可完成对象的创建任务,这些类有CPen、CBrush

(2)将构造的GDI对象选入当前设备坏境中,但不要忘记原来的GDI对象保存起来。

(3)绘图结束后,恢复当前设备环境中原来的GDI对象

如下列代码:

void CMyView::OnDraw(CDC *pDC){ CPen penBlack;//定义一个画笔变量 penBlack.CreatePen(PS_SOLID,2,rgb(0,0,0);//创建画笔 CPen *pOldPen=pDC->SelectObject(&penBlack);//将此画笔选入当前设备环境并 //保存原来的画笔 //用此画笔绘图 pDC->MoveTo(…); pDC->LineTo(…); //其他绘图函数 pDC->SelectObject(pOldPen);//恢复设备环境中原来的画笔}

2.2、库存的GDI对象

  除了自定义的GDI对象外,Windows还包含了一些预定义的库存GDI对象。由于它们是Windows系统的一部分,因此用户用不着删除它们。CDC的成员函数

SelectStockObject可以把一个库存对象选入当前设备环境中,并返回原先被选中的对象指针,同时使原先被选中的对象从设备环境中分离出来。如下代码:

void CMyView::OnDraw(CDC *pDC){ CPen newPen(PS_SOLID,2,RGB(0,0,0))pDC->SelectObject(&newPen);pDC->MoveTo(…);pDC->LineTo(…);… //其它绘图函数pDC->SelectStockObject(BLACK_PEN);//newPen被分离出来}

SelectStockObject函数可选用的库存GDI对象类型可以是下列值之一:

BLACK_BRUSH 黑色画刷DKGRAY_BRUSH 深灰色画刷GRAY_BRUSH 灰色画刷HOLLOW_BRUSH 中空画刷LTGRAY_BRUSH 淡灰色画刷NULL_BRUSH 空画刷WHITE_BRUSH 白色画刷BLACK_PEN 黑色画笔NULL_PEN 空画笔WHITE_PEN 白色画笔DEVICE_DEFAULT_FONT 设备默认字体SYSTEM_FONT 系统字体 

图形的绘制通常需要先创建画笔和画刷,然后调用相应的绘图函数。

 

3、 画笔

画笔是Windows应用程序中用于绘制各种直线和曲线的图形工具。它可分为修饰画笔和几何画笔两种类型。在这2种类型中,几何画笔的定义最复杂,它不但有修饰画笔的属性,而且还和画笔的样式、阴影线类型有关,通常用在对绘图有较高要求的场合。而修饰画笔只有简单的几种属性,通常用在简单的直线和曲线等场合。

一个修饰画笔通常具有宽度、风格和颜色3种属性。画笔的宽度用于确定所画的线条宽度,它是用设备单位表示的。默认的画笔宽度是一个像素单位。画笔的颜色确定了所画的线条颜色。画笔的风格确定了所绘图形的线型,它通常有实线、虚线、点线、点划线、双点划线、不可见线和内框线等7种风格。这些风格在Windows中都是以PS_为前缀的预定义的标识。以下为修饰画笔的风格:

PS_SOLID 实线    

PS_DASH虚线    

PS_DOT点线    

PS_DASHDOT 点画线   

PS_DASHDOTDOT双点画线   

PS_NULL不可见线   

PS_INSIDEFRAME 内框线

几何画笔这里不做介绍。

创建一个修饰画笔,可以使用CPen类的CreatePen函数,其原形如下:

BOOL CreatePen(int nPenStyle,int nWidth,COLORREF crColor);

参数分别表示画笔的:风格      宽度        颜色

    此外,还有一个CrearePenIndirect函数也是用于创建画笔对象,它的作用与CreatePen函数是完全一样的,只是画笔的3个属性不是直接出现在函数参数中,而是通过一个LOGPEN结构间接地给出。

BOOL CreatePenIndirect(LPLOGPEN lpLogPen); 

此函数用由LOGPEN结构指针指定的相关参数创建画笔。LOGPEN结构如下。

typedef struct tagLOGPEN{ /* lgpn*/ UINT lopnStyle;//画笔风格, POINT lopnWidth;//POINT结构的y不起作用,而用x表示画笔宽度 COLORREF lopnColor;//画笔颜色}LOGPEN;

值得注意的是:

(1)当修饰画笔的宽度大于1个像素时,画笔的风格只能取PS_NULL、

     PS_SOLID或PS_INSIDEFRAME定义,为其他风格不会起作用。

(2)画笔的创建工作也可在画笔的构造函数进行,它具有下列原形:

CPen(int nPenStyle,int nWidth,COLORREF crColor);

 

4、 画刷

画刷用于指定充填的特性,许多窗口、控件以及其它区域都需要用画刷进行充填绘制,它比画笔的内容更加丰富。画刷的属性通常包括填充色、填充图案和填充样式3种,画刷的填充色和画笔颜色一样,都是使用COLORREF颜色类型,画刷的填充图案通常是用户定义的8*8位图,而填充样式往往是CDC内部定义的一些特性,它们是以HS_为前缀的标识,如书308页图7.3所示。

CBrush类根据画刷属性提供了相应的创建函数,例如创建填充色画刷和填充样式画刷的函数为CreateSolidBrush和CreateHatchBrush,它们的原型如下:

BOOL CreateSolidBrush(COLORREF crColor);//创建填充色画刷

BOOL CreateHatchBrush(int nlndex,COLORREF crColor);//创建填充样式画刷

其中:nIndex用于指定画刷的内部填充样式,而crColor表示画刷的填充色。

   与画笔相类似,也有一个LOGBRUSH逻辑结构用于画刷属性的定义,并通过CBrush的成员函数CreateBrushIndirect来创建,其原型如下:

BOOL CreateBrushIndirect(const LOGBRUSH *lpLogBrush);

其中:LOGBRUSH逻辑结构如下定义:

typedef struct tagLOGBRUSH{ //lb UINT lbStyle; //风格 COLORREF lbColor;//填充色 LONG lbHatch;//填充样式}LOGBRUSH;

  另外,还需注意:

(1)画刷的创建工作也可在其构造函数中进行,它具有下列原型:

CBrush(COLORREF crColor);CBrush(int nIndex,COLORREF crColor);CBrush(CBitmap *pBitmap);

(2)画刷也可用位图来指定其填充图案,但该位图应该是8*8像素,若位图太大,Windows则只使用其左上角的8*8的像素。

(3)画刷仅对绘图函数Chord、Ellipse、FillRect、FrameRect、InvertRect、Pie、Polygon、PolyPolygon、Rectangle、RoundRect有效。  

 

例:绘制一条由点连起的曲线(简单图形)

1、 建一个单文档的应用程序

2、在Viwe.cpp的OnDraw(CDC *pDC)函数里加如下代码:

int data[20]={19,21,32,40,41,39,42,35,33,23,21,20,24, 11,9,19,22,32,40,42};CRect rc;GetClientRect(rc);rc.DeflateRect(50,50);int gridXnums=10,gridYnums=8;int dx=rc.Width()/gridXnums;int dy=rc.Height()/gridYnums;CRect gridRect(rc.left,rc.top,rc.left+dx *gridXnums,rc.top+dy *gridYnums);CPen gridPen(0,0,RGB(0,100,200));CPen *oldPen=pDC->SelectObject(&gridPen);for(int i=0;i<=gridXnums;i++){pDC->MoveTo(gridRect.left+i *dx,gridRect.bottom);pDC->LineTo(gridRect.left+i *dx,gridRect.top);}for(int j=0;j<=gridYnums;j++){pDC->MoveTo(gridRect.left,gridRect.top+j *dy);pDC->LineTo(gridRect.right,gridRect.top+j *dy);}pDC->SelectObject(oldPen);gridPen.Detach();gridPen.CreatePen(0,0,RGB(0,0,200));pDC->SelectObject(&gridPen);CBrush gridBrush(RGB(255,0,0));CBrush *oldBrush=pDC->SelectObject(&gridBrush);POINT ptRect[4]={{-3,-3},{-3,3},{3,3},{3,-3}},ptDraw[4];int deta;POINT pt[256];int nCount=20;deta=gridRect.Width()/nCount;for(i=0;i<nCount;i++){pt[i].x=gridRect.left+i *deta;pt[i].y=gridRect.bottom-(int)(data[i]/60.0 *gridRect.Height());for(j=0;j<4;j++){ptDraw[j].x=ptRect[j].x+pt[i].x;ptDraw[j].y=ptRect[j].y+pt[i].y;}pDC->Polygon(ptDraw,4);}pDC->Polyline(pt,nCount);pDC->SelectObject(oldPen); pDC->SelectObject(oldBrush);


(待完善)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。