title: Win32 API: How to avoid flickering of basic window controls?
body: <p>I scroll the parent window by invalidating and redrawing all the content inside WM_PAINT according to current nPos value from scrollbar. I want to scroll without flickering so I handle WM_ERASEBKGND to avoid redrawing the background. I also do simple double buffering for my TextOut calls and for some bitmaps that are displayed. It works good except my child controls. They flicker badly especially when nPos == 0 and app handles SB_LINEUP or nPos == nMax and app handles SB_LINEDOWN or when dragging and dropping the scrollbar. I move them with MoveWindow(). I also have tried DeferWindowPos(). I've googled it for a solution for flickering but it doesn't work or I'm not using it correctly. How to eliminate flickering of child controls?</p>
  
  <p>P.S. When I use WS_CLIPCHILDREN style for main window the controls aren't flickering but when scrolling some parts of my window get messed up, especially my static control on which I'm drawing some things by handling WM_DRAWITEM.</p>
  
  <p>EDIT: (simplified code)
  I double buffer inside WM_PAINT like this:</p>
  
  <pre><code>case WM_PAINT: {
      hDC = BeginPaint( hwnd, &amp;PS );
      hDCMem = CreateCompatibleDC( hDC );
      hBMMem = CreateCompatibleBitmap( hDC, wnd_x, wnd_y );
      SelectObject( hDCMem, hBMMem );
  
      Font = CreateFont( 130, 50, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN, "Arial" );
      SelectObject( hDCMem, Font );
      SetTextColor( hDCMem, RGB( 30, 144, 255 ) );
      SetBkColor( hDCMem, RGB( 192, 192, 192 ) );
      TextOut( hDCMem, 650, 69 - scr_pos, "ABC", 3 );
  
      MoveWindow( GetDlgItem( hwnd, ID_BUTT_START ), 720, 500 - scr_pos, 160, 150, TRUE );
  
      BitBlt( hDC, 0, 0, wnd_x, wnd_y, hDCMem, 0, 0, SRCCOPY );
      DeleteObject( hBMMem );
      DeleteDC( hDCMem );
      EndPaint( hwnd, &amp;PS );
  }
  </code></pre>
  
  <p>scr_pos is current nPos value taken from scrollbar.</p>
  
  <pre><code>case WM_ERASEBKGND:
      return 1;
  break;
  
  case WM_VSCROLL: {
      SCROLLINFO sinfo;
      ZeroMemory( &amp;sinfo, sizeof( SCROLLINFO ) );
      sinfo.cbSize = sizeof( SCROLLINFO );
      sinfo.fMask = SIF_POS | SIF_PAGE | SIF_TRACKPOS;
      GetScrollInfo( hwnd, SB_VERT, &amp;sinfo );
      scr_pos = sinfo.nPos;
      switch( LOWORD( wParam ) ) {
          case SB_TOP:
              scr_pos = 0;
          break;
          case SB_BOTTOM:
              scr_pos = 4000;
          break;
          case SB_LINEUP: {
              scr_pos -= 200;
              if ( scr_pos &lt; 0 ) {
                  scr_pos = 0;
              }
          }
          break;
          case SB_LINEDOWN: {
              scr_pos += 200;
              if ( scr_pos &gt; 4000 ) {
                  scr_pos = 4000;
              }
          }
          break;
          case SB_PAGEUP: {
              scr_pos -= si.nPage;
              if( scr_pos &lt; 0 ) {
                  scr_pos = 0;
              }
          }
          break;
          case SB_PAGEDOWN: {
              scr_pos += si.nPage;
              if( scr_pos &gt; 4000 ) {
                  scr_pos = 4000;
              }
          }
          break;
          case SB_THUMBPOSITION:
              scr_pos = HIWORD(wParam);
          break;
          case SB_THUMBTRACK:
              scr_pos = HIWORD(wParam);
          break;
      }    
      RedrawWindow( hwnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT );
  //  InvalidateRect ( hwnd, NULL, true );
  //  UpdateWindow( hwnd );
      ZeroMemory( &amp; sinfo, sizeof( SCROLLINFO ) );
      sinfo.cbSize = sizeof( SCROLLINFO );
      sinfo.fMask = SIF_POS;
      snfo.nPos = scr_pos;
      SetScrollInfo( hwnd, SB_VERT, &amp; sinfo, TRUE );
      }
  }
  break;
  </code></pre>
  
  <p>Nothing flickers except child controls...</p>