Search code examples
c++winapigraphicspolygonwm-paint

InvalidateRect is not repainting the window


I got a polygon that is drawn whenever I press a button.

I wanted to repaint the polygon as I press the button again, but when I press it, it just paints another polygon without erasing the other one:

//header
#define CREATETRIANGLE 1

//WM_COMMAND
    case 2:
      PAINTPROCEDURE = CREATETRIANGLE;
      InvalidateRect(hwnd, NULL, TRUE);
      break;

//WM_PAINT
case WM_PAINT:
  switch(PAINTPROCEDURE){
    case 0:{
      hdc = BeginPaint(hwnd, &ps);
      EndPaint(hwnd,&ps);
      }
    break;
    case 1:
      RedrawWindow(hwnd, &rect, NULL, RDW_NOCHILDREN); //I tried this function, but it did nothing
      TriangleDC = BeginPaint(hwnd, &tps);
        SelectPen(TriangleDC, CreatePen(PS_SOLID, 2, RGB(256,256,256)));
        SelectBrush(TriangleDC, CreateSolidBrush(RGB(0,192,192)));
       {
       POINT vertices[] = {{baseX,baseY}, {(baseX-(triangle.sideB)),baseY}, {baseX,(baseY-triangle.sideC)}};
       Polygon(TriangleDC, vertices, 3);
       }
      EndPaint(hwnd,&ps);
      PAINTPROCEDURE = 0;
                break;

I also tried to get the polygon out of its scope, but it did nothing as well.


Solution

  • it just paints another polygon without erasing the other one

    When you call BeginPaint, the system will normally call WM_ERASEBKGND before returning. The WM_ERASEBKGND handler is then given a chance to "erase" the window. The default handler (from DefWndProc) will fill the area with the brush from the WNDCLASS for this window.

    It sounds like the erasing isn't happening which can mean: (1) you've provided WM_ERASEBKGND handler that doesn't actually erase the screen, or (2) the hbrBackground in the WNDCLASS is set wrong or set to the null brush.

    In either of those cases, what should happen is that the fErase field of the PAINTSTRUCT you got from BeginPaint will be set to something other than 0, which tells you that you [the WM_PAINT handler] still have to erase the window first.

    Now sometimes people play games with their own custom WM_ERASEBKGND handler when trying to optimize painting (or in a miguided attempt to reduce flicker). That can result in the fErase flag being 0 even if you do need to erase first.

    My advice is to let DefWndProc handle the WM_ERASEBKGND and to make sure you've got a proper value set for hbrBackground in the WNDCLASS. Once that works, you can experiment with other approaches.