我用的是SDI下的formView,在主form中,我要画出两种指示信息,一个为方向指示,一个为偏移量指示。
偏移量指示为一个圆,里面有三条线,其中一条固定,而其它两条线会随着某些值的变化而重新画,我该怎么刷新?
方向指示为一点固定,而另外一点变化而连接成的线。见附件的图形。
如果有例子更好。
[email protected]
谢谢了

解决方案 »

  1.   

    可以在WM_PAINT消息中绘制,也可以另外创建一个CWnd或其他控件(比如CStatic)的继承类来绘制。设置好方向、偏移等数据,用GDI函数按照数据绘制,只需用到MoveTo/LineTo/Ellipse等几个函数。
      

  2.   

    对了,变量改变的时候调用Invalidate刷新就可以更新画面。
      

  3.   

    使用CDocument类的UpdateAllView,和CView类的OnUpdate方法,在CView类的OnInitialUpdate和OnUpdate中都要使用Invalidate方法。
    1.在创建MDI的第七步创建一个CFormView类型的视图CMultiView1View,新建一个视图类CDrawView,2.在ChildFrm头文件中添加成员变量:
     CSplitterWnd m_wndSplitter;
    添加函数:
      virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs,CCreateContext* pContext);在ChildFrm头文件中添加OnCreateClient函数实现体:
    BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT lpcs,CCreateContext* pContext)
    {
    CRect rect;
    GetClientRect(&rect);
    m_wndSplitter.CreateStatic(this,1,2,WS_VISIBLE|WS_CHILD,AFX_IDW_PANE_FIRST);
    m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CMultiView1View),CSize(0,0),pContext);
    m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CDrawView),CSize(0,0),pContext);
    m_wndSplitter.SetColumnInfo(0,rect.Width()/2,10);
    m_wndSplitter.SetColumnInfo(1,rect.Width()/2,10);
    m_wndSplitter.RecalcLayout();
    return TRUE;
    }3.添加文档成员变量 CPoint m_pt;并在构造函数中初始化它4.在视图CMultiView1View中的头文件添加函数:
    virtual void OnUpdate(CView* pView,LPARAM lparam,CObject* pObj);
    afx_msg void OnEditChanged();
    添加成员变量:int xpos;int ypos;在构造函数中将它们赋成0;在视图CMultiView1View中的cpp文件中添加消息注册:
    ON_EN_CHANGE(IDC_EDIT1,&CMultiView1View::OnEditChanged)
    ON_EN_CHANGE(IDC_EDIT2,&CMultiView1View::OnEditChanged)
    void CMultiView1View::DoDataExchange(CDataExchange* pDX)
    {
    CFormView::DoDataExchange(pDX);

    DDX_Text(pDX,IDC_EDIT1,xpos);
    DDX_Text(pDX,IDC_EDIT2,ypos);
    }void CMultiView1View::OnEditChanged()
    {
    UpdateData(TRUE);
    CMultiView1Doc* pDoc=GetDocument();
    pDoc->m_pt.x=xpos;
    pDoc->m_pt.y=ypos; CPoint pt=pDoc->m_pt;
    pDoc->UpdateAllViews(this,1,(CObject*)&pt);
    }void CMultiView1View::OnInitialUpdate()
    {
    CFormView::OnInitialUpdate();
    ResizeParentToFit();
    CMultiView1Doc* pDoc=GetDocument();
    xpos=pDoc->m_pt.x;
    ypos=pDoc->m_pt.y; UpdateData(FALSE);}
    void CMultiView1View::OnUpdate(CView *pView,LPARAM lParam,CObject* pObj)
    {
    if(lParam==2)
    {
    CPoint* pt=(CPoint*)pObj;
    xpos=pt->x;
    ypos=pt->y;
    UpdateData(FALSE);
    CMultiView1Doc* pDoc=GetDocument();
    pDoc->m_pt=*pt;
    }
    }5.在CDrawView头文件中添加成员变量: CPoint ptDraw;在构造函数中初始化它
    添加函数:
    virtual void OnUpdate(CView* pView,LPARAM lHint,CObject* cHint);
    virtual void OnInitialUpdate();
    添加消息声明:
    afx_msg void OnLButtonDown(UINT nflags,CPoint pt);在CDrawView的Cpp文件中添加消息注册:
    ON_WM_LBUTTONDOWN()
    添加函数体:
    void CDrawView::OnDraw(CDC* pDC)
    {
    CMultiView1Doc* pDoc =(CMultiView1Doc*) GetDocument();

    ptDraw=pDoc->m_pt;
    CBrush ptBrush;
    ptBrush.CreateSolidBrush(RGB(255,0,0));
    CBrush* bhOld=pDC->SelectObject(&ptBrush);
    pDC->Rectangle(ptDraw.x,ptDraw.y,ptDraw.x+10,ptDraw.y+10);
    pDC->SelectObject(&ptBrush);
    // TODO: 在此添加绘制代码
    }void CDrawView::OnInitialUpdate()
    {
    CMultiView1Doc* pDoc=(CMultiView1Doc*)GetDocument();
    ptDraw=pDoc->m_pt;
    Invalidate();
    }void CDrawView::OnUpdate(CView *pView, LPARAM lHint, CObject *cHint)
    {
    if(lHint==1)
    {
    CPoint* pt=(CPoint*)cHint;
    this->ptDraw=*pt;
    Invalidate();
    }
    }
    void CDrawView::OnLButtonDown(UINT nflags,CPoint pt)
    {
        ptDraw=pt;
    CMultiView1Doc* pDoc=(CMultiView1Doc*)GetDocument();
    pDoc->UpdateAllViews(this,2,(CObject*)&ptDraw);
    Invalidate();
    }
      

  4.   

    每次更新都用Invalidate不是好方法,而且如果画布很大更新很频繁的话将严重影响效率!
    可以在需要更新的地方通过GetDC局部擦除局部绘制。
    还可以使用下面的方法进行动态的擦除。int nDrawMode = ::SetROP2(hDC,R2_NOT);
    Draw...
    ......
    SetROP2(hDC,nDrawMode);=====================================================
    阙海忠 (CTO Skin++ 开发成员 http://www.uipower.com 上海勇进软件有限公司)