zoukankan      html  css  js  c++  java
  • 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

    常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。

    昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。
  • 相关阅读:
    Linux Socket函数close() 与 shutdown()区别
    Android Performance Patterns S01E03
    Android Performance Patterns S01E02
    Android Performance Patterns S01E01
    Java类初始化顺序
    原子性,可见性,有序性
    UML类图
    Linux 五种IO模型
    Linux学习笔记(一)
    线程的生命周期-java
  • 原文地址:https://www.cnblogs.com/htj10/p/11869492.html
Copyright © 2011-2022 走看看