我有一个程序每秒截取一次屏幕截图并计算屏幕的平均颜色。然而,大约 45 分钟的运行后,我的检查
if ((OffscrBmp = CreateCompatibleBitmap(bitmapDC, nScreenWith, nScreenHeight)) == NULL)
开始返回 true
。对 GetLastError()
的调用返回 6
,但我似乎找不到关于这意味着什么的任何文档。
为什么对该函数的数千次调用都能正常工作,然后突然每次调用都失败了?
这是我的全部功能:
COLORREF ScreenColourCapture::getScreenColour() {
// Most of this is adapted from http://www.cplusplus.com/forum/beginner/25138/
LPBITMAPINFO lpbi = NULL;
HBITMAP OffscrBmp = NULL;
HDC OffscrDC = NULL;
int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
HDC bitmapDC = CreateCompatibleDC(0);
HBITMAP hBmp = CreateCompatibleBitmap(GetDC(0), nScreenWidth, nScreenHeight);
SelectObject(bitmapDC, hBmp);
BitBlt(bitmapDC, 0, 0, nScreenWidth, nScreenHeight, GetDC(0), 0, 0, SRCCOPY);
if ((OffscrBmp = CreateCompatibleBitmap(bitmapDC, nScreenWidth, nScreenHeight)) == NULL) {
int error = GetLastError();
logging->error("CreateCompatibleBitmap failed!");
return 0;
}
if ((OffscrDC = CreateCompatibleDC(bitmapDC)) == NULL) {
logging->error("CreateCompatibleDC failed!");
return 0;
}
HBITMAP OldBmp = (HBITMAP)SelectObject(OffscrDC, OffscrBmp);
BitBlt(OffscrDC, 0, 0, nScreenWidth, nScreenHeight, bitmapDC, 0, 0, SRCCOPY);
if ((lpbi = (LPBITMAPINFO)(new char[sizeof(BITMAPINFOHEADER)+256 * sizeof(RGBQUAD)])) == NULL)
return 0;
ZeroMemory(&lpbi->bmiHeader, sizeof(BITMAPINFOHEADER));
lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
SelectObject(OffscrDC, OldBmp);
// First, call GetDIBits with no pixel array. This way it will populate bitmapinfo for us. Then
// call it with the pixel array and the now populated lpbi.
GetDIBits(OffscrDC, OffscrBmp, 0, nScreenHeight, NULL, lpbi, DIB_RGB_COLORS);
LPVOID lpvBits = new char[lpbi->bmiHeader.biSizeImage];
GetDIBits(OffscrDC, OffscrBmp, 0, nScreenHeight, lpvBits, lpbi, DIB_RGB_COLORS);
// Pass BMP data off for computation
COLORREF averageColour = getMeanColourFromPixels((BYTE *)lpvBits, lpbi);
// Wrap things up
delete[] lpvBits;
delete[] lpbi;
DeleteObject(hBmp);
DeleteObject(OldBmp);
DeleteObject(OffscrBmp);
ReleaseDC(GetDesktopWindow(), bitmapDC);
DeleteDC(OffscrDC);
return averageColour;
}
我的其余代码在这里,因为它的值(value):https://github.com/crummy/screenglow/tree/master/ConsoleApplication1
最佳答案
您必须先从 HDC
中取消选择位图,然后才能销毁它,否则您就是在泄漏它。它是这样的:
HBITMAP hBmp = CreateCompatibleBitmap(...);
HBITMAP previousBitmap = (HBITMAP)SelectObject(bitmapDC, hBmp);
// ...
SelectObject(bitmapDC, previousBitmap);
DeleteObject(hBmp);
此外,您调用 GetDC(0)
但不保存返回值,因此您不能 ReleaseDC
它。此外,bitmapDC
是由 CreateCompatibleDC
创建的,应该使用 DeleteObject
而不是 ReleaseDC
来删除。
关于c++ - 重复调用 CreateCompatibleBitmap() 最终因 GetLastError() == 6 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25829796/