Очень странная проблема, с которой я столкнулся сегодня. Выполнение приведенных ниже кодов на 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);
Вот почему комментирование раздела не работает …
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 () для получения битов рабочего стола.
Других решений пока нет …