如何保存鼠标绘制的任意曲线。我建立了一个对话框可以实现在桌面上绘制曲线。准确第说:在onnmousemove里绘制曲线。onlubuttondown里记录起点。
onlbuttonup里releasecapture.    onmousemove里:OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值 HWND hwnd=::GetDesktopWindow();
HDC hdc; if(nFlags==MK_LBUTTON) //判断鼠标左键是否按下,如果按下,则移动时画线
{ hdc= ::GetWindowDC(hwnd); MoveToEx(hdc,m_StartPoint.x, m_StartPoint.y, NULL); LineTo(hdc,m_StartPoint.x,m_StartPoint.y);
m_StartPoint.x=point.x; 
m_StartPoint.y=point.y; ::ReleaseDC(NULL,hdc); }
CDialog::OnMouseMove(nFlags, point);
}现在的问题是:由于没有在onpaint里绘制曲线,会导致, 比如:其他窗口一旦遮盖了我们绘制的曲线,则立即消失。所以想把代码放到ondraw里。 如何操作?放到ondraw 里。帮忙修改一下,谢谢了啊

解决方案 »

  1.   

    不知道你这个是基于对话框的程序还是SDI/MDI程序,
    如果是对话框程序,那么是没有OnDraw函数的,你可以理解OnPaint就是OnDraw。
    对于重绘操作,侯捷《深入浅出mfc》书中第八章--第十章都是围绕这个在说,非常详细,如果你既想知其然,又想知其所以然,那就去好好看看书吧,网上也有很多电子版!
      

  2.   

    笔误,我是想放到onpaint里。、谁能帮我啊
      

  3.   

    自己写一个带CDC入参的函数,可以设置一个全局变量的容器,搜集你MK_LBUTTON点击的点。然后在OnPaint中调用即可。效果就是没点的时候不画,有点的时候画。就这样
      

  4.   


    显然不对点是无穷的,你能保存多少?另外sorry, 我是用onpain的。
      

  5.   

    在屏幕DC上画就可以了
    另外推荐一下我写的小程序关于手绘图形识别的
    欢迎大家来拍砖 http://bbs.csdn.net/topics/390273653?page=1#post-392853754
      

  6.   

    你把代码移到onpaint下面一样会出现这个问题的,正确的做法应该是在lbuttondown记录起点,并记录标志要开始画线了。然后在mousemove记录移动的点,和lbuttonup记录终点。在Onpaint里面再来根据是否要画线的标志位来根据你记录的点来画线,这样就不怕发生重绘了
      

  7.   

    点是无穷的,你能保存多少?你点击的点保存。自己在用MoveTo和LineTo画点的时候,保存这些关键点。你说无限的点,感觉你不理解自己写的代码。Onpaint  有CPaintDC可以获取的。属于CDC的范畴,也可以用的。
      

  8.   


    看源码,结果不能绘制了void CTestView::OnLButtonDown(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    m_bIsDrawed=TRUE;
    g_vHPoints.push_back(point);
    CView::OnLButtonDown(nFlags, point);
    }void CTestView::OnMouseMove(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
     HDC hdc; /* if(nFlags &MK_LBUTTON  )
     {*/
     
    /* hdc= ::GetWindowDC(GetSafeHwnd()); ::MoveToEx(hdc,m_startPoint.x, m_startPoint.y, NULL);  ::LineTo(hdc,point.x,point.y);  m_startPoint=point; 
       ::ReleaseDC(NULL,hdc);*/  g_vHPoints.push_back(point); //保存点
    /* }*/
     CView::OnMouseMove(nFlags, point);}void CTestView::OnLButtonUp(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    g_vHPoints.push_back(point); //记录终点坐标
    m_bIsDrawed=FALSE;
    g_vHPoints.clear();
    CView::OnLButtonUp(nFlags, point);
    }
    void CTestView::OnDraw(CDC* /*pDC*/)
    {
    CTestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
    return; if(m_bIsDrawed)
    {
    HDC hdc; int i=0; hdc= ::GetWindowDC(GetSafeHwnd()); ::MoveToEx(hdc,g_vHPoints[0].x, g_vHPoints[0].y, NULL); for(i=1; i<g_vHPoints.size(); ++i)
    {  
    ::LineTo(hdc,g_vHPoints[i].x, g_vHPoints[i].y);
    ::MoveToEx(hdc,g_vHPoints[i].x, g_vHPoints[i].y, NULL);
    }
    ::ReleaseDC(NULL,hdc);
    } // TODO: 在此处为本机数据添加绘制代码
    }
    啥曲线都不能绘制了
      

  9.   


    void CTestView::OnLButtonDown(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    m_bIsDrawed=TRUE;
    g_vHPoints.push_back(point);
    Invalidate();  //加了这句后,可以绘制,但是曲线对不上,乱七八糟的
    CView::OnLButtonDown(nFlags, point);
    }
      

  10.   


    void Cttttt111Dlg::OnLButtonDown(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    m_ptBegin = point;
    m_ptEnd = point;
    m_bLine = TRUE;
    CDialog::OnLButtonDown(nFlags, point);
    }void Cttttt111Dlg::OnMouseMove(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    if (point != m_ptEnd)
    {
    m_ptBegin = m_ptEnd;
    m_ptEnd = point;
    }
    Invalidate(FALSE);
    CDialog::OnMouseMove(nFlags, point);
    }void Cttttt111Dlg::OnLButtonUp(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    m_bLine = FALSE;
    CDialog::OnLButtonUp(nFlags, point);
    }
    void Cttttt111Dlg::OnPaint()
    {
    if (IsIconic())
    {
    CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中
    int cxIcon = GetSystemMetrics(SM_CXICON);
    int cyIcon = GetSystemMetrics(SM_CYICON);
    CRect rect;
    GetClientRect(&rect);
    int x = (rect.Width() - cxIcon + 1) / 2;
    int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标
    dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
    //CDialog::OnPaint();
    CPaintDC dc(this);
    dc.MoveTo(m_ptBegin);
    dc.LineTo(m_ptEnd);
    }
    }
    随随便画,注意Invalidate(FALSE),默认只TRUE表示全重绘,会檫出背景。仅仅这样,被窗口覆盖后在拿开,被覆盖的一样会丢失,这个时候就要处理OnEraseBkgnd(CDC* pDC)这个消息了。把檫出前的画面保存下来,在重绘的时候就先画保存下来的画面,在话新的线,就搞定了
      

  11.   

    曲线对应不上就看自己的点是屏幕坐标和控件坐标是否转换了ScreenToClient函数
      

  12.   


    依然什么曲线绘制不了
    原因猜测:是起点和终点的坐标一样导致的但是保存坐标,是这样保存的啊
     void CTestView::OnDraw(CDC* /*pDC*/)
    {
    CTestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
    return;
    if(m_bIsPainted)
    {
    HDC hdc; hdc= ::GetWindowDC(GetSafeHwnd()); ::MoveToEx(hdc,m_startPoint.x, m_startPoint.y, NULL);
    ::LineTo(hdc,m_endPoint.x, m_endPoint.y); ::ReleaseDC(NULL,hdc);
    }
    }// CTestView 消息处理程序void CTestView::OnLButtonDown(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    m_startPoint=m_endPoint=point; m_bIsPainted=TRUE; Invalidate(FALSE); CView::OnLButtonDown(nFlags, point);
    }void CTestView::OnMouseMove(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值   m_startPoint=m_endPoint;   m_endPoint=point;
     CView::OnMouseMove(nFlags, point);}void CTestView::OnLButtonUp(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值 m_bIsPainted=FALSE; CView::OnLButtonUp(nFlags, point);
    }
      

  13.   

    hdc= ::GetWindowDC(GetSafeHwnd());拿错DC了hdc = GetDC()->GetSafeHwnd();
      

  14.   

    试了一下,见代码#include "vector"
    using namespace std;
    vector<CPoint> g_vHPoints;void CDesktopDrawView::OnDraw(CDC* pDC)
    {
    CDesktopDrawDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here
    if(g_vHPoints.size() > 0)     
    {         
    HDC hdc;           
    int i=0;           
    hdc= ::GetWindowDC(GetSafeHwnd());           
    ::MoveToEx(hdc,g_vHPoints[0].x, g_vHPoints[0].y, NULL);           
    for(i=1; i<g_vHPoints.size(); ++i)         
    {                 
    ::LineTo(hdc,g_vHPoints[i].x, g_vHPoints[i].y);             
    ::MoveToEx(hdc,g_vHPoints[i].x, g_vHPoints[i].y, NULL);         
    }         
    ::ReleaseDC(NULL,hdc);  

    }void CDesktopDrawView::OnMouseMove(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
    g_vHPoints.push_back(point);      //保存点
    Invalidate(FALSE); CView::OnMouseMove(nFlags, point);
    }
      

  15.   

    不要保存点(点那么多,你不怕内存爆啊)。
    用一个CBitmap来保存所有绘制,每次绘制都在前一次基础上绘制