Thread: repainting again...

  1. #1
    Unregistered
    Guest

    repainting again...

    I want to handle WM_ERASEBKGND message by myself, because when I let Windows handle it, the whole application window is erased, including all child windows. If I send WM_ERASEBKGND message manually, I must get the context device and send it with the message in WPARAM. I retreive such a context device using GetDCEx() with DCX_CLIPCHILDREN flag and the clipping region is set properly (does not contaion child windows). Then in WM_ERASEBKGND part of message handling procedure, I get this context device, get the clipping rectangle using GetClipBox() and fill it with color simulating "the erasing of a window". It may be like this:
    Code:
      case WM_COMMAND:
        {
          // ...
          // in response to e.g. toolbar button click
          HDC hDC = GetDCEx(hWnd, NULL, DCX_CLIPCHILDREN | DCX_CACHE);
          SendMessage(WM_ERASEBKGND, (WPARAM)hDC, 0);
          // some drawing using hDC...
          ReleaseDC(hWnd, hDC);
        }
        break;
    
        // ...
    
      case WM_ERASEBKGND:
        {
          RECT rcWin;
          GetClipBox((HDC)wParam, &rcWin);  // GetUpdRect() returns a free rectangle here!
          FillRect(hDC, &rcWin, hBrush);  // hBrush can be obtained by calling GetWindowLong()
        }
        break;
    This works fine. But only when I send WM_ERASEBKGND by myself. If it's sent by Windows, for example as a result of calling BeginPaint() in WM_PAINT message:
    Code:
      case WM_PAINT:
        PAINTSTRUCT ps;
        HDC hDC = BeginPaint(hWnd, &ps);
        // now Windows send a WM_ERASEBKGND message and return here
        // some drawing...
       EndPaint(hWnd, &ps);  
       // I don't remember the exact syntax of BeginPaint() and EndPaint(), it doesn't matter now
    the clipping and even update rectangle is free. So I need to handle it like this:
    Code:
      case WM_ERASEBKGND:
        {
          RECT rcWin;
          GetClipBox((HDC)wParam, &rcWin);
          if (IsEmptyRect(rcWin)) GetClientRect(hWnd, &rcWin);
          FillRect(hDC, &rcWin, hBrush);
        }
        break;
    But in this case, I there is a whole window in rcWin so I'm back where I began with problem. I'm redrawing whole window. This flickers on slow computers.
    My question is, how to get the proper update (or clipping) rectangle when WM_ERASEBKGND is sent automatically by Windows?

  2. #2
    S­énior Member
    Join Date
    Jan 2002
    Posts
    982
    I'm not sure what you mean by "the clipping and even update rectangle is free". But you have to return a non-zero value from a WM_ERASEBKGND message to indicate that all erasing has been done. Have you read -

    http://msdn.microsoft.com/library/de...dn_flicker.asp

  3. #3
    Unregistered
    Guest
    Take a close look at the PAINTSTRUCT that you pass to BeginPaint
    in your WM_PAINT handler - specifically the rcPaint parameter. This (and the rest) is filled by the call to BeginPaint.

    Use InvalidateRect(hwnd, &rc, 1); if you want to re-paint with erase of the rectangle given by rc. Although sending messages explicitly can be made to work it is a lot simple using InvalidateRect.

    Look too at InvalidateRgn, UpdateWindow and RedrawWindow for more discussion and solutions.

  4. #4
    Registered User larry's Avatar
    Join Date
    Sep 2001
    Posts
    96
    I've had some problem with logging in, so I posted this thread as an Unregistered. There is a correction of the last article.
    But in this case, there is a whole window in rcWin so I'm back where I began with problem. I'm redrawing whole window. This flickers on slow computers.
    My question is, how to get the proper update (or clipping) rectangle when WM_ERASEBKGND is sent automatically by Windows?
    Now for the answers.
    I'm not sure what you mean by "the clipping and even update rectangle is free". But you have to return a non-zero value from a WM_ERASEBKGND message to indicate that all erasing has been done.
    I meant that both GetUpdateRect() and GetClipBox() return empty rectangles. As for the return value, I just forgot to write it, but I know it should be there. I usually return TRUE from WM_ERASEBKGND.

    I don't want to invalidate the window, because it would cause another WM_PAINT message to be sent and the rcPaint rectangle is empty or contains whole client window. I want to redraw the part of main window that doesn't contain any child windows. As I do when WM_ERASEBKGND is sent from WM_COMMAND part.

    Sorensen, thanx for the link...
    Please excuse my poor english...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Parent not repainting Bitmp after child window closes
    By CodeX in forum Windows Programming
    Replies: 5
    Last Post: 10-05-2006, 12:03 AM
  2. Repainting form
    By publikum in forum C# Programming
    Replies: 3
    Last Post: 06-05-2005, 12:44 AM
  3. forcing window repainting after putting back caption
    By underthesun in forum Windows Programming
    Replies: 2
    Last Post: 02-05-2005, 10:13 PM
  4. [newbie] repainting window
    By Rage7531 in forum Windows Programming
    Replies: 3
    Last Post: 06-09-2002, 10:02 PM
  5. repainting a window
    By larry in forum Windows Programming
    Replies: 3
    Last Post: 01-15-2002, 10:58 PM