采用的是双缓冲绘图,想实现在黑色背景下,屏幕上画扇形坐标轴(更新时坐标轴不变),同时可以显示动态的彩色圆。我试了些方法,无论用什么画刷,画出来的都是白色,而且是闪烁的。学得不通,代码贴上来了,请大侠们帮帮忙。在有背景的情况下画图,是不是只能改背景位图的RGB值,才能显示想要的图?有没有办法可以将要显示的图直接覆盖背景,无显示部分就还是保留背景色。
下面是我的代码:
void CPlotDlg::Draw()//绘图
{
pDC=m_edit.GetDC();
m_edit.GetClientRect(&rect); CBitmap memBitmap;
CBitmap* pOldBmp = NULL;
memDC.CreateCompatibleDC(pDC); memBitmap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);
pOldBmp = memDC.SelectObject(&memBitmap); memDC.BitBlt(rect.left,rect.top,rect.right,rect.bottom,pDC,0,0,SRCCOPY);

reDraw(&memDC);
// reDraw 函数包括的语句
//  mDC->SetPixelV(rect.left+nCoordinate,rect.bottom-i*2,plot[i]);  改变屏幕像素 
//  mDC->SetPixelV(rect.left+nCoordinate,rect.bottom-i*2-1,plot[i]); pDC->BitBlt(rect.left,rect.top,rect.right,rect.bottom,&memDC,0,0,SRCCOPY);
memDC.SelectObject(pOldBmp);
memDC.DeleteDC();
memBitmap.DeleteObject();
ReleaseDC(pDC);
ReleaseDC(&memDC);

}OnPaint()函数里面有创建背景位图

解决方案 »

  1.   


    memDC.BitBlt(rect.left,rect.top,rect.right,rect.bottom,pDC,0,0,SRCCOPY);
    这里的pDC改成你的背景位图DC。
    就是再创建一个内存DC,专门存放背景。
      

  2.   

    看着很乱啊 pDC=m_edit.GetDC();  // 这条怎么取了控件的DCmemDC 又是哪儿来的?背景可以放在 OnEraseBkgnd 刷图的时候不用时时刷背景
      

  3.   

    我设定的显示屏幕是在一个编辑框内m_edit
      

  4.   

    memDC.BitBlt(rect.left,rect.top,rect.right,rect.bottom,pDC,0,0,SRCCOPY);
    这里的pDC改成你的背景位图DC。
    就是再创建一个内存DC,专门存放背景。不好意思哦,看了一些双缓冲的资料,还是不是很懂。你能说得再详细点吗?有背景色的情况下,跟无背景下绘图有什么不一样啊?
      

  5.   

    //创建内存DC
         HDC hdcMem = CreateCompatibleDC(hdc);
         //创建一个bmp内存空间
         HBITMAP hBmp = CreateCompatibleBitmap(hdc,SCREEN_WIDTH,SCREEN_HEIGHT);
         //将bmp内存空间分配给内存DC
         HGDIOBJ hOldSel = SelectObject(hdcMem,hBmp);
        
         //这是使用者需要绘制的画面,全部往内存DC绘制
          // 绘制代码.......................     如:
          Rectangle(hdcMem,0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
         
        
         //将内存DC的内容复制到屏幕显示DC中,完成显示
         BitBlt(hdc,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,hdcMem,0,0,SRCCOPY);
         //清除资源
         SelectObject(hdcMem,hOldSel);    
         DeleteDC(hdcMem);    
    另外,重载OnEraseBkgnd(CDC* pDC),在该函数中不要绘制背景,中直接返回TRUE。
      

  6.   

    首先,DC的含义是“设备关联”,用你那个“黑板”的比喻的话,DC其实就是个“黑板框”,并不是黑板本身。Windows的DC大体可以分为两类,一类是跟硬件相关联的设备DC,如屏幕、打印机等等。这些设备相当于真实的“黑板”。由于设备的物理特性的限制,这类“黑板”有特定的属性,例如分辨率、颜色位数等等。而设备DC,就是把这些真实“黑板”框起来的“黑板框”,你所绘制的图像,并不是画在DC上,而是画在设备上,DC不过是一个渠道而已。
    另一类DC是内存DC,它没有跟任何设备向关联,仅仅是为了画图方便,而用它来在内存里模拟真实的设备。由于它没有对应任何真实的设备,因此它没有什么固定的属性。为了保证能模拟某个特定设备,内存DC在生成的时候必须指定它模拟哪个设备,因此它必须用CreateCompatibleDC来生成,其参数就是待模拟的设备DC。由于内存DC没有任何固定属性,因此将一个内存DC作为参数送入CreateCompatibleDC来生成另一个内存DC是不行的。
    生成了内存DC之后,我们实际上仅仅拥有了一个黑板框。与设备DC不同,作为真实设备的“黑板”总是存在的,但内存DC的黑板则不然,它必须靠我们专门地在内存里制作一个出来才行。能够作为内存DC的黑板的东西就是Bitmap(你所谓的CBitmap仅仅是MFC对HBITMAP的封装,因此下面只谈HBITMAP)。由于没有了设备的物理限制,这个黑板你愿意做多大都行。为了能够更好地模拟真实的设备,这块黑板的生成,最好使用CreateCompatibleBitmap,并将需要模拟的设备DC传入其中。同样,不应该把一个内存DC作为参数送入CreateCompatibleBitmap,否则你会得到某些意料之外的结果。
    生成了黑板之后,还需要把黑板“安装”进黑板框,才能进行画图。“安装”的方法就是使用SelectObject,把你生成的黑板放进你的内存DC。SelectObject返回的结果是从这个DC里被换下来的黑板。第一次安装黑板的时候,被换下来的是一块“NULL 黑板”。之后,你可以按照你的意愿随时给黑板框更换黑板。顺便说一句,由于设备DC所关联的是真实的设备黑板,因此对一个设备DC进行安装黑板(把一个Bitmap送入SelectObject)的操作是无效的。
    装好黑板之后,就可以在黑板上画图了。如果装进黑板框的是“NULL 黑板”,那么你的一切绘图操作也都会成功,但没有任何效果(想象一下拿着粉笔在空气里画图)。当你画了一些图形之后,你可以把另一块黑板换上去,再去画另一些图形。当然,黑板被换下来之后,其内容不会发生任何变化。如果你愿意的话,你可以生成N块黑板,不断地换进同一个黑板框,画上各种不同的图形,然后再换下来。
    最后,如果你已经画完了,你可以通过DeleteDC销毁那个内存DC(黑板框)。尽管销毁黑板框的操作并不会损坏当前安装在其中的黑板,但仍然建议在销毁DC之前,用最初换下来的那块“NULL 黑板”把你自己的黑板换下来。至于你自己的黑板,你可以在你不需要它的时候,用DeleteObject来销毁。不过要注意,不要试图在这块黑板还装在某个黑板框里的时候去销毁它。剩下的问题就很简单了。什么叫双缓冲呢?
    1、做个内存里的黑板框。
    2、做个黑板装进去。
    3、在黑板上面画图。
    4、把画好的图贴到真实的设备黑板上。
    5、把新做的黑板换下来销毁。
    6、把黑板框销毁。这个流程可以很容易地改成:
    1、预先画好固定的图形:
      1.1、做个内存里的黑板框。
      1.2、做个黑板装进去。
      1.3、在黑板上面画图。
      1.4、把新做的黑板换下来,但不要销毁(如果你自己做的黑板你都没有弄个变量存起来,那我就无话可说了)。
      1.5、把黑板框销毁。
    2、当需要往屏幕上画的时候(例如响应WM_PAINT消息):
      2.1、做个内存里的黑板框。
      2.2、把你上次存起来的黑板装进去。
      2.3、把黑板上的内存贴到真实的设备黑板上。
      2.4、把黑板换下来。
      2.5、把黑板框销毁。
    3、作为一个良好习惯,当你的程序退出时,记得把你存起来的黑板销毁。如果你愿意的话,上述流程还可以进一步变化,例如你把好几种不同固定图形预先画在几块黑板上,按需要选用,或者你同时制作两个黑板框,把一块新做的黑板装进黑板框1,然后把预先做好的黑板1至黑板N轮流装进黑板框2,并往黑板框1中的新黑板上贴,最后再把最终做好的新黑板中的内容贴到真实的设备黑板上,诸如此类。
      

  7.   

    用的是双缓冲绘图,想实现在黑色背景下,屏幕上画扇形坐标轴(更新时坐标轴不变)
    楼主,你傻了么?这个需要双缓冲所,直接一个Pen就OK了,要想局部刷新就InvalidateRect()双缓冲用来做什么?一般都用来贴图片,靠,画的东西跟贴的不一样!
      

  8.   

    推荐用CMemDC类,就是那个MemDC.h文件。
      

  9.   

    有背景么?那么背景一起放到DC中,双缓存。不然肯定闪死你,再不行的话,发QQ给我了。
      

  10.   

    我用这个画扇形轮廓
    pDC->MoveTo(200,200);
    pDC->AngleArc(200, 200, 10, 180,-90); 
    pDC->LineTo(200,200);结果画出来,LineTo画的直线出现锯齿状,怎么解决这个问题呀?
      

  11.   

    楼主,用SetSmoothingMode函数,参数如下SmoothingModeInvalid
    Reserved.SmoothingModeDefault
    Specifies that smoothing is not applied.SmoothingModeHighSpeed
    Specifies that smoothing is not applied.SmoothingModeHighQuality
    Specifies that smoothing is applied using an 8 X 4 box filter.SmoothingModeNone
    Specifies that smoothing is not applied.SmoothingModeAntiAlias8x4
    Specifies that smoothing is applied using an 8 X 4 box filter.SmoothingModeAntiAlias
    Specifies that smoothing is applied using an 8 X 4 box filter.SmoothingModeAntiAlias8x8
    Specifies that smoothing is applied using an 8 X 8 box filter.
      

  12.   

    if (!m_flagelemt) 
    {
        memDC.BitBlt(rect.left,rect.top,rect.right,rect.bottom,pDC,0,0,SRCCOPY);   
    }
    else
    {
    memDC.FillSolidRect(PlotRect.left,PlotRect.top,PlotRect.right,PlotRect.bottom,RGB(0,0,0));  //刷新为黑色背景
     
    //画扇形代码
     CPoint Radus1,Radus2,Radus3;
       CString str;
       CPen* pPenBlue = new CPen;
       // 绿色画笔
       pPenBlue->CreatePen(PS_SOLID,1,RGB(0,255,0));
       // 选中当前绿色画笔,并保存以前的画笔
       CGdiObject* pOldPen=memDC.SelectObject(pPenBlue);
       memDC.MoveTo(rect.left+360,rect.top+514);
       memDC.AngleArc(rect.left+360,rect.top+514,300,45,90);
       Radus1=memDC.GetCurrentPosition();
       str="9.3m";
       memDC.SetTextColor(RGB(255,0,0));
       memDC.TextOut(Radus1.x-35,Radus1.y,str);
       memDC.AngleArc(rect.left+360,rect.top+514,0,0,0); 
       memDC.MoveTo(rect.left+360,rect.top+514);
       memDC.AngleArc(rect.left+360,rect.top+514,400,45,90);
       Radus2=memDC.GetCurrentPosition();
       str="12.2m";
       memDC.TextOut(Radus2.x-35,Radus2.y,str);
       memDC.AngleArc(rect.left+360,rect.top+514,0,0,0);   
       memDC.MoveTo(rect.left+360,rect.top+514);
       memDC.AngleArc(rect.left+360,rect.top+514,500,45,90);
       Radus3=memDC.GetCurrentPosition();
       str="15.1m";
       memDC.TextOut(Radus3.x-5,Radus3.y+5,str);   
       memDC.AngleArc(rect.left+360,rect.top+514,0,0,0);
       memDC.SelectObject(pOldPen); }
    这是我写的扇形代码。AngleArc画的线段不会出现锯齿现象,我就用了两次。可我运行一段时间后,就出现异常。我把画扇形的代码注释起来,else中只保留memDC.FillSolidRect这句,程序能正常运行下去。是我这段代码写错了吗?请高手指点下,谢谢拉
      

  13.   

    你都没有选择画刷  默认是白色画刷 你可以用 HBRUSH::FromHandle((HBRUSH)Getstockobject(NULL_BRUSH))来创建一个空画刷 (函数名拼的可能不准)
      

  14.   

    知道了,CPen* pPenBlue = new CPen;后边没delete掉,就出错了