title: GDI+ flickering
body: <p>So I'm trying to make a cheap copy of Gyazo (the screenshotting tool)</p>
  
  <p>The problem is that the cursor coordinates are flickering, how can I prevent that? I have already tried <code>WM_ERASEBKGND</code> but it doesn't help anything.</p>
  
  <p>Also is there anything else wrong with my code? Any bad practices / techniques?</p>
  
  <pre><code>#include &lt;Windows.h&gt;
  #include &lt;string&gt;
  #include &lt;gdiplus.h&gt;
  #pragma comment (lib, "Gdiplus.lib")
  
  // Store the "screenshot" when first launching the program
  HBITMAP hbm;
  
  // This draws the cursor coordinates close to the cursor
  void DrawCursorCoords(Gdiplus::Graphics &amp;graphics, Gdiplus::Bitmap &amp;bitmap, Gdiplus::Color c)
  {
      POINT cursorPos;
      GetCursorPos(&amp;cursorPos);
  
      std::wstring x = std::to_wstring(cursorPos.x);
      std::wstring y = std::to_wstring(cursorPos.y);
  
      graphics.DrawString(x.c_str(), x.length(), &amp;Gdiplus::Font(L"Consolas", 16), Gdiplus::PointF(cursorPos.x, cursorPos.y), &amp;Gdiplus::SolidBrush(c));
      graphics.DrawString(y.c_str(), y.length(), &amp;Gdiplus::Font(L"Consolas", 16), Gdiplus::PointF(cursorPos.x, cursorPos.y + 16), &amp;Gdiplus::SolidBrush(c));
  }
  
  // Paint our stuff
  void Paint(HDC &amp;hdc)
  {
      Gdiplus::Graphics * gfx = new Gdiplus::Graphics(hdc);
      Gdiplus::Bitmap * bmap = new Gdiplus::Bitmap(hbm, (HPALETTE)0);
  
      gfx-&gt;DrawImage(bmap, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
  
      if (GetAsyncKeyState(VK_LBUTTON))
          DrawCursorCoords(*gfx, *bmap, Gdiplus::Color::Red);
      else
          DrawCursorCoords(*gfx, *bmap, Gdiplus::Color::Green);
  
      delete gfx;
      delete bmap;
  }
  
  LRESULT APIENTRY WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  {
      PAINTSTRUCT ps;
      HDC hdc;
  
      switch (message)
      {
      case WM_PAINT:
      {
          hdc = BeginPaint(hwnd, &amp;ps);
  
          Paint(hdc);
  
          EndPaint(hwnd, &amp;ps);
          break;
      }
  
      case WM_TIMER:
      {
          InvalidateRect(hwnd, NULL, NULL);
          break;
      }
  
      case WM_CLOSE:
      {
          DestroyWindow(hwnd);
          break;
      }
  
      case WM_RBUTTONUP:
      case WM_KEYDOWN:
      case WM_DESTROY:
      {
          PostQuitMessage(0);
          break;
      }
  
      case WM_ERASEBKGND: return TRUE;
  
      default: return DefWindowProc(hwnd, message, wParam, lParam);
  
      }
  
      return 0L;
  }
  
  BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  {
      char className[] = "_className";
      HWND hwnd = NULL;
  
      WNDCLASS wc;
      wc.style = 0;
      wc.lpfnWndProc = WndProc;
      wc.cbClsExtra = 0;
      wc.cbWndExtra = 0;
      wc.hInstance = hInstance;
      wc.hIcon = NULL;
      wc.hCursor = LoadCursor(NULL, IDC_CROSS);
      wc.hbrBackground = (HBRUSH)(0);
      wc.lpszMenuName = NULL;
      wc.lpszClassName = className;
  
      if (RegisterClass(&amp;wc))
      {
          hwnd = CreateWindowEx(
              WS_EX_TRANSPARENT | WS_EX_TOPMOST,
              className, NULL,
              WS_POPUP | WS_VISIBLE,
              0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
              NULL, NULL, hInstance, NULL);
      }
  
      if (!hwnd) return FALSE;
  
      ShowWindow(hwnd, SW_SHOW);
      UpdateWindow(hwnd);
  
      SetTimer(hwnd, 1, 1, NULL);
  
      return TRUE;
  }
  
  int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  {
      // Take a screenshot and store it to 'hbm'
      HWND hwndDesktop = GetDesktopWindow();
      HDC hdcDesktop = GetDC(hwndDesktop);
      HDC hdcCapture = CreateCompatibleDC(hdcDesktop);
      hbm = CreateCompatibleBitmap(hdcDesktop, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
      SelectObject(hdcCapture, hbm);
      BitBlt(hdcCapture, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
          hdcDesktop, 0, 0, SRCCOPY | CAPTUREBLT);
  
      // Start GDI+
      Gdiplus::GdiplusStartupInput gdiplusStartupInput;
      ULONG_PTR gdiplusToken;
      Gdiplus::GdiplusStartup(&amp;gdiplusToken, &amp;gdiplusStartupInput, NULL);
  
      MSG msg;
  
      InitInstance(hInstance, nCmdShow);
  
      while (GetMessage(&amp;msg, NULL, 0, 0) &gt; 0)
      {
          TranslateMessage(&amp;msg);
          DispatchMessage(&amp;msg);
      }
  
      Gdiplus::GdiplusShutdown(gdiplusToken);
      DeleteObject(hbm);
      ReleaseDC(hwndDesktop, hdcDesktop);
      DeleteDC(hdcDesktop);
      DeleteDC(hdcCapture);
  
      return msg.wParam;
  }
  </code></pre>