3

so ive been having a bit of a memory leak problem with my C# code, I have searched fairly thoroughly and do realize there is another question here WPF CreateBitmapSourceFromHBitmap() memory leak (and many others) that sort of cover the same topic but doesnt meet my criteria or solve my problem.

So here is my code, I got this from another project a while back Im fairly positive that the problem has to do with // Here's the WPF glue to make it all work. It converts from an // hBitmap to a BitmapSource. Love the WPF interop functions bitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( compatibleBitmapHandle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

Here is the full method code, this is being called like this and

BitmapSource captured = CaptureRegion( hWnd, rect.X, rect.Y, rect.Width, rect.Height, true);

And is also being called many times per second.(70-100ms per call)

      // capture a region of a the screen, defined by the hWnd
        public static BitmapSource CaptureRegion(
            IntPtr hWnd, int x, int y, int width, int height, bool addToClipboard)
        {
            IntPtr sourceDC = IntPtr.Zero;
            IntPtr targetDC = IntPtr.Zero;
            IntPtr compatibleBitmapHandle = IntPtr.Zero;
            BitmapSource bitmap = null;
            //IntPtr hBitmap = bitmap.GetHbitmap();
//            IntPtr hBitmap;

            try
            {
                // gets the main desktop and all open windows
                sourceDC = User32.GetDC(User32.GetDesktopWindow());

                //sourceDC = User32.GetDC(hWnd);
                targetDC = Gdi32.CreateCompatibleDC(sourceDC);

                // create a bitmap compatible with our target DC
                compatibleBitmapHandle = Gdi32.CreateCompatibleBitmap(sourceDC, width, height);

                // gets the bitmap into the target device context
                Gdi32.SelectObject(targetDC, compatibleBitmapHandle);

                // copy from source to destination
                Gdi32.BitBlt(targetDC, 0, 0, width, height, sourceDC, x, y, Gdi32.SRCCOPY);

                // Here's the WPF glue to make it all work. It converts from an 
                // hBitmap to a BitmapSource. Love the WPF interop functions
                bitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    compatibleBitmapHandle, IntPtr.Zero, Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());

            }
            catch (Exception ex)
            {
                throw new ScreenCaptureException(string.Format("Error capturing region {0},{1},{2},{3}", x, y, width, height), ex);
            }
            finally
            {
                Gdi32.DeleteObject(compatibleBitmapHandle);
                // Gdi32.DeleteObject(hBitmap);
                User32.ReleaseDC(IntPtr.Zero, sourceDC);
                User32.ReleaseDC(IntPtr.Zero, targetDC);
            }

            return bitmap;
        }

I really cant understand how I can apply the fix mentioned in the above thread to my problem, because my BitmapSource doesnt seem to be created from a bitmap, I cant see how deleting the bitmap object can help.

Thanks a lot for your help.

Community
  • 1
  • 1
user1143896
  • 97
  • 2
  • 9
  • Is it a GDI handle leak or a memory leak? (You can check with Windows Task Manager whether the number of GDI objects increases). –  Jun 11 '12 at 14:06
  • Well I just checked and it appears that the GDI objects goes up from about 37 to 1400 in a couple of seconds, does this mean its not CreateBitmapSourceFromHBitmap? – user1143896 Jun 11 '12 at 14:20
  • Your code looks OK to me; I cannot see that you are leaking any GDI handles there. Try to find other places in your code where it allocates GDI handles (bitmaps, fonts, brushes, etc.). Or use a tool like [AQTime](http://smartbear.com/products/qa-tools/application-performance-profiling) to find resource leaks. –  Jun 11 '12 at 14:31
  • for GDI leaks I usually use Deleaker... – John Smith Jul 23 '12 at 19:04

0 Answers0