When I call the following function in a Windows program, the program abruptly terminates.
The purpose of ScanRect()
is to copy a rectangle at specified coordinates on the screen and load the pixel values into a memory buffer.
Every function call within ScanRect()
succeeds, including both calls to GetDIBits()
. The first call, with lpvBits
set to NULL
, causes it to fill the BITMAPINFOHEADER
of bmInfo
with information about the pixel data, reporting a value of 32 bits per pixel. The second call to GetDIBits()
copies 80 lines of the rectangle into memory buffer pMem
, returning the value 80 for the number of lines copied.
Everything seems to succeed, but then the program suddenly terminates. I inserted the line Sleep(8192)
after the second call to GetDIBits()
, and the program terminates after the 8 seconds have elapsed.
What is causing the program to terminate?
EDIT: the original code is revised per suggestions in this thread. No errors are detected when the function is run, but the program still terminates unexpectedly. I realize the memory buffer size is hard coded, but it is way bigger than needed for the rectangle used in the testing. That should not cause an error. Of course I will have the program compute the necessary buffer size after I find out why the program is terminating.
VOID ScanRect(int x, int y, int iWidth, int iHeight) // 992, 96, 64, 80
{ HDC hDC = GetDC(NULL);
if (!hDC)
{
cout << "!hDC" << endl; // error handling ...
}
else
{ HBITMAP hBitmap = CreateCompatibleBitmap(hDC, iWidth, iHeight);
if (!hBitmap)
{
cout << "!hBitmap" << endl; // error handling ...
}
else
{ HDC hCDC = CreateCompatibleDC(hDC); // compatible with screen DC
if (!hCDC)
{
cout << "!hCDC" << endl; // error handling ...
}
else
{ HBITMAP hOldBitmap = (HBITMAP) SelectObject(hCDC, hBitmap);
BitBlt(hCDC, 0, 0, iWidth, iHeight, hDC, x, y, SRCCOPY);
BITMAPINFO bmInfo = {0};
bmInfo.bmiHeader.biSize = sizeof(bmInfo.bmiHeader);
if (!GetDIBits(hCDC, hBitmap, 0, iHeight, NULL, &bmInfo, DIB_RGB_COLORS))
{
cout << "!GetDIBits" << endl; // error handling ...
}
else
{ HANDLE hHeap = GetProcessHeap();
LPVOID pMem = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 65536); // TODO: calculate a proper size based on bmInfo's pixel information ...
if (!pMem)
{
cout << "!pMem" << endl;
}
else
{ int i = GetDIBits(hCDC, hBitmap, 0, iHeight, pMem, &bmInfo, DIB_RGB_COLORS);
cout << "i returned by GetDIBits() " << i << endl;
HeapFree(hHeap, NULL, pMem);
}
}
SelectObject(hCDC, hOldBitmap);
DeleteDC(hCDC);
}
DeleteObject(hBitmap);
}
ReleaseDC(NULL, hDC);
}
}