我在视图框架上设定一菜单项,点击该菜单项触发MYCView::Onclick函数。在该函数中我只是简单的通过GetDocument()获取MYCDocument的对象指针pDoc,然后连续三次调用pDoc->UpdateAllViews(NULL),我希望这三次调用能三次触发MYCViews::Ondraw(),从而完成视图的更新,但奇怪的是仅仅调用了一次。实在搞不懂,请多多指点。

解决方案 »

  1.   

    哦     你应该在Onclick 调用 Invalidate();
      

  2.   

    用Invalidate
    或者你更新三次doc,每次更新调用一次pDoc->Upda...。
      

  3.   

    你怎么知道只调用了一次?如果是当前view,你直接用Invalidate();就行了。用UpdateAllViews也行,不过是绕了一大圈,最后也是调用各个view的Invalidate().void CDocument::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint)
    // walk through all views
    {
    ASSERT(pSender == NULL || !m_viewList.IsEmpty());
    // must have views if sent by one of them POSITION pos = GetFirstViewPosition();
    while (pos != NULL)
    {
    CView* pView = GetNextView(pos);
    ASSERT_VALID(pView);
    if (pView != pSender)
    pView->OnUpdate(pSender, lHint, pHint);
    }
    }void CView::OnUpdate(CView* pSender, LPARAM /*lHint*/, CObject* /*pHint*/)
    {
    ASSERT(pSender != this);
    UNUSED(pSender);     // unused in release builds // invalidate the entire pane, erase background too
    Invalidate(TRUE);
    }PS:你的CViewC中,如果重载了Onpaint,可能会造成OnDraw不执行。
      

  4.   

    为什么连续三次调用pDoc->UpdateAllViews(NULL),
    但是仅仅调用了一次Ondraw()。这是因为UpdateAllViews也好,Invalidate()也好, 
    它们发送WM_PAINT给窗口。
    窗口接收到WM_PAINT后, 触发Ondraw()。但是WM_PAINT消息在队列中会被合并。
    也就是说, 当队列中有WM_PAINT消息时,
    再来的WM_PAINT消息会被合并到前一个WM_PAINT消息中。换句话说,不论你“连续”发多少WM_PAINT,最后窗口只能收到一个。
      

  5.   

    rtdb(东临碣石)说得对。如果你真要那样的话,可以这样试试:CDocument* pDoc=GetDocument();
    POSITION pos = pDoc->GetFirstViewPosition();
    while (pos != NULL)
    {
    CView* pView = pDoc->GetNextView(pos);
    for(int i=0;i<3;i++)
             {
                  pView->Invalidate();
                  pView->UpdateWindow();
              }
    }
      

  6.   

    同意上面几位,并有保留。
    :不论你“连续”发多少WM_PAINT,最后窗口只能收到一个。
    我想,Windows处理WM_PAINT的机制是:如果消息队列中有其余消息,这时候向进程发送WM_PAINT消息时(系统发送),会将WM_PAINT消息合并,也就是只更新一次。可是当消息队列中的WM_PAINT已经处理后,再发送的WM_PAINT会重新得到处理,而WM_PAINT的产生是在调用了UpdateWindow()或者RedrawWindow()后才会有的,也就是说,上面这位老兄只要在CView::OnUpdate()里,调用Invalidate();再调用UpdateWindow();就可以达到每次更新都能使CView::OnDraw()得到执行。
      

  7.   

    感谢rtdb 和webber84。
    对Mackz有些不同意见:
    Invalidate(),updateallviews(),showwindow()均会产生WM_PAINT消息,只是该消息的处理优先级较低,而updatewindow()能够使该消息立即得到处理,但它并不会产生WM_PAINT.希望能跟MACKz进一步探讨。