| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3585 人关注过本帖
标题:什么是双缓存画图机制啊?VC绘图中的
只看楼主 加入收藏
myvc
Rank: 2
等 级:论坛游民
威 望:1
帖 子:85
专家分:89
注 册:2009-10-25
结帖率:76.47%
收藏
已结贴  问题点数:20 回复次数:4 
什么是双缓存画图机制啊?VC绘图中的
急急急!!!哪位高手知道什么是双缓存画图机制啊?VC绘图中的,可否举例示之,谢
搜索更多相关主题的帖子: 绘图 机制 缓存 画图 
2010-04-01 12:36
秀痘魔导士
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:6
帖 子:250
专家分:1150
注 册:2009-12-23
收藏
得分:20 
双缓冲的原理可以这样形象的理解:把电脑屏幕看作一块黑板。首先我们在内存环境中建立一个“虚拟“的黑板,然后在这块黑板上绘制复杂的图形,等图形全部绘制完毕的时候,再一次性的把内存中绘制好的图形“拷贝”到另一块黑板(屏幕)上。采取这种方法可以提高绘图速度,极大的改善绘图效果。
  例如在OnDraw()函数中可以如下所述实现双缓冲,其主要步骤分为四步:

  CPen Pen;Pen.CreatePen(PS_INSIDEFRAME,1,RGB(225,225,0));

  CBrush Brush;

  Brush.CreateSolidBrush(RGB(225,225,0));

  CDC dcMem;CBitmap bm;

  CRect rc;GetClientRect(&rc);

  // Step 1:为屏幕DC创建兼容的内存

  DC :CreateCompatibleDC()

  dcMem.CreateCompatibleDC(pDC);

  // Step 2:创建位图:

  CreateCompatibleBitmap()

  bm.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());

  // Step 3:把位图选入设备环境:SelectObject(),可以理解为选择画布dcMem.SelectObject(&bm);

  dcMem.SelectObject(Pen);

  dcMem.SelectObject(Brush);

  dcMem.Ellipse(0,0,50,50);//画椭圆

  // Step 4:把绘制好的图形“拷贝“到屏幕上:BitBlt()pDC->BitBlt(0,0,rc.Width(),

  rc.Height(),&dcMem,0,0,SRCCOPY);

  dcMem.DeleteDC();

  bm.DeleteObject();

  这样便实现了双缓冲,通过这个方法可以防止在VC中画图时出现屏幕闪烁的情况。
2010-04-01 14:20
myvc
Rank: 2
等 级:论坛游民
威 望:1
帖 子:85
专家分:89
注 册:2009-10-25
收藏
得分:0 
我做的是一个可以动的物体(用计时器),按你的方法做了,屏幕还是闪烁,我把OnDraw()和OnTimer()的程序贴在这,你再帮我看看吧,谢谢啦

void CMyView::OnDraw(CDC* pDC)
{
    CMyDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here


    CDC MemDC;
CBitmap MemBitmap
CRect rc;
GetClientRect(&rc);
MemDC.CreateCompatibleDC(pDC);

MemBitmap.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());

CBitmap *pOldBmp=MemDC.SelectObject(&MemBitmap);

MemDC.FillSolidRect(0,0,rc.Width(),rc.Height(),RGB(190,232,235));

    COLORREF rgb1=RGB(0,0,255);
    CBrush brush,brush1,brush2;
    brush.CreateSolidBrush(rgb1);
    MemDC.SelectObject(brush);
    MemDC.Rectangle(ptx,pty,ptx+100,pty+50);
   

    brush1.CreateSolidBrush(rgb);
    MemDC.SelectObject(brush1);
    MemDC.Ellipse(ptx+80,pty,ptx+100,pty+20);

   
    MemDC.SelectStockObject(BLACK_BRUSH);
    MemDC.Ellipse(ptx+10,pty+35,ptx+40,pty+65);
    MemDC.Ellipse(ptx+60,pty+35,ptx+90,pty+65);

    pDC->BitBlt(0,0,rc.Width(),rc.Height(),&MemDC,0,0,SRCCOPY);

MemBitmap.DeleteObject();
MemDC.DeleteDC();
  pDC->TextOut(0,0,"红灯停,绿灯行,每隔2秒红绿灯变化一次");
}

void CMyView::OnTimer(UINT nIDEvent)
{
    // TODO: Add your message handler code here and/or call default
    if(nIDEvent==1)
    {
        count+=1;
    }
    if(count<=40)
    {
        if(flag)
        {
            rgb=RGB(0,255,0);
            ptx+=5;
            Invalidate(true);
        }
    }
    else
    {
        rgb=RGB(255,0,0);
        Invalidate(true);
        count=0;
        flag=!flag;
    }
    CScrollView::OnTimer(nIDEvent);
}



[ 本帖最后由 myvc 于 2010-4-3 16:18 编辑 ]
2010-04-03 16:17
myvc
Rank: 2
等 级:论坛游民
威 望:1
帖 子:85
专家分:89
注 册:2009-10-25
收藏
得分:0 
回复 2楼 秀痘魔导士
    首先非常感谢你的帮助,我做的是一个可以动的物体(用计时器),按你的方法做了,屏幕还是闪烁,我把OnDraw()和OnTimer()的程序贴在这,你再帮我看看吧,谢谢啦

void CMyView::OnDraw(CDC* pDC)
{
    CMyDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here


    CDC MemDC;
CBitmap MemBitmap
CRect rc;
GetClientRect(&rc);
MemDC.CreateCompatibleDC(pDC);

MemBitmap.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());

CBitmap *pOldBmp=MemDC.SelectObject(&MemBitmap);

MemDC.FillSolidRect(0,0,rc.Width(),rc.Height(),RGB(190,232,235));

    COLORREF rgb1=RGB(0,0,255);
    CBrush brush,brush1,brush2;
    brush.CreateSolidBrush(rgb1);
    MemDC.SelectObject(brush);
    MemDC.Rectangle(ptx,pty,ptx+100,pty+50);
   

    brush1.CreateSolidBrush(rgb);
    MemDC.SelectObject(brush1);
    MemDC.Ellipse(ptx+80,pty,ptx+100,pty+20);

   
    MemDC.SelectStockObject(BLACK_BRUSH);
    MemDC.Ellipse(ptx+10,pty+35,ptx+40,pty+65);
    MemDC.Ellipse(ptx+60,pty+35,ptx+90,pty+65);

    pDC->BitBlt(0,0,rc.Width(),rc.Height(),&MemDC,0,0,SRCCOPY);

MemBitmap.DeleteObject();
MemDC.DeleteDC();
  pDC->TextOut(0,0,"红灯停,绿灯行,每隔2秒红绿灯变化一次");
}

void CMyView::OnTimer(UINT nIDEvent)
{
    // TODO: Add your message handler code here and/or call default
    if(nIDEvent==1)
    {
        count+=1;
    }
    if(count<=40)
    {
        if(flag)
        {
            rgb=RGB(0,255,0);
            ptx+=5;
            Invalidate(true);
        }
    }
    else
    {
        rgb=RGB(255,0,0);
        Invalidate(true);
        count=0;
        flag=!flag;
    }
    CScrollView::OnTimer(nIDEvent);
}
2010-04-03 16:19
秀痘魔导士
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:6
帖 子:250
专家分:1150
注 册:2009-12-23
收藏
得分:0 
以下是引用myvc在2010-4-3 16:17:25的发言:

我做的是一个可以动的物体(用计时器),按你的方法做了,屏幕还是闪烁,我把OnDraw()和OnTimer()的程序贴在这,你再帮我看看吧,谢谢啦

void CMyView::OnDraw(CDC* pDC)
{
    CMyDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here


    CDC MemDC;
CBitmap MemBitmap
CRect rc;
GetClientRect(&rc);
MemDC.CreateCompatibleDC(pDC);

MemBitmap.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());

CBitmap *pOldBmp=MemDC.SelectObject(&MemBitmap);

MemDC.FillSolidRect(0,0,rc.Width(),rc.Height(),RGB(190,232,235));

    COLORREF rgb1=RGB(0,0,255);
    CBrush brush,brush1,brush2;
    brush.CreateSolidBrush(rgb1);
    MemDC.SelectObject(brush);
    MemDC.Rectangle(ptx,pty,ptx+100,pty+50);
   

    brush1.CreateSolidBrush(rgb);
    MemDC.SelectObject(brush1);
    MemDC.Ellipse(ptx+80,pty,ptx+100,pty+20);

   
    MemDC.SelectStockObject(BLACK_BRUSH);
    MemDC.Ellipse(ptx+10,pty+35,ptx+40,pty+65);
    MemDC.Ellipse(ptx+60,pty+35,ptx+90,pty+65);

    pDC->BitBlt(0,0,rc.Width(),rc.Height(),&MemDC,0,0,SRCCOPY);

MemBitmap.DeleteObject();
MemDC.DeleteDC();
  pDC->TextOut(0,0,"红灯停,绿灯行,每隔2秒红绿灯变化一次");
}

void CMyView::OnTimer(UINT nIDEvent)
{
    // TODO: Add your message handler code here and/or call default
    if(nIDEvent==1)
    {
        count+=1;
    }
    if(count<=40)
    {
        if(flag)
        {
            rgb=RGB(0,255,0);
            ptx+=5;
            Invalidate(true);
        }
    }
    else
    {
        rgb=RGB(255,0,0);
        Invalidate(true);
        count=0;
        flag=!flag;
    }
    CScrollView::OnTimer(nIDEvent);
}
MemDC不要每次都生成临时对象,做为本地成员变量存储,这样才能保留上一次的信息
2010-04-08 10:28
快速回复:什么是双缓存画图机制啊?VC绘图中的
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018815 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved