分享

MFC学习之 自绘入门

 3D建模仿真 2013-05-21

    使用MFC画点的方法很简单,只需要调用COLORREF CDC::SetPixel( int x, int y, COLORREF crColor )就可以在指定点画上指定颜色,同时返回原来的颜色。COLORREF CDC::GetPixel( int x, int y)可以得到指定点的颜色。在Windows中应该少使用MFC的画点函数,因为这样做的执行效率比较低。

    刷子和画笔是MFC作图中是使用最多的GUI对象,本节在讲解刷子和画笔使用方法的同时也讲述一写基本作图函数。

    在画点或画线时系统使用当前DC中的画笔,所以在创建画笔后必须将其选入DC才会在绘图时产生效果。画笔可以通过CPen对象来产生,通过调用CPen::CreatePen( int nPenStyle, int nWidth, COLORREF crColor )来创建。其中nPenStyle指名画笔的风格,可取如下值:

  • PS_SOLID 实线   
  • PS_DASH 虚线,宽度必须唯一   
  • PS_DOT 点线,宽度必须唯一   
  • PS_DASHDOT 点划线,宽度必须唯一   
  • PS_DASHDOTDOT 双点划线,宽度必须唯一  
  • PS_NULL 空线,使用时什么也不会产生  
  • PS_ENDCAP_ROUND 结束处为圆形   
  • PS_ENDCAP_SQUARE 结束处为方形  

nWidth和crColor为线的宽度和颜色。

    刷子是在画封闭曲线时用来填充的颜色,例如当你画圆形或方形时系统会用当前的刷子对内部进行填充。刷子可利用CBrush对象产生。通过以下几种函数创建刷子:

  • BOOL CreateSolidBrush( COLORREF crColor ); 创建一种固定颜色的刷子
  • BOOL CreateHatchBrush( int nIndex, COLORREF crColor ); 创建指定颜色和网格的刷子
  • BOOL CreatePatternBrush( CBitmap* pBitmap ); 创建以8*8位图为模板的刷子

在选择了画笔和刷子后就可以利用MFC的DC作图函数进行作图了,基本的画线函数有以下几种

  • CDC::MoveTo( int x, int y ); 改变当前点的位置
  • CDC::LineTo( int x, int y ); 画一条由当前点到参数指定点的线
  • CDC::BOOL Arc( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); 画弧线
  • CDC::BOOL Polyline( LPPOINT lpPoints, int nCount ); 将多条线依次序连接

基本的作图函数有以下几种:

  • CDC::BOOL Rectangle( LPCRECT lpRect ); 矩形
  • CDC::RoundRect( LPCRECT lpRect, POINT point ); 圆角矩形
  • CDC::Draw3dRect( int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight ); 3D边框
  • CDC::Chord( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); 扇形
  • CDC::Ellipse( LPCRECT lpRect ); 椭圆形
  • CDC::Pie( LPCRECT lpRect, POINT ptStart, POINT ptEnd );
  • CDC::Polygon( LPPOINT lpPoints, int nCount ); 多边形

    对于矩形,圆形或类似的封闭曲线,系统会使用画笔绘制边缘,使用刷子填充内部。如果你不希望填充或是画出边缘,你可以选入空刷子(NULL_PEN)或是(NULL_BRUSH)空笔。

下面的代码创建一条两象素宽的实线并选入DC。并进行简单的作图:

{

...

        CPen pen;

        pen.CreatePen(PS_SOLID,2,RGB(128,128,128));

        CPen* pOldPen=(CPen*)dc.SelectObject(&pen);

        dc.SelectStockObject(NULL_BRUSH);//选入空刷子

        dc.Rectangle(CRect(0,0,20,20));//画矩形

...

}

注:SelectObject该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。

       StretchBlt : 函数从源矩形中复制一个位图到目标矩形,必要时按目前目标设备设置的模式进行图像的拉伸或压缩。

       SelectStockObject :其作用是选择系统预定义的GDI对象(stock -库存)。由于是系统定义的公用函数,所以用完以后也不用手动删除。
       而SelectObject则是选择你自己自定义的的GDI对象,用完之后要DelectObject();

 bitblt : 直接按你指定的大小输出源dc到目标dc,而strechblt会调整你源dc大小,使之适应你所指定的目标dc大小,再输出。

也就是说,strechblt输出的图总是完整的,而且充满你指定的目标DC区域,而bitblt则可能输出的图是不完整的,也可能无法充满目标dc制定区域。


 在Windows中可以将预先准备好的图像复制到显示区域中,这种内存拷贝执行起来是非常快的。在Windows中提供了两种使用图形拷贝的方法:通过设备相关位图(DDB)和设备无关位图(DIB)。

关于DDB 和 DIB : http://blog.csdn.net/qsycn/article/details/4485523

    DDB可以用MFC中的CBitmap来表示,而DDB一般是存储在资源文件中,在加载时只需要通过资源ID号就可以将图形装入。BOOL CBitmap::LoadBitmap( UINT nIDResource )可以装入指定DDB,但是在绘制时必须借助另一个和当前绘图DC兼容的内存DC来进行。通过CDC::BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop )绘制图形,同时指定光栅操作的类型。BitBlt可以将源DC中位图复制到目的DC中,其中前四个参数为目的区域的坐标,接下来是源DC指针,然后是源DC中的起始坐标,由于BitBlt为等比例复制,所以不需要再次指定长宽,(StretchBlt可以进行缩放)最后一个参数为光栅操作的类型,可取以下值:

  • BLACKNESS 输出区域为黑色   
  • DSTINVERT 反色输出区域   
  • MERGECOPY 在源和目的间使用AND操作   
  • MERGEPAINT 在反色后的目的和源间使用OR操作   
  • NOTSRCCOPY 将反色后的源拷贝到目的区   
  • PATINVERT 源和目的间进行XOR操作  
  • SRCAND 源和目的间进行AND操作 
  • SRCCOPY 复制源到目的区  
  • SRCINVERT 源和目的间进行XOR操作   
  • SRCPAINT 源和目的间进行OR操作   
  • WHITENESS 输出区域为白色  

下面用代码演示MFC下的位图使用:

CYourView::OnDraw(CDC* pDC)

{

        CDC memDC;//定义一个兼容DC

        memDC.CreateCompatibleDC(pDC);//创建DC

        CBitmap bmpDraw;

        bmpDraw.LoadBitmap(ID_BMP) ;//装入DDB

        CBitmap* pbmpOld=memDC.SelectObject(&bmpDraw) ;

//保存原有DDB,并选入新DDB入DC

        pDC->BitBlt(0,0,20,20,&memDC,0,0,SRCCOPY) ;

//将源DC中(0,0,20,20)复制到目的DC(0,0,20,20)

        pDC->BitBlt(20,20,40,40,&memDC,0,0,SRCAND);

 //将源DC中(0,0,20,20)和目的DC(20,20,40,40)中区域进行AND操作

        memDC.SelectObject(pbmpOld) ;//选入原DDB

}

(图标并不是一个GDI对象,所以不需要选入DC)在MFC中没有一个专门的图标类,因为图标的操作比较简单,使用HICON CWinApp::LoadIcon( UINT nIDResource )或是HICON CWinApp::LoadStandardIcon( LPCTSTR lpszIconName ) 装入后就可以利用BOOL CDC::DrawIcon( int x, int y, HICON hIcon )绘制。由于在图标中可以指定透明区域,所以在某些需要使用非规则图形而且面积不大的时候使用图标会比较简单。下面给出简单的代码:

OnDraw(CDC* pDC)

{

        HICON hIcon1=AfxGetApp()->LoadIcon(IDI_I1);

        HICON hIcon2=AfxGetApp()->LoadIcon(IDI_I2);

        pDC->DrawIcon(0,0,hIcon1);

        pDC->DrawIcon(0,40,hIcon2);

        DestroyIcon(hIcon1);

        DestroyIcon(hIcon2);

}

    同样在MFC也没有提供一个DIB的类,所以在使用DIB位图时我们需要自己读取位图文件中的头信息,并读入数据,并利用API函数StretchDIBits绘制。位图文件以BITMAPFILEHEADER结构开始,然后是BITMAPINFOHEADER结构和调色版信息和数据,其实位图格式是图形格式中最简单的一种,而且也是Windows可以理解的一种。我不详细讲解DIB位图的结构,提供一个MFC的CDib类供大家使用,这个类包含了基本的功能如:Load,Save,Draw。


CDC类常用绘图函数类常用绘图函数:
Arc:绘制一段弧:

Chord:绘制弦形:

Ellipse:绘制椭圆或圆:

MoveTo:将当前位置移动到指定位置:

LineTo:从当前位置到指定位置画一条直线:

Polyline:画连接指定点的折线段:

PolyBezler:根据两个端点和两个控制点画贝塞尔曲线

Pie:画冰块:

Polygon:根据两个或两个以上的顶点绘制一个多边形:

Rectangle:根据指定的左上角和右下角坐标绘制一个矩形:

RoundRect:画圆角矩形:

SetPixel:画一个点

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多