MFC中CDC类及其派生类

  • CDC类(设备上下文类)用于绘图
CDC派生类  封装的GDI函数 功能说明
CPaintDC类

BeginPaint

EndPaint

标准客户区绘图,窗口刷新时不消失。

只在WM_PAINT消息下使用(OnPaint())

CWindowDC类

GetWindowDC

ReleaseDC

非客户区绘图,窗口刷新时不消失,

在WM_NCPAINT消息下使用

CClientDC类

GetDC

ReleaseDC

临时客户区绘图,窗口刷新时消失,
在任何情况下都可以使用
CMemDC类

CreateCompatibleDC

DeleteDC

VC6.0未实现,网上可以找到。

CMemDC类:

#ifndef __MEMDC_H__
#define __MEMDC_H__
//Author:www.baojy.com

class CMemDC :public CDC
{
    CSize m_size;
public:
    void BitRgn(
        CRgn &rgn,            //目标区域
        COLORREF crTrans    // 透明色
        )
    {
        int i = 0,j=0;
        rgn.CreateRectRgn(0,0,0,0);
        while(i<m_size.cx)
        {
            j = 0;
            while(j<m_size.cy)
            {
                if(GetPixel(i,j) - crTrans)
                {
                    CRgn r;
                    r.CreateRectRgn(i,j,i+1,j+1);
                    rgn.CombineRgn(&rgn,&r,RGN_OR);
                }
                ++j;
            }
            ++i;
        }
    }
    void BitTrans(
        int nXDest,        // 目标起点X
        int nYDest,        // 目标起点Y
        int nWidthDest,    // 目标宽度
        int nHeightDest,// 目标高度
        CDC* pDC,        // 目标DC
        int nXSrc,        // 来源起点X
        int nYSrc,        // 来源起点Y
        COLORREF crTrans// 透明色
        )
    {
        CMemDC dcImage(nWidthDest, nHeightDest,pDC);//临时DC
        CBitmap bmpMask;
        bmpMask.CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);            // 创建单色掩码位图
        CDC dcMask;//掩码DC 
        dcMask.CreateCompatibleDC(pDC);
        dcMask.SelectObject(bmpMask);
        //将载入位图的内存DC中的位图,拷贝到临时DC中
        dcImage.BitBlt( 0, 0, nWidthDest, nHeightDest, this, nXSrc, nYSrc, SRCCOPY);
        
        // 设置临时DC的透明色
        dcImage.SetBkColor(crTrans);
        //掩码DC的透明区域为白色其它区域为黑色
        dcMask.BitBlt(0, 0, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCCOPY);
        
        //临时DC透明区域为黑色,其它区域保持不变
        dcImage.SetBkColor(RGB(0,0,0));
        dcImage.SetTextColor(RGB(255,255,255));
        dcImage.BitBlt( 0, 0, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);
        
        // 目标DC透明部分保持屏幕不变,其它部分变成黑色
        pDC ->SetBkColor(RGB(255,255,255));
        pDC ->SetTextColor(RGB(0,0,0));
        pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);
        pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCPAINT);
    } 
    void StretchTrans(
        int nXDest,            // 目标起点X
        int nYDest,            // 目标起点Y
        int nWidthDest,     // 目标宽度
        int nHeightDest,    // 目标高度
        CDC* pDC,            // 目标DC
        int nXSrc,            // 来源起点X
        int nYSrc,            // 来源起点Y
        int nWidthSrc,        // 来源宽度
        int nHeightSrc,        // 来源高度
        COLORREF crTrans    // 透明色
        )
    {
        CMemDC dcImage(nWidthDest, nHeightDest,pDC);//临时DC
        CBitmap bmpMask;
        // 创建单色掩码位图
        bmpMask.CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);
        CDC dcMask;
        dcMask.CreateCompatibleDC(pDC);
        dcMask.SelectObject(bmpMask);
    
        // 将载入位图的内存DC中的位图,拷贝到临时DC中
        if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
            dcImage.BitBlt(0, 0, nWidthDest, nHeightDest, this, nXSrc, nYSrc, SRCCOPY);
        else
            dcImage.StretchBlt(0, 0, nWidthDest, nHeightDest, 
                this, nXSrc, nYSrc, nWidthSrc, nHeightSrc, SRCCOPY);
        
        // 设置临时DC的透明色
        dcImage.SetBkColor( crTrans);
        //掩码DC的透明区域为白色其它区域为黑色
        dcMask.BitBlt(0,0,nWidthDest, nHeightDest,&dcImage,0,0,SRCCOPY);
        
        //临时DC透明区域为黑色,其它区域保持不变
        dcImage.SetBkColor(RGB(0,0,0));
        dcImage.SetTextColor(RGB(255,255,255));
        dcImage.BitBlt(0, 0, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);
        
        // 目标DC透明部分保持屏幕不变,其它部分变成黑色
        pDC ->SetBkColor(RGB(255,255,255));
        pDC ->SetTextColor(RGB(0,0,0));
        pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);
        pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCPAINT);
    }    
    CMemDC()
    {
        m_size.cx = m_size.cy = 0;
    }
    //从资源中加载位图
    BOOL LoadBitmap(UINT nBitmapID,CDC* pDC=NULL)
    {
        CBitmap bitmap;
        bitmap.LoadBitmap(nBitmapID);
        BITMAP bm;
        bitmap.GetBitmap(&bm);
        m_size.cx = bm.bmWidth;
        m_size.cy = bm.bmHeight;
        CreateCompatibleDC(pDC);
        SelectObject(bitmap);
        return TRUE;
    }
    CMemDC(UINT nBitmapID,CDC* pDC=NULL)
    {
        LoadBitmap(nBitmapID,pDC);
    }
    //从.bmp文件中加载位图
    BOOL LoadBitmap(LPCSTR szBitmapFile,CDC* pDC=NULL)
    {
        HBITMAP hBitmap = (HBITMAP)LoadImage(AfxGetInstanceHandle(),
            szBitmapFile,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
        BITMAP bm;
        GetObject(hBitmap,sizeof(bm),&bm);
        m_size.cx = bm.bmWidth;
        m_size.cy = bm.bmHeight;
        CreateCompatibleDC(pDC);
        SelectObject(hBitmap);        
        return TRUE;
    }
    CMemDC(LPCSTR szBitmapFile,CDC* pDC=NULL)
    {
        LoadBitmap(szBitmapFile,pDC);
    }
    //创建一张空白内存画布
    BOOL Create(int cx,int cy,CDC* pDC = NULL)
    {
        CreateCompatibleDC(pDC);
        CBitmap bitmap;
        if(pDC)
            bitmap.CreateCompatibleBitmap(pDC,cx,cy);
        else
            bitmap.CreateCompatibleBitmap(&CClientDC(NULL),cx,cy);
        m_size.cx = cx;
        m_size.cy = cy;
        SelectObject(bitmap);
        return TRUE;
    }
    CMemDC(int cx,int cy,CDC* pDC = NULL)
    {
        Create(cx,cy,pDC);
    }
    //摧毁
    BOOL DeleteDC()
    {
        if(!GetSafeHdc())
            return TRUE;
        CBitmap * pBitmap = GetCurrentBitmap();
        pBitmap ->DeleteObject();
        return CDC::DeleteDC();
    }
    ~CMemDC()
    {
        DeleteDC();
    }
    inline int Width(){return m_size.cx;}
    inline int Height(){return m_size.cy;}
};

#endif //__MEMDC_H__
View Code

 例子:

 

/* Pen Styles */
#define PS_SOLID            0
#define PS_DASH             1       /* -------  */
#define PS_DOT              2       /* .......  */
#define PS_DASHDOT          3       /* _._._._  */
#define PS_DASHDOTDOT       4       /* _.._.._  */
#define PS_NULL             5

 

    // CPaintDC 是标准客户区绘画。刷新不消失。CPaintDC中封装了BeginPaint(),EndPaint()
    // 而CClientDC 是临时客户区绘图,刷新会消失。封装了GetDC(),ReleaseDC()
    CPaintDC dc(this); // device context for painting
    CRect rect;
    GetClientRect(&rect);
    dc.Ellipse(rect);//画椭圆
    //画线
    dc.MoveTo(0,0);
    dc.LineTo(rect.right,rect.bottom);
    //画矩形,利用当前画笔绘制矩形,内部由当前画刷填充。
    dc.Rectangle(20,20,100,80);
    //画圆角矩形
    dc.RoundRect(20,90,100,150,10,10);//前4个数是矩形坐标,后2个是圆角的大小


---------------------------------
/*    rect.bottom = 30;
    dc.FillSolidRect(&rect,RGB(0,100,255));
    CString str = "测试CPaintDC类";
    dc.DrawText(str,&rect,  DT_CENTER | DT_VCENTER | DT_SINGLELINE); // DT_VCENTER | DT_SINGLELINE 配合使用才有上下居中的效果
*/
/*    调用FillSolidRect时,以前用SetBkColor设置的背景色,被设置为clr指定的颜色。
    就是说你的背景色已经变成了FillSolidRect设置的颜色了。
    也许正常是看不出来的。
    但当以再用画笔画PS_DOT类的线时,
    你会发现你虚线原来的空白地方变成了FillSolidRect设置的颜色了。
    用FillSolidRect时一定要注意。
    可以用CDC::FillRect()
*/
    rect.bottom = 30;
    CBrush brush;
    brush.CreateSolidBrush(RGB(0,100,255));
    dc.FillRect(&rect,&brush);
    CString str = "测试CPaintDC类";
    dc.SetBkMode(TRANSPARENT);
    dc.DrawText(str,&rect,  DT_CENTER | DT_VCENTER | DT_SINGLELINE); // DT_VCENTER | DT_SINGLELINE 配合使用才有上下居中的效果
    
    dc.MoveTo(20,120);
    dc.LineTo(120,120);
    CPen p1(PS_SOLID, 3, RGB(0,0,255));
    CPen* pOldPen = dc.SelectObject(&p1); // 返回前一个画笔
    dc.MoveTo(20,140);
    dc.LineTo(120,140);

//    CPen p2(PS_DASHDOTDOT, 1, RGB(255,0,0)); // 注意,虚线只有在宽度为1时,才有效
    CPen p2;
    LOGPEN logPen = {PS_DASHDOTDOT, 1};
    logPen.lopnColor = RGB(255,0,0);
    p2.CreatePenIndirect(&logPen);
    dc.SelectObject(&p2);
    dc.MoveTo(20,150);
    dc.LineTo(120,150);
    dc.Rectangle(20,160,120,200);
    dc.Ellipse(20,160,110,200);

    CPen p3;
    p3.CreatePen(PS_DASH, 1, RGB(255,0,0));
    dc.SelectObject(&p3);
    // 画多边形
    CPoint ps[] = {CPoint(70,200), CPoint(20,300),CPoint(120,300)};
    dc.Polygon(ps, sizeof(ps)/sizeof(ps[0]));

    CRect rect2(150,50,300,150);
    dc.Ellipse(150,50,300,150);
    dc.SelectObject(&p1);
    CPoint pt1(100,50),pt2(300,200);
//    dc.Arc(&rect2,pt1,pt2); // 画弧线(非闭合)
    dc.Chord(&rect2,pt1,pt2); // 画弧线(闭合)
    dc.MoveTo(pt1);
    dc.LineTo(rect2.CenterPoint());
    dc.LineTo(pt2);

    LOGPEN pl;
    p3.GetLogPen(&pl);

    HPEN hPen = p3;// HPEN hPen = (HPEN)p3.GetSafeHandle();
    CPen* pPen;
    pPen = CPen::FromHandle(hPen);

/*    CPen p4(PS_NULL,666,RGB(55,55,55)); // 空画刷,就是后面的宽度和颜色无效,
    dc.SelectObject(&p4);
//    dc.Rectangle(150,50,300,150); // 无边框默认填充白色
    CBrush br(RGB(255,0,255));
    dc.SelectObject(&br);
    dc.Rectangle(150,50,300,100); // 无边框填充紫色 相当于     dc.FillSolidRect(CRect(150,50,300,100),RGB(255,0,255));
*/    
View Code

 

posted @ 2019-11-15 20:53  htj10  阅读(736)  评论(0编辑  收藏  举报
TOP