大家好,我在初始化对话框时,生成了一条曲线,我现在要用鼠标在曲线上画一条拟合直线,可是我画直线的时候凡是直线经过的地方,原来的曲线就没了,我是要保留曲线的,请问大家怎么回事呢,我该怎么做才能使直线经过的地方曲线不消失呢

解决方案 »

  1.   

    你是直接使用dc进行绘制曲线的吗?如果是,并且没有放在Onpaint中的话就会被刷掉,建议绘制曲线的代码放在OnPaint函数中,不要放在OnInitialDlg中,要么就像1楼那样保存曲线的相关参数,然后在重绘时重新绘制曲线。
      

  2.   

    我是在OnPaint中画的曲线,对话框初始化后曲线就画好了,然后我用鼠标在曲线上动态地画拟合直线,使用LBUTTONDOWN,MOUSEMOVE,LBUTTONUP来画的,直线经过曲线的地方曲线就消失了
      

  3.   

    我把代码贴出来,我也不知道问题在哪里,大家帮我看看阿
    void duishugonglvpu::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
            

    CDC*pDC=GetDC();

    CPen pen;
    pen.CreatePen (PS_SOLID,1,RGB(0,0,255));
    CPen* oldpen=pDC->SelectObject (&pen);
    m_pFirst=point;
    m_pLast=point;
            pDC->MoveTo(m_pFirst);
    pDC->LineTo(m_pLast);
    SetCapture();
    pDC->SelectObject (oldpen);
            CDialog::OnLButtonDown(nFlags, point)
    }
    void duishugonglvpu::OnLButtonUp(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default CDC*pDC=GetDC();
    CPen pen;
    pen.CreatePen (PS_SOLID,1,RGB(0,0,255));
    //选笔
    CPen* oldpen=pDC->SelectObject (&pen);
    int t=pDC->SetROP2(R2_NOTXORPEN);
    pDC->MoveTo (m_pFirst);
    pDC->LineTo (m_pLast);
    pDC->SetROP2(t);
    m_pLast=point;
    pDC->MoveTo (m_pFirst);
    pDC->LineTo (m_pLast);
    ReleaseCapture();
    pDC->SelectObject (oldpen); CDialog::OnLButtonUp(nFlags, point);
    }
    void duishugonglvpu::OnMouseMove(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
     if(nFlags==MK_LBUTTON)//如果鼠标按下,执行下面操作
    {
        SetCapture();
     CDC* pDC=GetDC();

    //擦除旧线
    CPen pen;
    pen.CreatePen (PS_SOLID,1,RGB(0,0, 255));
        CPen* oldpen=pDC->SelectObject (&pen);
    int t=pDC->SetROP2(R2_NOTXORPEN);

    pDC->MoveTo(m_pFirst);
    pDC->LineTo (m_pLast);
    //画新线
    pDC->SetROP2(t);
    m_pLast=point;
    pDC->MoveTo(m_pFirst);
    pDC->LineTo (m_pLast);
     pDC->SelectObject (oldpen);
    } CDialog::OnMouseMove(nFlags, point);
    }
    void duishugonglvpu::OnPaint() 
    {
    CPaintDC dc(this); // device context for painting

    // TODO: Add your message handler code here // 字符串
    CString str;

    // 循环变量
    int i;
    // int j;
    // 最大计数
    //double lMaxCount = 0;


    // 获取绘制坐标的文本框
    CWnd* pWnd = GetDlgItem(IDC_GONGLVPU);

    // 指针
    CDC* pDC = pWnd->GetDC();
    pWnd->Invalidate();
    pWnd->UpdateWindow();
    //pDC->SetMapMode(MM_ANISOTROPIC);
    pDC->Rectangle(0,0,600,620);

    // 创建画笔对象
    CPen* pPenRed = new CPen;

    // 红色画笔
    pPenRed->CreatePen(PS_SOLID,1,RGB(255,0,0));

    // 创建画笔对象
    CPen* pPenBlue = new CPen;

    // 蓝色画笔
    pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0, 255));

    // 创建画笔对象
    CPen* pPenGreen = new CPen;

    // 绿色画笔
    pPenGreen->CreatePen(PS_DOT,1,RGB(0,0,0));
    // CBrush brush;
    // brush.CreateSolidBrush(0,0,255);

    // 选中当前红色画笔,并保存以前的画笔
    CGdiObject* pOldPen = pDC->SelectObject(pPenRed);

    // 绘制坐标轴
    pDC->MoveTo(30,10);

    // 垂直轴
    pDC->LineTo(30,580);
    str.Format("-30");
    pDC->TextOut(8, 577, str);
    str.Format("-25");
    pDC->TextOut(8, 497, str);
    str.Format("-20");
    pDC->TextOut(8, 417, str);
    str.Format("-15");
    pDC->TextOut(8, 337, str);
    str.Format("-10");
    pDC->TextOut(8, 257, str);
    str.Format("-5");
    pDC->TextOut(15, 177, str);
    str.Format("0");
    pDC->TextOut(15,97,str);
    str.Format("5");
    pDC->TextOut(15,17,str);
    for (i = 20; i < 580; i += 8)
    {  int t=(i-20)/8;
    if ((t & 1) == 0)
    {
    // 10的倍数
    pDC->MoveTo(30, i);
    pDC->LineTo(26, i);
    }
    else

    {
    // 10的倍数
    pDC->MoveTo(30, i);
    pDC->LineTo(28, i);
    }
    }
    // 水平轴
    pDC->MoveTo(30,580);
    pDC->LineTo(450,580);

    // 写X轴刻度值
    str.Format("0");
    pDC->TextOut(30, 583, str);
    str.Format("0.1");
    pDC->TextOut(110, 583, str);
    str.Format("0.2");
    pDC->TextOut(190, 583, str);
    str.Format("0.3");
    pDC->TextOut(270, 583, str);
    str.Format("0.4");
    pDC->TextOut(350, 583, str);
    str.Format("0.5");
    pDC->TextOut(430, 583, str);

    // 绘制X轴刻度
    for (i = 8; i <= 400; i += 8)
    {   int t=(i-8)/8;
    if ((t & 1) == 0)
    {
    // 10的倍数
    pDC->MoveTo(i + 30, 580);
    pDC->LineTo(i + 30, 582);
    }
    else
    {
    // 10的倍数
    pDC->MoveTo(i + 30, 580);
    pDC->LineTo(i + 30, 584);
    }
    }

    // 绘制X轴箭头
    pDC->MoveTo(450,580);
    pDC->LineTo(435,575);
    pDC->MoveTo(450,580);
    pDC->LineTo(435,585);

    // 绘制y轴箭头
    pDC->MoveTo(30,10);
    pDC->LineTo(25,15);
    pDC->MoveTo(30,10);
    pDC->LineTo(35,15);
    //在对话框类中调用视图类的成员
    CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;//得到主框架指针 CMDIChildWnd *pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();//得到子框架的活动视图类指针
        CCqhView *pView = (CCqhView *) pChild->GetActiveView();
       pCTm=new double[pView->m+1];
       //分配内存
       f1=new double[pView->m+1];
       //将功率谱值和频率值换算为所对应的像素个数
       
       for (i=0;i<=pView->m;i++)
       
        pCTm[i]=pView->pCTmp[i]/0.0625;
       
      for (i=0;i<=pView->m;i++)

       f1[i]=pView->f[i]/0.00125;
       //选择画笔  //LOGBRUSH       lb;
      //lb.lbColor=RGB(255,0,0);     
     // lb.lbHatch=HS_CROSS;     
      //lb.lbStyle=BS_SOLID; 
      //CPen Newpen(PS_GEOMETRIC |PS_SOLID,   20,   &lb,   NULL,   NULL); 
    pOldPen = pDC->SelectObject(pPenGreen);
    CBrush brush;
    //*oldBrush;
    brush.CreateSolidBrush(RGB(0,0,0));
    //oldBrush=pDC->SelectObject(&brush);
    //int m_nColor;
    //m_nColor=GRAY_BRUSH;    //绘制径向对数功率谱曲线
    pDC->MoveTo(30,(pCTm[0]+100));
    for (i=0;i<=pView->m;i++)
    {
    if(pCTm[i]-0<=0)
    {   pCTm[i]=fabs(pCTm[i]);
    //pDC->SelectStockObject(m_nColor);
    pDC->BeginPath();
    pDC->Ellipse((f1[i]+30-2),(pCTm[i]+100-2),(f1[i]+30+2),(pCTm[i]+100+2));
    pDC->EndPath();
    pDC->SelectObject(&brush);
    pDC->FillPath();
    //pDC->SetPixel((f1[i]+30),(pCTm[i]+100),0);
    }
    else
    {//pDC->SelectStockObject(m_nColor);
        pDC->BeginPath();
    pDC->Ellipse((f1[i]+30-2),(100-pCTm[i]-2),(f1[i]+30+2),(100-pCTm[i]+2));
    pDC->EndPath();
    pDC->SelectObject(&brush);
    pDC->FillPath();
    }

    }
    pDC->SelectObject(pPenBlue);
    恢复以前的画笔
    pDC->SelectObject(pOldPen);

    // 删除新的画笔
    delete pPenRed;
    delete pPenBlue;
    delete pPenGreen;

    // Do not call CDialog::OnPaint() for painting messages
    }
      

  4.   

    把所有的绘图动作都放到OnPaint中,鼠标消息中只需要记录坐标和动作,然后刷新;OnPaint中绘制曲线和记录下来的坐标形成的线。
      

  5.   

    GetDC得到的dc不用后要用ReleaseDC释放,否则会出现你所说的问题
      

  6.   

    Mackz能说的清楚点么,刚接触,比较菜,上面贴的就是我写的代码,你可以具体到我程序里面说说怎么改么?谢谢你的热心帮助啊
      

  7.   

    SetROP2(t)删掉,SetROP2(R2_NOTXORPEN)不用删,这样试试
      

  8.   

    “我是在OnPaint中画的曲线,对话框初始化后曲线就画好了,然后我用鼠标在曲线上动态地画拟合直线,使用LBUTTONDOWN,MOUSEMOVE,LBUTTONUP来画的,直线经过曲线的地方曲线就消失了”
    画过之后用Invalidate引起曲线的重绘
      

  9.   

    yequnsong你说的办法我也试了,画的时候直线不断的闪烁,到响应完LBUTTONUP时就没有直线,但是原来的曲线还是存在,gs1234537我试试:)
      

  10.   

    问题出再OnMouseMove中if(nFlags==MK_LBUTTON)//如果鼠标按下,执行下面操作
    {
            SetCapture();
      CDC*   pDC=GetDC();//擦除旧线
    CPen   pen;
    pen.CreatePen   (PS_SOLID,1,RGB(0,0,   255));
            CPen*   oldpen=pDC-> SelectObject   (&pen);
    // 返回的t的模式为copy pen,即直接把画笔颜色复制到屏幕,没有于屏幕颜色进行任何运算
    int   t=pDC-> SetROP2(R2_NOTXORPEN);pDC-> MoveTo(m_pFirst);
    pDC-> LineTo   (m_pLast);
    //画新线
    pDC-> SetROP2(t);[color=#FF0000]// 把模式设置为了copy pen

    m_pLast=point;
    pDC-> MoveTo(m_pFirst);
    // 绘制直线,把屏幕颜色覆盖为直线颜色,所以会看到直线擦掉曲线的情况,把pDC-> SetROP2(t)删掉,这里的模式还是保持R2_NOTXORPEN,意思是线的颜色与屏幕颜色异或然后取反,这样不会擦掉屏幕颜色,但曲线的颜色会与直线的颜色进行R2_NOTXORPEN变成另一种颜色
    pDC-> LineTo   (m_pLast);
      pDC-> SelectObject   (oldpen);
    }CDialog::OnMouseMove(nFlags,   point);

      

  11.   

    void   duishugonglvpu::OnMouseMove(UINT   nFlags,   CPoint   point)   

    //   TODO:   Add   your   message   handler   code   here   and/or   call   default 
      if(nFlags==MK_LBUTTON)//如果鼠标按下,执行下面操作 

            SetCapture(); 
      CDC*   pDC=GetDC(); //擦除旧线 
    CPen   pen; 
    pen.CreatePen   (PS_SOLID,1,RGB(0,0,   255)); 
            CPen*   oldpen=pDC-> SelectObject   (&pen); 
    int   t=pDC-> SetROP2(R2_NOTXORPEN);   pDC-> MoveTo(m_pFirst); 
      pDC-> LineTo   (m_pLast); 
      //画新线 
      pDC-> SetROP2(t);        <---------去掉此行!!!!!!
      m_pLast=point; 
      pDC-> MoveTo(m_pFirst); 
      pDC-> LineTo   (m_pLast); 
      pDC-> SelectObject   (oldpen); 
    } CDialog::OnMouseMove(nFlags,   point);