我把绘图放在OnMouseMove()中,就是在这个函数中建立一个firstDC,然后在OnPaint() 中建立一个memDC,把firstDC用BitBlt函数复制到memDC中,然后再把memDC拷贝到pDC中进行显示,结果显示不出来,我试了一下,如果在OnMouseMove()中直接用pDC绘制是可以显示的,我在OnMouseMove()中调用Invalidate(false)后就失败了,请教各位啊

解决方案 »

  1.   

    调用Invalidate(false),窗口重绘,估计你绘制的图就没有了。
      

  2.   

    void CDrawJiLiangDlg::OnMouseMove(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
        mousepoint=point;
    CClientDC dc(this);
    CBitmap m_bitmap;
    // m_bitmap.CreateCompatibleBitmap(&dc,p_rect.Width(),p_rect.Height());
    CBitmap * m_bitmapOldXY=NULL; if (secondDC.GetSafeHdc() == NULL) secondDC.CreateCompatibleDC(&dc);//创建与dc兼容的dc
    BITMAPINFOHEADER bmih;
    memset(&bmih, 0, sizeof(BITMAPINFOHEADER));

    bmih.biSize = sizeof(BITMAPINFOHEADER);
    bmih.biBitCount = 24;
    bmih.biCompression = BI_RGB;
    bmih.biPlanes = 1;
    bmih.biWidth = p_rect.Width();
    bmih.biHeight = p_rect.Height();

    BITMAPINFO bmi;
    memset(&bmi, 0, sizeof(BITMAPINFO));

    bmi.bmiHeader = bmih;

    void* p;
    m_bitmap.Attach(::CreateDIBSection(secondDC.GetSafeHdc(), &bmi, DIB_RGB_COLORS, &p, NULL, 0));

    m_bitmapOldXY = secondDC.SelectObject(&m_bitmap);
    secondDC.BitBlt(p_rect.left,p_rect.top,p_rect.right,p_rect.bottom,&dc,0,0,SRCCOPY);
        CPen pen1,*pOldpen;
    pen1.CreatePen(PS_SOLID,1,RGB(255,0,0));
    pOldpen=secondDC.SelectObject(&pen1);
    if ((point.x>=p_rect.left&&point.x<=p_rect.right)&&(point.y>=p_rect.top&&point.y<=p_rect.bottom))
    { //绘制横线和竖线
    int pp;
    double cell_distangce_x=(p_rect.right-30-originPoint.x)/(len1-1);    
    double origindis=point.x-originPoint.x;
         for (int i=0;i<len1;i++)
         {
     if (origindis>=abs(point.x-(originPoint.x+i*cell_distangce_x)))
     {
    origindis=abs(point.x-(originPoint.x+i*cell_distangce_x));
    pp=i;
     }
     else if(mousepoint.x<originPoint.x)
     {
     pp=-1;
     }
         }
     CString str_y;
     if (pp>=0)
     {
     secondDC.MoveTo(originPoint.x+pp*cell_distangce_x,p_rect.top);
     secondDC.LineTo(originPoint.x+pp*cell_distangce_x,p_rect.bottom);      
     str_y.Format("%f",*(pp2+pp));
     SetDlgItemText(IDC_ZUOBIAO,str_y);
     pDC->BitBlt(p_rect.left,p_rect.top,p_rect.right,p_rect.bottom,&secondDC,0,0,SRCCOPY);
     Invalidate(false);
     }
     
     
      }
    secondDC.SelectObject(m_bitmapOldXY);
        secondDC.SelectObject(pOldpen); CDialog::OnMouseMove(nFlags, point);
    }void CDrawJiLiangDlg::OnPaint() 
    {
    CPaintDC dc(this);
     CDC memDC; pOldBmp = NULL; 
    CBitmap memBitmap;           // 用于内存绘图的位图
    memDC.CreateCompatibleDC(&dc); 
    memBitmap.CreateCompatibleBitmap(&dc,p_rect.Width(),p_rect.Height());
    pOldBmp = memDC.SelectObject(&memBitmap); originPoint.x=p_rect.left+50;
    originPoint.y=(long)(p_rect.top+p_rect.Height()-20);
    if (memDC.GetSafeHdc() != NULL)
    { memDC.BitBlt(p_rect.left,p_rect.top,p_rect.right,p_rect.bottom,&firstDC,0,0,SRCPAINT);
    memDC.BitBlt(p_rect.left,p_rect.top,p_rect.right,p_rect.bottom,&secondDC,0,0,SRCPAINT);
    pDC->BitBlt(p_rect.left,p_rect.top,p_rect.right,p_rect.bottom,&memDC,0,0,SRCCOPY);
    }
        
    CDialog::OnPaint();  
    }
      

  3.   

    chinatcp:
    我知道是重绘后没有了,但是不应该啊,为什么呢?
      

  4.   

    把onmousemove的代码全部移到onpaint中去,至于怎么放
    ,根据你所需要的状态再组合。
      

  5.   

    问题可能出在:
    secondDC与firstDC上,初始化在哪儿?另外:
    pOldBmp = memDC.SelectObject(&memBitmap);
    用完后,要
    memDC.SelectObject(pOldBmp );
    还有,memDC.DeleteDC();memBitmap.DeleteObject();
      

  6.   

    memDC.BitBlt(p_rect.left,p_rect.top,p_rect.right,p_rect.bottom,&firstDC,0,0,SRCPAINT);
    memDC.BitBlt(p_rect.left,p_rect.top,p_rect.right,p_rect.bottom,&secondDC,0,0,SRCPAINT);
    pDC->BitBlt(p_rect.left,p_rect.top,p_rect.right,p_rect.bottom,&memDC,0,0,SRCCOPY);现在问题就是firstDC画图是成功的,一旦重绘就会失败,不知道什么原因
      

  7.   

    我测试了一下,单独使用一个按钮控制firstDC绘图是没问题的,一重绘就没有了
      

  8.   

    fandh:
    加上那几句代码还是不行
      

  9.   

    Invalidate(false);
    pDC->BitBlt(p_rect.left,p_rect.top,p_rect.right,p_rect.bottom,&secondDC,0,0,SRCCOPY);
    把 Invalidate 放到前面试试。
      

  10.   

    你把mousemove里面的代码去掉,然后不停的进行窗口切换,看看会不会有问题?
      

  11.   

    firstDC和onpaint中的pDC是哪来的?
      

  12.   

    chinatcp

    其实是pDC->BitBlt(p_rect.left,p_rect.top,p_rect.right,p_rect.bottom,&secondDC,0,0,SRCCOPY);
    这句加上去会一闪一闪的,这句是为了测试,我的本意是没有这句应该可以画出来的,不好意思没有表达清楚
      

  13.   

    pDC是在对话框初始化时OnInitDialog()中用pDC = this->GetDC();得到的,这个是没问题的
      

  14.   

    firstDC和secondDC是一样的,两个只要解决一个就可以了
      

  15.   

    这个是背景绘制,要放在OnPaint中,只要窗口重绘,就自动绘制背景。
    你放在 OnMouseOver中,每移动一下鼠标,就会触发无数次消息,所以会闪。
    而在绘制后,调用Invalidate,整个窗口重绘,你绘制的图就失效了。
      

  16.   

    太乱了,pdc没有必要存在,直接用dc画就可以了,建议lz   整理代码在OnPaint中画,onmouse中只是记录状态然后刷新。
      

  17.   


    但是整个窗口重绘时只要secondDC中保存的那张内存图片没有消失应该是可以显示的啊?为什么会失效呢?重绘只是重新拷贝了一下啊
      

  18.   

    奇怪的是,基本一样的我如果把同样的代码放到单文档的View类中,也就是重绘时调用OnDraw()就可以呢,在对话框中就不行了呢?
      

  19.   

    对话框背景擦除消息OnEraseBkgnd 直接 return TRUE;
     
      

  20.   

    这个我已搞定,呵呵。
    去掉一句代码即可:
    secondDC.BitBlt(p_rect.left,p_rect.top,p_rect.right,p_rect.bottom,&dc,0,0,SRCCOPY);
      

  21.   

    http://vckbase.com/document/viewdoc/?id=1612
      

  22.   

    在OnMouseMove()里使窗口无效(Invalidate  RedrawWindow SendMessage(WM_PAINT)) ,绘制部分都在OnPaint()中完成吧