• 让CDC输出的图形具有保持功能的三种方法1


      看了孙鑫老师的书后,顺便对已绘制的图形具有保持功能作一下总结。总的来说,有三种方法可以图形具体保持功能。分别如下:

    1. 在每次绘制图形后,用一个对象数组来保存已经绘制的样式以及图形坐标 。只在在窗体重绘时重新来绘制这些保存的图形数据即可。
    2. 采用元数据文件,它采用了元数据文件设备上下文来保存已绘制的图形,每次窗体重绘时再播放元数据文件来实现图形保持功能。
    3. 这种方法采用一个兼容DC,它利用一个兼容位图(相当于一块画布),用户在所有绘制图形操作都在这一块画布上进行,这块画布同时也保存了用户的所有绘制操作,当窗体时行重绘时,当前窗口重绘DC把已绘制好图形的画布直接拷贝到当前DC中,这样就达到了图形保持功能。


      分别就这三情况,我给出了参考代码,以后仅作笔记使用。

      第一种最普通的方法:

        

    第一种:保存重绘图形数据
    //自定义一个类,提供重绘图形数据
    class CGraph  
    {
    public:
        CGraph();
        CGraph(UINT m_nDrawType,CPoint m_ptOrigin,CPoint m_ptEnd);
        
    virtual ~CGraph();
    public:
        UINT m_nDrawType;  
    //绘制类型
        CPoint m_ptOrigin; //图形原点
        CPoint m_ptEnd;    //图形终点
    }; 


    接下来,在每次绘制图形后保存需要该绘制图形数据

    void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point) 
    {
        
    // TODO: Add your message handler code here and/or call default
        CClientDC dc(this);
        CBrush 
    *ptBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
        dc.SelectObject(ptBrush);
            
    //绘制图形
        switch(m_nDrawType)
        {
            
    case 1:
                dc.SetPixel(point,RGB(
    0,0,0));
                
    break;
            
    case 2:
                dc.MoveTo(m_ptOrigin);
                
    break;
            
    case 3:
                dc.Rectangle(CRect(m_ptOrigin,point));
                
    break;
            
    case 4:
                dc.Ellipse(CRect(m_ptOrigin,point));
                
    break;
        }

        
    //保存图形数据,保存之前,先将设置点转换为逻辑点
        OnPrepareDC(&dc);
        dc.DPtoLP(
    &m_ptOrigin);
        dc.DPtoLP(
    &point); 
            
    //在堆中分配一块空间来保存重绘图形数据
        CGraph *= new CGraph(m_nDrawType,m_ptOrigin,point);    //must use a point to CGraph
            
    //m_ptArray类型是一个CPtrArray类型的成员变量
        m_ptrArray.Add(g);
        
        CScrollView::OnLButtonUp(nFlags, point);
    }

    最后一步就是窗口重绘图时重新绘制这些图形即可。

    //OnDraw函数在调用之前,会先调用OnPrepareDC将逻辑点转换为设备点
    void CGraphicView::OnDraw(CDC* pDC)
    {
        CGraphicDoc
    * pDoc = GetDocument();
        ASSERT_VALID(pDoc);

        
    //redraw
        CClientDC dc(this);
        CBrush 
    *brush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
        dc.SelectObject(brush);
        
    for(int i=0; i<m_ptrArray.GetSize(); i++)
        {
            
    switch(((CGraph*)m_ptrArray.GetAt(i))->m_nDrawType)
            {
            
    case 1:
                dc.SetPixel(((CGraph
    *)m_ptrArray.GetAt(i))->m_ptEnd,RGB(0,0,0));
                
    break;
            
    case 2:
                dc.MoveTo(((CGraph
    *)m_ptrArray.GetAt(i))->m_ptOrigin);
                dc.LineTo(((CGraph
    *)m_ptrArray.GetAt(i))->m_ptEnd);
                
    break;
            
    case 3:
                dc.Rectangle(CRect(((CGraph
    *)m_ptrArray.GetAt(i))->m_ptOrigin,
                    ((CGraph
    *)m_ptrArray.GetAt(i))->m_ptEnd));
                
    break;
            
    case 4:
                dc.Ellipse(CRect(((CGraph
    *)m_ptrArray.GetAt(i))->m_ptOrigin,
                    ((CGraph
    *)m_ptrArray.GetAt(i))->m_ptEnd));
                
    break;
            }
        }

    }



      这是一种常规做法,代码量比其它二种要稍多一些。其它二种方法,另写二篇吧!算凑个数吧,嘻嘻!

      有关坐标点的转换问题,其实很简单,不用想得太复杂,其实就是二种坐标点的转换问题,逻辑点转换为设备点以及设备点转换为逻辑点,平时我们用到的绘图函数用到的坐标都是逻辑点。如果要输出到设备上(显示器,打印机)都得转换为设备点。设备点的原点永远都是客户区的(0,0)坐标点。我们只需要根据公式做映射即OK了。其实MFC已经帮我们做好了映射了,每次在响应WM_PAINT的事件中,都会去调用 OnPrepareDC(CDC* dc)方法 ,  在这个方法中,就做了转换坐标的方法。

      多看看MFC的代码,一切原理都会变得不是那么神秘!

    Author:repository
    From:  http://repository.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    java反射详解 (转至 http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html)
    DexClassLoader
    防止 apk反编译 jocky-- java混淆代码 (转至:http://my.oschina.net/f839903061/blog/72554)
    Android APK反编译详解(附图) (转至 http://blog.csdn.net/ithomer/article/details/6727581)
    双卡手机怎么指定SIM卡打电话
    android设备休眠
    GSON使用笔记(3) -- 如何反序列化出List
    Notepad++ 更换主题
    如何才能成为一个成功的项目经理
    项目经理是干出来的,不是学出来的;是带出来的,不是教出来的
  • 原文地址:https://www.cnblogs.com/repository/p/1879621.html
Copyright © 2020-2023  润新知