title: Desktop screen overlay - transparency key visual artefacts during CopyFromScreen
body: <p>This is a continuation of my other question (understanding of it is not required, just for reference):</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/34420599/desktop-screen-overlay-new-form-flicker-issue">Desktop screen overlay - new form flicker issue</a></li>
  </ul>
  
  <p>It turns out that Graphics.CopyFromScreen which I'm using has the following artefact - it assumes I want to copy with transparency key = Color.Black, so it skips those very dark areas - part of my desktop background image - they suddenly appear in white, and now it looks rather ugly:</p>
  
  <p><a href="https://i.stack.imgur.com/FflaH.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FflaH.png" alt="enter image description here"></a></p>
  
  <p>The code I'm currently using is provided below:</p>
  
  <pre><code>private static Bitmap MakeScreenshot()
  {
    Rectangle bounds = Screen.GetBounds(Point.Empty);
    Bitmap image = new Bitmap(bounds.Width, bounds.Height);
  
    using (Graphics g = Graphics.FromImage(image))
    {
      g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
    }
  
    return image;
  }
  </code></pre>
  
  <p><a href="https://stackoverflow.com/a/10234693/897326">An answer by Hans Passant</a> suggested using a <strong>p/invoke</strong> instead, but for a different issue - layered windows - so I tried that, and it <strong>worked</strong>, below is equivalent code, but now using WinApi:</p>
  
  <pre><code>public static Bitmap CreateBitmapFromDesktopNew()
  {
    Size sz = GetDesktopBounds().Size;
    IntPtr hDesk = GetDesktopWindow();
    IntPtr hSrce = GetWindowDC(hDesk);
    IntPtr hDest = CreateCompatibleDC(hSrce);
    IntPtr hBmp = CreateCompatibleBitmap(hSrce, sz.Width, sz.Height);
    IntPtr hOldBmp = SelectObject(hDest, hBmp);
    bool b = BitBlt(hDest, 0, 0, sz.Width, sz.Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
    Bitmap bmp = Bitmap.FromHbitmap(hBmp);
    SelectObject(hDest, hOldBmp);
    DeleteObject(hBmp);
    DeleteDC(hDest);
    ReleaseDC(hDesk, hSrce);
    return bmp;
  }
  </code></pre>
  
  <p><strong>Question:</strong> Is there a native .NET approach that solves my particular problem? I'm trying to avoid using WinApi if there is a better way of doing it.</p>