Запись изображения окна в
BMP файл
Компилятор: Visual C++
Чтобы сохранить изображение окна в BMP файл,
необходимо нарисовать картинку на контексте
устройства, преобразовать битмап, связанный с DC в
памяти в устройство-независимый битмап, а затем
записать DIB в файл. Ниже преведена функция
WriteWindowToDIB(), в которой для решения нашей задачи
используются функции DDBToDIB() и WriteDIB().
Давайте разберёмся, как создаётся изображение
окна на контексте устройства в памяти и как
создаётся логическая палитра, которая отвечает
за изображение. Для начала создадим DC в памяти,
совместимый с оконным DC. Далее создадим
совместимый битмап, который имеет такой же
размер как и окно. Затем воспользуемся BitBlt(),
чтобы передать изображение в DC в памяти, получив
тем самым битмап.
Однако, это только половина работы; другая
половина заключается в том, чтобы получить
логическую палитру, которая будет
использоваться с битмапом. Если битмапу
требуется логическая палитра, и она не будет
доступна, то битмап не захочет правильно
отображаться. Воспользуемся функцией GetDeviceCaps(),
чтобы определить, поддерживает ли дисплей
манипуляции с палитрой. Далее выделяем
достаточное количество памяти для структуры
LOGPALETTE, а затем используем GetSystemPaletteEntries() чтобы
заполнить таблицу цветов. Теперь мы можем
спокойно создать логическую палитру.
В заключение используются функции DDBToDIB() и
WriteDIB(). Обратите внимание, что если окно частично
перекрывается другими окнами, то в сохранённом
битмапе будут содержаться части этих окон.
BOOL WriteWindowToDIB( LPTSTR szFile, CWnd *pWnd )
{
CBitmap bitmap;
CWindowDC dc(pWnd);
CDC memDC;
CRect rect;
memDC.CreateCompatibleDC(&dc);
pWnd->GetWindowRect(rect);
bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() );
CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY);
// Если устройство поддерживает палитру, то создаём логическую палитру
CPalette pal;
if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries =
GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );
// Создаём палитру
pal.CreatePalette( pLP );
delete[] pLP;
}
memDC.SelectObject(pOldBitmap);
// Преобразуем битмап в DIB
HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal );
if( hDIB == NULL )
return FALSE;
// Записываем в файл
WriteDIB( szFile, hDIB );
// Освобождаем память выделенную DDBToDIB для DIB
GlobalFree( hDIB );
return TRUE;
}
|