views:

148

answers:

1

Hello,

I use BitBlt() and CreateBitmapSourceFromHBitmap() to capture a window as a BitmapSource that I can display on an Image element in a WPF application. But for some reason, most of the application that it captures is transparent. Here is a source vs. capture image of what's happening:

http://userpages.umbc.edu/~smyth1/images/screencap.PNG

It's gray because the background of the window it's on is gray. Whatever background I give the window will show through.

How can I get the captured image to more accurately reflect the original?

+2  A: 

The problem in your code could be due to the Win32 API you're using (CreateCompatibleDC, SelectObject, CreateBitmap...). I tried with a simpler code, using only GetDC and BitBlt, and it works fine for me. Here's my code:

    public static Bitmap Capture(IntPtr hwnd)
    {
        IntPtr hDC = GetDC(hwnd);
        if (hDC != IntPtr.Zero)
        {
            Rectangle rect = GetWindowRectangle(hwnd);
            Bitmap bmp = new Bitmap(rect.Width, rect.Height);
            using (Graphics destGraphics = Graphics.FromImage(bmp))
            {
                BitBlt(
                    destGraphics.GetHdc(),
                    0,
                    0,
                    rect.Width,
                    rect.Height,
                    hDC,
                    0,
                    0,
                    TernaryRasterOperations.SRCCOPY);
            }
            return bmp;
        }
        return null;
    }

I tried it in Windows Forms and WPF (with Imaging.CreateBitmapSourceFromHBitmap), it works fine in both cases for the same screenshot (SO page in Firefox).

HTH,

Thomas Levesque
Thanks! Where can I find GetWindowRectangle?
directedition
It's just a helper method for the GetWindowPlacement API, used to get the window size. I didn't post it because it wasn't meaningful, but I can add it if you want
Thomas Levesque
If you wouldn't mind posting it, or linking me to a doc on it, I'd greatly appreciate it.
directedition
Alright, I'm using:[DllImport("user32.dll")]private static extern bool GetWindowRect(IntPtr hWnd, out RECT lprect);And it's working great! Thanks a ton!
directedition