case WM_LBUTTONUP: CIientToBmp(UkOkn. "тележка.bmp"):break; Ее реализация очень похожа на только что рассмотренную функцию Wri teDIBC), поэтому для разнообразия вместо стандартных средств языка С по обмену с файлами и управлению памятью будут использованы соответствующие функции Windows, как показано в листинге 17.12.
Листинг 17.12
int ClientToBmp(HWND hWnd.char *Name) {
BITMAPFILEHEADER bmfHdr; BITMAPINFOHEADER bi; RECT r:
int BitToPixel-16;
//Устанавливаем цветовую глубину 16 бит
GetCli entRect(hWnd.&r):
HDC hdc - GetDC(hWnd):
HDC hdcMem - CreateCompatibleDC(hdc);
HBITMAP BitMap - CreateCompatibleBitmap(hdc. r.right.r.bottom); //Узнали размер рабочей области и создали битовую карту BitMap такого //размера. Битовая карта создана на основе контекста устройства hdc. поэтому //она хранит изображение DDB-формата. Именно поэтому нельзя //использовать функцию WriteDIBC)
HBITMAP OldBitmap - (HBITMAP)SelectObject(hdcMem. BitMap);
Запись изображений в файл
BitBltChdcMem, 0. 0. г.right, г.bottom, hdc. 0. 0. SRCCOPY); BitMap - (HBITMAP)SelectObject(hdcMem.OldBitmap); ReleaseDC(hWnd.hdc):
DeleteDC(hdcMem); // Скопировали окно в битовую карту и освободились //от ненужных теперь контекстов
ZeroMemory(&bi.sizeof(BITMAPINF0HEADER)): //Это аналог функции memsetO.
//который заполняет заголовок нулями.
bi.biSize - sizeof(BITMAPINF0HEADER):
bi.biWidth - r.right:
bi.biHeight - r.bottom:
bi.biPlanes - 1;
bi.biBitCount - BitToPixel;
bi.biSizelmage - (r.right * BitToPixel+31)/32*4 * r.bottom;
//Для вычисления размера изображения в байтах мы увеличиваем значение
//г.right * BitToPixel/8 байт на строку до значения, кратного четырем. Это
//вычисление может выполнить и функция GetDIBitsO (см. MSDN).
HANDLE fh - CreateFile(Name. GENERIC_WRITE. 0. NULL. CREATE_ALWAYS.
FIL E_ATTRIBUTE_N0RMAL|FIL E_F LAG_S EQU E NTIAL_SCAN. NULL):
DWORD dwWritten;
//Открыли файл и объявили переменную для занесения количества
//записанных в файл байт.
if (fh « INVALID_HANDLE_VALUE) return 2;
bmfHdr.bfType - (м"«8)|"В"; //Заполняем дисковый заголовок.