0

I have simple c++ dll that contains code for screen capturing.

HBITMAP hCaptureBitmap;

extern "C" __declspec(dllexport)  HBITMAP  __stdcall CaptureScreenByGDI(bool allScreens)
{
    int nScreenWidth;
    int nScreenHeight;
    HDC hDesktopDC;

    if(allScreens)
    {
        nScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
        nScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    }
    else
    {
        nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
        nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
    }

    HWND hDesktopWnd = GetDesktopWindow();

    if(allScreens)
    {
        hDesktopDC = GetDC(NULL);
    }
    else
    {
        hDesktopDC = GetDC(hDesktopWnd);
    }

    HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
    hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC, 
        nScreenWidth, nScreenHeight);

    SelectObject(hCaptureDC,hCaptureBitmap); 

    BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,
        hDesktopDC,0,0,SRCCOPY|CAPTUREBLT); 

    ReleaseDC(hDesktopWnd,hDesktopDC);
    DeleteDC(hCaptureDC);

    return hCaptureBitmap;
}

extern "C" __declspec(dllexport)  void __stdcall ClearAfterGDI()
{
    DeleteObject(hCaptureBitmap);
}

After calling

CaptureScreenByGDI(true);
ClearAfterGDI();

from c# still remain memory leaks. Why? If I call DeleteObject(hCaptureBitmap) from CaptureScreenByGDI function and return void everthing is OK.

How to solve this?

arthot
  • 48
  • 1
  • 4

1 Answers1

3

You need to save the old bitmap in the DC you create and restore it before deleting the DC:

HGDIOBJ hBmpOld = SelectObject(hCaptureDC,hCaptureBitmap); 
...
SelectObject(hCaptureDC, hBmpOld);
DeleteDC(hCaptureDC);
Jonathan Potter
  • 36,172
  • 4
  • 64
  • 79
  • I really don't know what exactly solve the problem, but after I added your code + DeleteObject(hCaptureBitmap) before recreating bitmap + add bmp.Dispose() in c# everything got fine ) – arthot Jun 19 '13 at 00:11