0

I have run into this "BitBlt" from time to time in my searched, but i don´t get how to use it.

From what people say, it seems to be the fastest way to capture a screen that Windows show. However, i can´t say anything about that myself as i don´t got it working.

The only thing i have manage to atleast, try the method, is with this:

 gfxBmp.CopyFromScreen(0,0,0,0 rc.Size,CopyPixelOperation.CaptureBlt);

Which i guess uses it? (rc.size = size of a certain window) Sadly, it doesn´t do anything, i get a black picture. if i use SourceCopy however, it works, but that is the normal method.

I am currently trying to replace some code, to use BltBit, but it isn´t working that well either:

    public MemoryStream CaptureWindow(IntPtr hwnd, EncoderParameters JpegParam)
    {
        NativeMethods.Rect rc;
        NativeMethods.GetWindowRect(hwnd, out rc);
        using (Bitmap bmp = new Bitmap(rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
        {

            using (Graphics gfxBmp = Graphics.FromImage(bmp))
            {
                IntPtr hdcBitmap = gfxBmp.GetHdc();
                try
                { 

                    NativeMethods.BitBlt(hdcBitmap, 0, 0, 0, 0, hwnd, 0, 0, 0xCC0020);

                }
                finally
                {
                    gfxBmp.ReleaseHdc(hdcBitmap);
                }
            }
            MemoryStream ms = new MemoryStream();
            bmp.Save(ms, GetEncoderInfo(ImageFormat.Jpeg), JpegParam);

            return ms;
        }
    }
Zerowalker
  • 761
  • 2
  • 8
  • 27

1 Answers1

1

You are right, Graphics.CopyFromScreen already uses BitBlt internally. Following, the code from the .NET 4.0 Framework:

// [...]
new UIPermission(UIPermissionWindow.AllWindows).Demand();
int width = blockRegionSize.Width;
int height = blockRegionSize.Height;
using (DeviceContext deviceContext = DeviceContext.FromHwnd(IntPtr.Zero))
{
    HandleRef hSrcDC = new HandleRef(null, deviceContext.Hdc);
    HandleRef hDC = new HandleRef(null, this.GetHdc());
    try
    {
        if (SafeNativeMethods.BitBlt(hDC, destinationX, destinationY, width, height, hSrcDC, sourceX, sourceY, (int)copyPixelOperation) == 0)
        {
            throw new Win32Exception();
        }
    }
    finally
    {
        this.ReleaseHdc();
    }
}

There are other possibilities to capture screenshots. You could use as well the WinAPI function PrintWindow.

But for graphiccard-accelerated content, both won't work. The hardware overlay resides in the gpu-memory, where you can't access it. That's why you often get a black image for videos, games, ...

Thomas B.
  • 2,276
  • 15
  • 24
  • It does? does it use it even with SourceCopy? And for the code, i don´t get how to implement it in my code (the other code segment in my post). I am currently using PrintWindow, Though, i am having a bit of a problem with it, as it forces the window to refresh all the time. Some applications doesn´t like that. – Zerowalker Aug 09 '13 at 07:27
  • The code was only an extract from the CopyFromScreen code. Use ILSpy(http://ilspy.net/) to see for yourself. – Thomas B. Aug 09 '13 at 07:45
  • Ah then i understand why you wrote like that. Hmm, still need to get it working somehow though, as i only get a blackscreen, not matter what i capture with BlBit (can be desktop or whatever). – Zerowalker Aug 09 '13 at 07:56