gdi编程基础

一. DC 1. 概念 设备上下文:通俗来说就是,我们在绘图时用来响应软,硬件消息的媒介。MFC为我们封装了CDC类,那我们就结合MSDN来学习,就显得不会那么乱了。 2. CDC,CPaintDC, CClientDC, CWindowDC,CMetaFileDC CDC:DC的基类。 CPaintDC:跟进下源代码,发现本质上调用了BeginPaint()和E...
摘要由CSDN通过智能技术生成

目录

一. DC

        1. 概念

        2. CDC,CPaintDC, CClientDC, CWindowDC, CMetaFileDC

        3. 用法

        4. 绘图流程 

 二.  CPen

         1. 说明

         2. 使用

         3.  闪烁矩形

三.  画刷

        1. 说明

        2. 使用

        3. 反转区域颜色 

四. CFont

        1.说明           

        2. 创建

        3. 获取

        4. 绘制 

五.  文本

        1.  说明

        2. 使用

六.  CBitmap

        1. 说明

        2. 加载位图                 

        3. 位图拷贝

七. BeginPath

      1. 说明          

        2. 使用

八. CRgn

        1. 说明

        2.  使用

        3. 补充

九. 双缓冲

        1. 说明

        2. 使用

十. gdi+

       1. 说明

        2. 创建

        3. 绘制渐变色

        4. 基数样条函数

        5. 持久路径对象

        6. 可伸缩区域

        7. Alpha混合模式

        8. 扩展字体功能

十一. 总结


一. DC

        1. 概念

                设备上下文:通俗来说就是,我们在绘图时用来响应软,硬件消息的媒介。MFC为我们封装了CDC类,那我们就结合MSDN来学习,就显得不会那么乱了。

        2. CDC,CPaintDC, CClientDC, CWindowDC, CMetaFileDC

                CDC:DC的基类。 

                CPaintDC:跟进下源代码,发现本质上调用了BeginPaint()EndPaint(),所以只能存在于WM_PAINT消息响应里,原因是它还需要帮忙清除消息列表里的WM_PAINT消息。原点坐标为客户区的左上角。

                CClientDC:原点坐标在客户区左上角,在哪里使用就没有限制了。

                CWindowDC:原点坐标在窗口的左上角,使用也没有限制。

                CMetaFileDC:高精度绘制,如CAD,基本用不到。

        3. 用法

                (1) 使用实例

        void CDlgDC::OnPaint()
        {
	        CPaintDC dc(this); // device context for painting

	        CRect stRect;
	        GetClientRect(&stRect);
	        dc.FillSolidRect(&stRect, RGB(240, 255, 255));

	        dc.TextOut(0, 0, _T("PaintDC Draw"));

	        CClientDC objClientDC(this);
	        objClientDC.TextOut(100, 0, _T("ClientDC Draw"));

	        //获取窗口DC
	        CDC* pDC = CDC::FromHandle(::GetDC(this->m_hWnd));
	        pDC->TextOut(200, 0, _T("CDC draw"));
	        ::ReleaseDC(GetSafeHwnd(), pDC->GetSafeHdc());
        }


        ... ...


        void CDlgDC::InitDraw()
        {
	        //坐标原点为窗口的左上角(0,0),故可以在标题栏作画
	        CWindowDC objWindowDC(this);
	        objWindowDC.TextOut(0, 0, _T("WindowDC Draw"));
        }

       //为了作测试,窗口样式还是Dialog带标题栏,所以在这里重绘标题栏
        void CDlgDC::OnNcPaint() 
        {
	        InitDraw();

	        // TODO:  在此处添加消息处理程序代码
	        // 不为绘图消息调用 CDialogEx::OnNcPaint()
        }

                (2) 获取/释放窗口DC

	    //获取窗口DC
	    CDC* pDC = CDC::FromHandle(::GetDC(this->m_hWnd));
	    pDC->TextOut(200, 0, _T("CDC draw"));
	    ::ReleaseDC(GetSafeHwnd(), pDC->GetSafeHdc());

        4. 绘图流程 

                 (1) 前面讲了一下DC的概念,查看一下MSDNCDC类会发现函数太多,看得头晕,那我们就来梳理下。

                 (2) 先说下通用用法,绘图前一定选一块"画布"(DC), 再搞一种"画图工具"(gdi对象, 画笔,画刷等),然后开始绘制(绘图函数)。除了几个特殊函数,基本上都满足这个绘图流程。

                (3) 那我们再细分下:与画线有关的用CPen;填充相关的用CBrush;字体与文本相关的CFont;与图片相关的CBitmap;路径相关(填充多边形)的BeginPath;裁剪窗体相关的CRgn;不常用的先不说,然后绘图时我们再将这些组合起来,就实现了绘图。后面针对每个gdi对象我们再详细聊聊。

	    //创建DC
	    CClientDC objDC(this);

	    //创建GDI对象
	    CPen objPen;
	    objPen.CreatePen(PS_SOLID, 4, (COLORREF)-1);

	    //将GDI象装进DC中
	    CPen* pOldPen = objDC.SelectObject(&objPen);

	    //绘制
	    objDC.Rectangle(CRect(0, 0, 100, 100));

	    //释放
	    objDC.SelectObject(pOldPen);
	    ::DeleteObject(objPen);

                (4) 最后我们再聊聊资源释放的问题, objDC.SelectObject(pOldPen);前面画刷被选入设备,如果不恢复缺省或系统画刷,::DeleteObject(objPen)就会失效,造成内存泄露,而且不会报错,只会一直累加,造成程序的崩溃。

 二.  CPen

         1. 说明

                   创建画笔时要注意,部分画笔样式(PS_DOT等)只在限制的画笔宽度下才有有效。创建画笔的两种方式。    

	    //方式1
        CPen objPen;
	    objPen.CreatePen(PS_SOLID, 4, RGB(0, 245, 255));
	    //方式2
	    //LOGPEN stLogPen;
	    //stLogPen.lopnStyle = PS_SOLID;
	    //stLogPen.lopnWidth = CPoint(4, 4);
	    //stLogPen.lopnColor = RGB(0, 245, 255);
	    //objPen.CreatePenIndirect(&stLogPen);

         2. 使用

    void CDlgPen::InitDraw()
    {
	    CClientDC objDC(this);

    	//获取客户端区域
	    CRect stRect;
	    GetClientRect(&stRect);

    	//画点
	    for (int iNum = 0; iNum < 10; iNum++)
    	{
	        objDC.SetPixel(0 + iNum * 10, 10, RGB(255, 0, 0));
        }
	
	    //画笔
	    CPen objPen;
	    objPen.CreatePen(PS_SOLID, 4, RGB(0, 245, 255));
	    //CreatePenIndirect效果一样
	    //LOGPEN stLogPen;
    	//stLogPen.lopnStyle = PS_SOLID;
	        //stLogPen.lopnWidth = CPoint(4, 4);
    	//stLogPen.lopnColor = RGB(0, 245, 255);
	    //objPen.CreatePenIndirect(&stLogPen);

	    CPen* pOldPen = objDC.SelectObject(&objPen);

	    //画线
	    objDC.MoveTo(200, 20);
	    objDC.LineTo(700, 70);

	    //画弧
    	objDC.Arc(CRect(10, 10, 110, 110), CPoint(20, 20), CPoint(100, 100));

	    objDC.MoveTo(0, 120);
	    objDC.ArcTo(CRect(0, 120, 100, 220), CPoint(0, 120), CPoint(100, 220));

	    objDC.MoveTo(0, 350);
	    objDC.AngleArc(100, 350, 100, 0.0, 180.0);//圆点, 半径, 起始角度, 结束角度

	    //画矩形
	    objDC.Rectangle(CRect(0, 400, 120, 480));

	    //画圆角矩形
	    objDC.RoundRect(CRect(200, 100, 340, 200), CPoint(10, 10));

	    //画椭圆
	    objDC.Ellipse(CRect(220, 220, 360, 320));

	    //画饼图
	    objDC.Pie(CRect(220, 340, 360, 460), CPoint(220, 340), CPoint(360, 360));

	    //画封闭图形
	    CPoint aptData[] = {CPoint(500, 200), CPoint(600, 100), CPoint(700, 200), CPoint(630, 250), CPoint(550,
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值