我在视图框架上设定一菜单项,点击该菜单项触发MYCView::Onclick函数。在该函数中我只是简单的通过GetDocument()获取MYCDocument的对象指针pDoc,然后连续三次调用pDoc->UpdateAllViews(NULL),我希望这三次调用能三次触发MYCViews::Ondraw(),从而完成视图的更新,但奇怪的是仅仅调用了一次。实在搞不懂,请多多指点。
解决方案 »
- C++double精度处理问题,求解
- VC 对EXCEL的操作时,如何设置......?
- 做网管软件的前途(市场)如何?
- 关于自定义类的问题!~
- 有关生产数码相机可行性报告!CSDN的朋友,帮帮我啊!!
- 处理ACCESS2000中的时间类型——初学者在线等,急!
- 一个关于msado15.dll的问题!急!急!急!非常急!在线等待!
- odbc api中的SQLProcedures如何获得数据原的store procedure的列表?
- 请教 tide(水手辛巴德) 比较急
- 求助:我在VC++环境下 使用ADO连接EXCEL出现了 abnormal program termination错误 呼唤达人帮忙!!
- 资源中的位图如何用StretchDIBits显示出来
- 谁知道TRUE TYPE 字体的相关内容?怎样读取其轮廓信息?
或者你更新三次doc,每次更新调用一次pDoc->Upda...。
// 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不执行。
但是仅仅调用了一次Ondraw()。这是因为UpdateAllViews也好,Invalidate()也好,
它们发送WM_PAINT给窗口。
窗口接收到WM_PAINT后, 触发Ondraw()。但是WM_PAINT消息在队列中会被合并。
也就是说, 当队列中有WM_PAINT消息时,
再来的WM_PAINT消息会被合并到前一个WM_PAINT消息中。换句话说,不论你“连续”发多少WM_PAINT,最后窗口只能收到一个。
POSITION pos = pDoc->GetFirstViewPosition();
while (pos != NULL)
{
CView* pView = pDoc->GetNextView(pos);
for(int i=0;i<3;i++)
{
pView->Invalidate();
pView->UpdateWindow();
}
}
:不论你“连续”发多少WM_PAINT,最后窗口只能收到一个。
我想,Windows处理WM_PAINT的机制是:如果消息队列中有其余消息,这时候向进程发送WM_PAINT消息时(系统发送),会将WM_PAINT消息合并,也就是只更新一次。可是当消息队列中的WM_PAINT已经处理后,再发送的WM_PAINT会重新得到处理,而WM_PAINT的产生是在调用了UpdateWindow()或者RedrawWindow()后才会有的,也就是说,上面这位老兄只要在CView::OnUpdate()里,调用Invalidate();再调用UpdateWindow();就可以达到每次更新都能使CView::OnDraw()得到执行。
对Mackz有些不同意见:
Invalidate(),updateallviews(),showwindow()均会产生WM_PAINT消息,只是该消息的处理优先级较低,而updatewindow()能够使该消息立即得到处理,但它并不会产生WM_PAINT.希望能跟MACKz进一步探讨。