zoukankan      html  css  js  c++  java
  • MFC绘图基础 .

    from:http://blog.csdn.net/leolee82/article/details/6992590

    先认识一下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 );// 低字设为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& 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类的PtInRect函数来做:
    BOOL PtInRect( POINT point ) const;
    该函数当点point在其矩形区域内时,返回真。注意,该矩形区域不包括矩形的右边界和底边界


    然后就是关于 设备描述表 的获取和释放了,前一文章提到过, 这里就不提了
    只说一个特别点的概念 “安全DC句柄”
    也可以用CDC类的成员函数:
    HDC GetSafeHdc();
    来获取CD所对应窗口(如客户区)的安全DC句柄,该句柄在窗口存在期间一直是有效的。
    例如,可先定义类变量HDC m_hDC;,再在适当的地方给它赋值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 COLORREF; // 0x00bbggrr
    和一个由红绿蓝三原色构造颜色值的宏RGB:(wingdi.h)
    #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))

    其中,r、g、b为字节变量,取值范围为0~255。其函数说明为:
    COLORREF RGB(
    BYTE bRed, // 红分量
    BYTE bGreen, // 绿分量
    BYTE bBlue // 蓝分量
    );

    例如:
    COLORREF red, gray;
    red = RGB(255, 0, 0);
    gray = RGB(128, 128,128);

    在API中还定义了由COLORREF变量获取各个颜色分量的宏Get?Value:(wingdi.h)
    #define GetRValue(rgb) (LOBYTE(rgb))
    #define GetGValue(rgb) (LOBYTE(((WORD)(rgb)) >> 8))
    #define GetBValue(rgb) (LOBYTE((rgb)>>16))

    (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的派生类)。
    笔的创建与使用的步骤为:

    #1创建笔对象:
    创建笔类CPen对象的方法有如下两种:
    CPen( int nPenStyle, int nWidth, COLORREF crColor );
    其中:
    nPenStyle为笔的风格,可取值:PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PSDASHDOTDOT
    注意:1~4号笔风格只是在笔宽=0或1时有效,笔宽>1时总为实心的
    BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor );

    #2将笔对象选入设备上下文:
    为了能使用我们所创建的笔对象,必须先将它选入设备上下文,这可以调用设备上下文类CDC的成员函数SelectObject来完成:
    CPen* SelectObject( CPen* pPen );返回值为指向原来笔对象的指针(一般将其保存下来,供下次再装入时使用)。
    pOldPen = pDC->SelectObject(&pen);

    另外,Windows中有一些预定义的笔对象,可用CDC的另一成员函数SelectStockObject将其选入DC
    其函数原型为:virtual CGdiObject* SelectStockObject( int nIndex );
    预定义的笔对象有BLACK_PEN(黑色笔)、WHITE_PEN (白色笔)、NULL_PEN(空笔/无色笔)
    例如:pDC->SelectStockObject(BLACK_PEN);

    #3使用设备上下文画线状图:
    画线状图以及面状图的边线,所使用的是当前设备上下文中的笔对象。
    线状图有直线、折线、矩形、(椭)圆(弧)等,详见

    #4将笔对象从设备上下文中放出:
    为了能删除使用过的笔对象,必须先将它从设备上下文中释放出来后,然后才能删除。
    释放的方法是装入其他的笔对象(一般是重新装入原来的笔对象)。例如
    pDC->SelectObject(pOldPen);

    #5删除笔对象:
    为了能删除笔对象,必须先将其从设备上下文中释放。删除方法有如下几种:
    调用笔类CDC的成员函数DeleteObject删除笔的当前内容(但是未删除笔对象,以后可再用成员函数CreatePen在笔对象中继续创建新的笔内容)。

    pen.DeleteObject();
    使用删除运算符delete将笔对象彻底删除,如delete pen;
    自动删除:若笔对象为局部变量,则在离开其作用域时,会被系统自动删除


    (4)面色(刷)
    在Windows中,面状图必须用刷(brush)来填充,所以面色是由刷色来确定的。
    MFC中的刷类为CBrush(它也是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 正斜线
    HS_BDIAGONAL 3 反斜线
    HS_CROSS 4 十字线(正网格)
    HS_DIAGCROSS 5 斜十字线(斜网格)


    CBrush( CBitmap* pBitmap ); // 创建位图为pBitmap的图案刷
    如:pDC->FillRect( &rect, new CBrush( RGB(r, g, b) ) );


    与构造函数相对应,有多个创建不同类型刷的成员函数:
    BOOL CreateSolidBrush( COLORREF crColor );
    BOOL CreateHatchBrush( int nIndex, COLORREF crColor );
    BOOL CreatePatternBrush( CBitmap* pBitmap );
    BOOL CreateDIBPatternBrush( 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(空刷)、LTGRAY_BRUSH(亮灰刷)、NULL_BRUSH(空刷)、WHITE_BRUSH(白刷)
    缺省的刷为空刷

    与笔一样,可以用函数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");


    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
    );来完成。


    5 设置绘图属性除了映射模式外,还有许多绘图属性可以设置
    如背景、绘图方式、多边形填充方式、画弧方向、刷原点等。

    #1.背景
    1)背景色当背景模式为不透明时,背景色决定线状图的空隙颜色(如虚线中的空隙、条纹刷的空隙和文字的空隙)
    可以使用CDC类的成员函数GetBkColor和SetBkColor来获得和设置当前的背景颜色:
    COLORREF GetBkColor( ) const; // 返回当前的背景色
    virtual COLORREF SetBkColor( COLORREF crColor ); // 返回先前的背景色
    // 若出错返回0x800000002)
    背景模式背景模式影响有空隙的线状图的空隙(如虚线中的空隙、条纹刷的空隙和文字的空隙)用什么办法填充。
    可以使用CDC类的成员函数GetBkMode和SetBkMode来获得和设置当前的背景模式:
    int GetBkMode( ) const; // 返回当前背景模式
    int SetBkMode( int nBkMode ); // 返回先前背景模式背景模式的取值nBkMode值 名称 作用

    OPAQUE 不透明的(缺省值) 空隙用背景色填充
    TRANSPARENT 透明的 空隙处保持原背景图不变

    2. 绘图模式绘图模式(drawing mode)指前景色的混合方式,
    它决定新画图的笔和刷的颜色(pbCol)如何与原有图的颜色(scCol)相结合而得到结果像素色(pixel)。
    1)设置绘图模式可使用CDC类的成员函数SetROP2 (ROP = Raster OPeration光栅操作)来设置绘图模式:
    int SetROP2( int nDrawMode );
    其中,nDrawMode可取值:绘图模式nDrawMode的取值

    符号常量 作用 运算结果
    R2_BLACK 黑色 pixel = black
    R2_WHITE 白色 pixel = white
    R2_NOP 不变 pixel = scCol
    R2_NOT 反色 pixel = ~scCol
    R2_COPYPEN 覆盖 pixel = pbCol
    R2_NOTCOPYPEN 反色覆盖 pixel = ~pbCol
    R2_MERGEPENNOT 反色或 pixel = ~scCol | pbCol
    R2_MERGENOTPEN 或反色 pixel = scCol | ~pbCol
    R2_MASKNOTPEN 与反色 pixel = scCol & ~pbCol
    R2_MERGEPEN 或 pixel = scCol | pbCol
    R2_NOTMERGEPEN 或非 pixel = ~(scCol | pbCol)
    R2_MASKPEN 与 pixel = scCol & pbCol
    R2_NOTMASKPEN 与非 pixel = ~(scCol & pbCol)
    R2_XORPEN 异或 pixel = scCol ^ pbCol
    R2_NOTXORPEN 异或非 pixel = ~(scCol ^ pbCol)
    其中,R2_COPYPEN(覆盖)为缺省绘图模式,R2_XORPEN(异或)较常用。

  • 相关阅读:
    OC中Foundation框架之NSDictionary、NSMutableDictionary
    【03_136】Single Number
    【算法】QuickSort
    【02_258】Add Digits
    【01_292】Nim Game
    做题过程中得到的注意点
    No.02——第一次使用Android Studio,并创建出Hello World
    No.01——配置编程环境
    一个好用的代码分享网站
    【数据结构】某些难理解点
  • 原文地址:https://www.cnblogs.com/lidabo/p/2595443.html
Copyright © 2011-2022 走看看