Странная ошибка о GetDIBits и контексте устройства

Очень странная проблема, с которой я столкнулся сегодня. Выполнение приведенных ниже кодов на VC6 с проектом MFC и это черный экран, он отлично работает и показывает картинку с рабочего стола, если я уберу комментарий. Однако эти коды выполняются в бесконечном цикле, поэтому я стараюсь уменьшить объем памяти и затраты памяти, как BitBlt а также CreateCompatibleBitmap и т.д. Я не понимаю, как моя программа связана с этими закомментированными кодами. Кто-нибудь знает, в чем причина проблемы и почему?

HDC hdcDesktop = ::CreateDC("DISPLAY", NULL, NULL, NULL);
RECT desktopRect;
::GetWindowRect(::GetDesktopWindow(), &desktopRect);
int desktopWidth = desktopRect.right - desktopRect.left;
int desktopHeight = desktopRect.bottom - desktopRect.top;

HBITMAP hBitmap = CreateCompatibleBitmap(hdcDesktop, desktopWidth, desktopHeight);
/*
HDC hdcMemory = CreateCompatibleDC(hdcDesktop);
SelectObject(hdcMemory, hBitmap);
BitBlt(hdcMemory, 0, 0, desktopWidth, desktopHeight, hdcDesktop, 0, 0, SRCCOPY);
*/

BITMAPINFO bitmapInfo = {0};
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

GetDIBits(hdcDesktop, hBitmap, 0, 0, NULL, &bitmapInfo, DIB_RGB_COLORS);
BYTE *pData = new BYTE[bitmapInfo.bmiHeader.biSizeImage];
memset(pData, 0, bitmapInfo.bmiHeader.biSizeImage);
GetDIBits(hdcDesktop, hBitmap, 0, bitmapInfo.bmiHeader.biHeight, pData, &bitmapInfo, DIB_RGB_COLORS);

CRect destRect;
GetClientRect(&destRect);
StretchDIBits(::GetDC(m_hWnd), 0, 0, destRect.Width(), destRect.Height(), 0, 0, bitmapInfo.bmiHeader.biWidth, bitmapInfo.bmiHeader.biHeight,
pData, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);

0

Решение

Вот почему комментирование раздела не работает …

HBITMAP hBitmap = CreateCompatibleBitmap(hdcDesktop, desktopWidth, desktopHeight);

HDC hdcMemory = CreateCompatibleDC(hdcDesktop);
SelectObject(hdcMemory, hBitmap);

// BitBlt makes a copy of the desktop here.
BitBlt(hdcMemory, 0, 0, desktopWidth, desktopHeight, hdcDesktop, 0, 0, SRCCOPY);

BITMAPINFO bitmapInfo = {0};
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

// the following lines make use of the contents of bitmap in hBitmap
// commenting out the BitBlt would mean the bitmap is uninitialized.
//
GetDIBits(hdcDesktop, hBitmap, 0, 0, NULL, &bitmapInfo, DIB_RGB_COLORS);
BYTE *pData = new BYTE[bitmapInfo.bmiHeader.biSizeImage];
memset(pData, 0, bitmapInfo.bmiHeader.biSizeImage);  // <-- this is unnecessary.

GetDIBits(hdcDesktop, hBitmap, 0, bitmapInfo.bmiHeader.biHeight, pData, &bitmapInfo, DIB_RGB_COLORS);

Вы можете оптимизировать свой код, создав DIBSection, связанный с ним буфер BITMAPINFO и pData в глобальной области видимости для вашего приложения. Его размеры действительны в течение довольно долгого времени … Вам нужно следить за изменениями в разрешении экрана, обрабатывая сообщения WM_DISPLAYCHANGE (https://msdn.microsoft.com/en-us/library/windows/desktop/dd145210(v=vs.85).aspx).

Это спасет вас от повторного вызова CreateCompatibleBitmap ().

Однако я не вижу обходного пути использования BitBlt () и GetDIBits () для получения битов рабочего стола.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]