Компилятор: 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; CWindowDCdc(pWnd); CDC memDC; CRectrect;
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; }
|