InvalidateRect更新失效区。更新由谁完成,WM_PAINT?在何时调用这个函数较适宜?

解决方案 »

  1.   

    程序会在空闲的时候做这方面的处理(处理WM_PAINT消息)
    你也可以调用UpdateWindow来强制即时刷新窗体
      

  2.   

    你需要重新画画的时候,调用InvalidateRect.
      

  3.   

    ixMind(路在何方)  程序会在空闲的时候做这方面的处理,能否讲得更清楚写。何时为空闲?我只看到一次WM_PAINT,是由UpdateWindow(...)产生的(详见下附代码)
    如果去掉BeginPaint(),EndPaint()倒是一直产生WM_PAINT,不过Petzold说这样做是错误的又MSDN 关于WM_PAINT叙述如下:
    The system sends this message when there are no other messages in the application's message queue. 
    程序空闲时干这个。我什么也没干,它应该很空才是,怎么我才看到一次WM_PAINT呢?有点糊涂了。附代码:
    WindowProc(...)//in window procedure
    {   case:
          WM_PAINT:
             OutputDebugString("On message WM_PAINT\n");
             BeginPaint(...);
             EndPaint(...);
             return 0;
    }
      

  4.   

    WM_PAINT 消息用于在窗体某个区域的图像无效(因为遮挡窗体去除,窗体大小改变,窗体位置改变,等等)需要重新绘制客户区时通知窗体的 WindowProcWM_PAINT 并不是一个队列消息,它通过一个队列标志 PM_QS_PAINT 控制,在一次消息循环到下一次消息循环之间,如果 InvalidateRect 等函数或其他情况使窗体的无效区域不为空,队列标志 PM_QS_PAINT 就会被设置,随后 GetMessage 就会因为 PM_QS_PAINT 标志为真而返回一个 WM_PAINT 消息,此时并不清除队列的 PM_QS_PAINT 标志。一般处理 WM_PAINT 消息首先调用 BeginPaint ,这个函数取得窗体的 DC , 并将保存的窗体无效区域设为 DC 的剪切区域后返回,最后,调用 EndPaint 将清空任何窗体无效区域和队列的 PM_QS_PAINT 标志。此外 ValidateRect(hWnd, NULL); 也有相同的作用。如果不清除队列的 PM_QS_PAINT 标志,这将导致 GetMessage 持续返回 WM_PAINT 消息,此外即是系统空闲,如果没有  PM_QS_PAINT 标志,WM_PAINT 消息也不会产生。
      

  5.   

    在windows核心编程的第26章的26.4.1小节讲到的就是消息队列的状态标志
    (不过那上面是QS_PAINT标志)以下供参考
    UpdateWindow的内部流程是检查窗体的无效区域是否为空,如不为空,
    则SendMessage(hwnd, WM_PAINT...)
    (注意SendMessage对于同一个线程的窗体,是直接调用该窗体的WndProc,
    而不是经过消息队列传递的)InvalidateRect只是设置无效区(不知道是不是立即设置paint标志)
    具体的重绘操作是等稍后“空闲”的时候来完成的,因为WM_PAINT/PM_QS_PAINT
    的优先级仅高于WM_TIMER/QS_TIMER,而比其它的都低