Операционная система Microsoft Windows 3.1 для программиста. Дополнительные главы

Фрагмент файла bmpinfo/dib.cpp


// ----------------------------------------------------- // Функции для работы с файлами в формате DIB // ----------------------------------------------------- #define STRICT #include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <mem.h>
#pragma hdrstop #include "dib.hpp"

// ------------------------------- // Функция SizeToHiMetric // Преобразование ширины и высоты для // режима отображения MM_HIMETRIC // ------------------------------- static void SizeToHiMetric(int *width, int *height) { HDC hDC = GetDC(0);

if(hDC) { // Определяем количество пикселов на один // логический дюйм по горизонтали и вертикали int dpiX = GetDeviceCaps(hDC, LOGPIXELSX);
int dpiY = GetDeviceCaps(hDC, LOGPIXELSY);

// Константа для пересчета const long HiMetricPerInch = 2540;

// Выполняем пересчет if(width) *width = int (*width * HiMetricPerInch / dpiX);
if(height) *height = int (*height * HiMetricPerInch / dpiY);

ReleaseDC(0, hDC);
} }

// ------------------------------- // Функция DIBCopyToClipboard // Копирование DIB в Clipboard // ------------------------------- BOOL DIBCopyToClipboard(HDIB hDib, HWND hwnd) { POINT ptSize; HDC hdcMeta, hdc, hdcMem; HMETAFILE hMF; HBITMAP hBitmap; HPALETTE hPal, hOldPal; HGLOBAL hMeta; LPMETAFILEPICT lpMeta; int x, y;

// Если DIB не загружен или он имеет тип, // отличный от WINRGB_DIB, копирование не выполняем if(hDib == NULL) return FALSE; if(DIBType(hDib) != WINRGB_DIB) return FALSE;

// Открываем и очищаем Clipboard if(!OpenClipboard(hwnd)) return FALSE; EmptyClipboard();

// Определяем размеры DIB DIBGetBmpRect(hDib, &ptSize);
x = ptSize.x; y = ptSize.y;

// Создаем DDB // Копируем в него содержимое окна, // размеры копируемой области равны // размерам DIB hdc = GetDC(hwnd);
hdcMem = CreateCompatibleDC(hdc);
hBitmap = CreateCompatibleBitmap(hdc, x, y);
if(hBitmap) { SelectObject(hdcMem, hBitmap);
StretchBlt(hdcMem, 0, 0, x, y, hdc, 0, 0, x, y, SRCCOPY);
} DeleteDC(hdcMem);
ReleaseDC(hwnd, hdc);






// Создаем метафайл в памяти hdcMeta = CreateMetaFile((LPSTR)NULL);

// Устанавливаем начало координат и размеры изображения SetWindowOrgEx(hdcMeta, 0, 0, NULL);
SetWindowExtEx(hdcMeta, ptSize.x, ptSize.y, NULL);

// Создаем палитру из DIB hPal = DIBCreatePalette(hDib);
if(hPal) { // Выбираем и реализуем палитру в контекст // метафайла hOldPal = SelectPalette(hdcMeta, hPal, FALSE);
RealizePalette(hdcMeta);
}

// Рисуем DIB в контексте метафайла DIBPaint(hdcMeta, 0, 0, hDib);

// Выбираем старую палитру if(hPal) SelectPalette(hdcMeta, hOldPal, FALSE);

// Закрываем метафайл hMF = CloseMetaFile(hdcMeta);

// Заказываем память для заголовка метафайла hMeta = GlobalAlloc(GHND, sizeof(METAFILEPICT));
lpMeta = (LPMETAFILEPICT)GlobalLock(hMeta);

// Преобразуем координаты для // режима отображения MM_HIMETRIC SizeToHiMetric(&x, &y);

// Заполняем заголовок метафайла lpMeta->
mm = MM_ANISOTROPIC; lpMeta->
xExt = x; lpMeta->
yExt = y; lpMeta->
hMF = hMF;

// Расфиксируем память заголовка метафайла GlobalUnlock(hMeta);

// Записываем метафайл в Clipboard if(hMeta) SetClipboardData(CF_METAFILEPICT, hMeta);

// Записываем DDB в Clipboard if(hBitmap) SetClipboardData(CF_BITMAP, hBitmap);

// Записываем палитру в Clipboard if(hPal) SetClipboardData(CF_PALETTE, hPal);

// Закрываем Clipboard CloseClipboard();
return TRUE; }

Функция SizeToHiMetric предназначена для преобразования значений ширины и высоты изображения из пикселов в сотые доли миллиметра. Напомним, что при заполнении заголовка метафайла в изотропном и анизотропном режиме отображения размеры изображения указываются в сотых долях миллиметра.

Для выполнения преобразования функция SizeToHiMetric определяет количество пикселов в одном логическом дюйме для контекста отображения, связанного с экраном дисплея. Далее ширина (высота) изображения (в пикселах) умножается на значение 2540 (1 дюйм соответствует 25,4 миллиметра) и делится на количество пикселов в одном логическом дюйме.

Функция DIBCopyToClipboard выполняет копирование данных в Clipboard одновременно в нескольких форматах, используя методики, описанные нами в предыдущих разделах.Для определения размеров DIB вызывается функция DIBGetBmpRect, определенная в файле dib.cpp (в листинге не представлена).


Содержание раздела