2014-10-03 17 views
0

나는 BitBlt 메도를 사용하여 화면을 캡처하는 함수를 사용하고 HBITMAP을 반환 할 수 있습니다.Windows에서 수백 번 반복 된 후 C++ 화면 캡처가 실패합니다. 메모리 누수가 있습니까?

int screenCapture() { 
    int width = 1000; 
    int height = 700; 

    HDC hdcTemp, hdc; 
    BYTE* bitPointer; 

    hdc = GetDC(HWND_DESKTOP); 
    hdcTemp = CreateCompatibleDC(hdc); 

    BITMAPINFO bitmap; 
    bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader); 
    bitmap.bmiHeader.biWidth = width; 
    bitmap.bmiHeader.biHeight = -height; 
    bitmap.bmiHeader.biPlanes = 1; 
    bitmap.bmiHeader.biBitCount = 24; 
    bitmap.bmiHeader.biCompression = BI_RGB; 
    bitmap.bmiHeader.biSizeImage = 0; 
    bitmap.bmiHeader.biClrUsed = 0; 
    bitmap.bmiHeader.biClrImportant = 0; 
    HBITMAP hBitmap = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL); 
    SelectObject(hdcTemp, hBitmap); 
    BitBlt(hdcTemp, 0, 0, width, height, hdc, 0, 0, SRCCOPY); 
    ReleaseDC(HWND_DESKTOP, hdc); 
    DeleteDC(hdcTemp); 
    return (int)bitPointer[0]; 
} 

여기에서 함수는 픽셀 배열의 첫 번째 값만 반환합니다.
사실, 잘 작동합니다.

for (int i = 0; i >= 0; i++) { 
     cout << i << ": " << screenCapture() << endl; 
    } 

하지만 루프이하려고 할 때 오류가 몇 백 라운드 (나를 위해 900 조금) 후에 생성, Access violation reading location 오류입니다.

widthheight의 값을 줄이면 오류가 더 오래 걸립니다.

나는 진짜 초보자이며 어디에서 오류가 올지 모르지만 메모리 문제처럼 보일 것입니다. 맞습니까?

+4

당신은'DeleteObject 매크로 (HBITMAP)' –

+2

당신이 결국 비트 맵 핸들을 DeleteObject 매크로를 호출해야합니까? 일반적으로 dc에 새 객체를 선택하고 이전 객체를 선택하면 이전 객체를 저장하려고합니다. DC를 삭제할 때 문제가되지는 않지만 또 다른 누출 가능성이 있습니다. –

+0

@AlexK @RetiredNinja'DeleteObject'로 시도했지만 제대로하지 않았습니다. 이제 제대로 작동하고 "액세스 위반 읽기 위치"오류가 발생했습니다. 감사합니다. – Delgan

답변

3

SelectObject()을 호출하기 전에 이미 HBITMAPHDC에 있었던 원래의 HBITMAP이 누출되었습니다. SelectObject()을 사용할 때마다 항상 원래 값을 복원해야합니다 (사용자가 소유하지 않은 값).

오류 검사를 잊지 마세요!

이 시도 :

int screenCapture() 
{ 
    int result = -1; 

    int width = 1000; 
    int height = 700; 

    HDC hdcTemp, hdc; 
    BYTE* bitPointer; 

    hdc = GetDC(HWND_DESKTOP); 
    if (hdc != NULL) 
    { 
     hdcTemp = CreateCompatibleDC(hdc); 
     if (hdcTemp != NULL) 
     { 
      BITMAPINFO bitmap; 
      bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader); 
      bitmap.bmiHeader.biWidth = width; 
      bitmap.bmiHeader.biHeight = -height; 
      bitmap.bmiHeader.biPlanes = 1; 
      bitmap.bmiHeader.biBitCount = 24; 
      bitmap.bmiHeader.biCompression = BI_RGB; 
      bitmap.bmiHeader.biSizeImage = 0; 
      bitmap.bmiHeader.biClrUsed = 0; 
      bitmap.bmiHeader.biClrImportant = 0; 

      HBITMAP hBitmap = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)&bitPointer, NULL, NULL); 
      if (hBitmap != NULL) 
      { 
       HBITMAP hPrevBitmap = SelectObject(hdcTemp, hBitmap); 

       BitBlt(hdcTemp, 0, 0, width, height, hdc, 0, 0, SRCCOPY); 
       result = (int) bitPointer[0]; 

       SelectObject(hdcTemp, hPrevBitmap); 
       DeleteObject(hBitmap); 
      } 

      DeleteDC(hdcTemp); 
     } 

     ReleaseDC(HWND_DESKTOP, hdc); 
    } 

    return result; 
}