Код функции, которая сохраняет картинку н£ диске, получая в качестве параметров путь к файлу szFi le и дескриптор битовой карты hBitmap, приведен в листинге 17.11.
Листинг 17.11
BOOL WriteDIBC char *szFile. HBITMAP hBitmap) {
BITMAPFILEHEADER hdr; DIBSECTION db;
if(!(file-fopen(szFile."wb"))) return FALSE; GetObject(hBitmap.sizeof(DIBSECTION),&db); BITMAPINFOHEADER bi - db.dsBmih: BITMAP bm-db.dsBm;
hdr.bfType- ((WORD) CM' « 8) | 'В'); // В первых двух байтах bmp-файла //всегда хранятся коды символов "ВМ".
продолжение &
Работа с растровыми изображениями
Листинг 17.11 (продолжение)
//Следующее поле содержит длину файла. hdr.bfSize - bm.bmWidthBytes*bm.bmHeight+
sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); //Длина сформирована как сумма размеров заголовков и длины массива с кодами //цвета. (Чтобы не учитывать дополнительные байты каждой строки //и разрядность кода цвета, количество строк bm.bmHeight умножается на ширину //строки в байтах bm.bmWidthBytes.) hdr.bfReservedi - hdr.bfReserved2 - 0;
hdr.bfOffBits - sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
//Для непалитровых режимов, которые мы рассматриваем, смещение от начала
//файла до цвета первого пиксела равно сумме двух заголовков.
fwr1te(&hdr.l.sizeof( BITMAPFILEHEADER ).f1le):
//Записали файловый заголовок.
fwriteC&M.l. sizeof ( BITMAPINFOHEADER ) .file):
//Записали загружаемый заголовок.
fwr1 te(bm.bmBits.1.bm.brriWidthBytes*bm.bmHeight.fi1e):// Записали данные
//Порядок строк в файле совпадает с порядком строк в ОЗУ. поэтому никакой
//дополнительной обработки не требуется.
fclose(file);
return TRUE:
}
В тех случаях, когда требуется записать на диск данные из DDB-формата, можно выйти из положения, скопировав их в DIB-карту подходящего размера. Но, кроме того, API Windows предлагает функцию GetDIBitsO для преобразования данных из DDB- в DIB-формат и SetDIBi ts() для обратного преобразования.
Теперь следует вернуться к проекту Con Mem и решить задачу сохранения в файле изображения рабочей области окна с движущейся тележкой. Для этого в оконную процедуру, обрабатывающую щелчок правой кнопкой мыши, нужно добавить еще один вызов функции: