这样一段程序,鼠标按下,在对话框上画一个不同颜色的方块,抬起恢复。鼠标按下后方块绘制过程也执行了,但是没有画到屏幕上,方块颜色没变。是何缘故, 请求指点。为什么PAINT执行却不被应用到屏幕上。void CMoeventDlg::OnPaint() 
{ CPaintDC dc(this); // device context for painting
if(mouse_on)
dc.FillSolidRect(0,0,30,30,RGB(123,121,12));
else
dc.FillSolidRect(0,0,30,30,RGB(0,121,200));
CDialog::OnPaint();}void CMoeventDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
// TODO: Add your message handler code here and/or call default
mouse_on=true;
SendMessage(WM_PAINT);
CDialog::OnLButtonDown(nFlags, point);
}void CMoeventDlg::OnRButtonUp(UINT nFlags, CPoint point) 
{
// TODO: Add your message handler code here and/or call default
mouse_on=false;
SendMessage(WM_PAINT);
CDialog::OnRButtonUp(nFlags, point);
}

解决方案 »

  1.   

    void CMoeventDlg::OnPaint() 
    { CPaintDC dc(this); // device context for painting
    if(mouse_on)
    dc.FillSolidRect(0,0,30,30,RGB(123,121,12));
    else
    dc.FillSolidRect(0,0,30,30,RGB(0,121,200));
    CDialog::OnPaint();}
    这段函数不行吧。虽然你前面调用了dc的绘制函数。但是,CDialog::OnPaint()将把你前面绘制的内容又刷掉的
      

  2.   

    不要调用
    CDialog::OnPaint();
    SendMessage(WM_PAINT);=>Invalidate(FALSE);
      

  3.   

    SendMessage(WM_PAINT);=>Invalidate(FALSE);
      

  4.   

    用Invalidate(FALSE)来触发wm_pain消息
      

  5.   

    仔细研究了一下。MSDN上说WM_PAINT会被UpdateWindow或者RedrawWindow引起,其处理一般为BeginPaint和EndPaint等等,就是重画。但是使用楼主的程序Debug也可以明显的看到它调用了OnPaint函数,但是就是没有改变。测试了一下,使用UpdateWindow代替SendMessage(WM_PAINT);同样可以触发OnPiant函数,但是效果一样没有改变;使用RedrawWindow代替SendMessage(WM_PAINT);就可以看到改变了,为什么?Invalidate确实也能更新。
      

  6.   

    如果有高手为我们解释一下以下调用详细过程最好了:
    SendMessage(WM_PAINT);//是不是应该有后面的两个参数wParam和lParam?怎么设置这两个参数?
    UpdateWindow();//为什么它同样触发了OnPaint函数,为什么也不行?
    RedrawWindow();//它比上面的UpdateWindow多做了什么?为什么它能行?
      

  7.   

    UpdateWindow();//为什么它同样触发了OnPaint函数,为什么也不行?
    RedrawWindow();//它比上面的UpdateWindow多做了什么?为什么它能行?我的理解:UpdateWindow是对整个窗口的全部进行绘画比如包括系统菜单等,而RedrawWindow去不包含系统菜单的绘画
      

  8.   

    还有我觉得用InvalidateRect(FALSE);更好,如果说错了当我没说,出现这个现象,可以肯定地是被“刷”掉了
      

  9.   

    我的理解:UpdateWindow是对整个窗口的全部进行绘画比如包括系统菜单等,而RedrawWindow去不包含系统菜单的绘画
    ========================================
    不管是不是包含菜单,按道理都是应该刷新的啊,呵呵
      

  10.   


    InvalidateRect()实际上也是发送WM_PAINT消息的!!!楼主这个问题有意思,我去研究一下。
      

  11.   

    将CPaintDC dc(this); 
    改为
    CClientDC dc(this); // device context for painting
    其他都不动
      

  12.   

    代码:
    头文件中:bool mouse_on;
    构造函数中mouse_on = false;
    void CMoeventDlg::OnPaint() 
    { CClientDC dc(this); // device context for painting
    if(!mouse_on)
    dc.FillSolidRect(10,10,30,30,RGB(123,121,12));
    else
    dc.FillSolidRect(0,0,30,30,RGB(0,121,200));
    CDialog::OnPaint();}void CMoeventDlg::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
    mouse_on=true;
    SendMessage(WM_PAINT);
    CDialog::OnLButtonDown(nFlags, point);
    }void CMoeventDlg::OnLButtonUp(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
    mouse_on=false;
    SendMessage(WM_PAINT);
    CDialog::OnRButtonUp(nFlags, point);
    }
      

  13.   

    楼主我试过了Invalidate(TRUE);
    UpdateWindow();和RedrawWindow();
    作用是相同.
      

  14.   


    SendMessage(WM_PAINT);
    UpdateWindow();//只有出现更新区域此函数才有效果
    不行.
      

  15.   

    我也仔细研究了一下,有如下结论:
    1、MFC的Invalidate()和InvalidateRect()都是调用的
       WIN API: InvalidateRect().
    2.
      使用InvalidateRect(..)可以触发WM_PAINT,但系统并不立即重绘
      (这是因为WM_PAINT的2个特性:low priority、
        Windows combines multiple WM_PAINT messages in the message queue
       into a single message. )
    3.
      如果想立即重绘,那么就需要调用UpdateWindow();
    4.
      InvalidateRect(true,...,NULL)
      UpdateWindow();

      RedrawWindow(..);
      等价。
    5.
      这是最重要的,本帖的关键:
      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_88ac.asp
      :
      The WM_PAINT message is generated by the system and should not be sent by an application.