Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming_Windows_95_Part_I.pdf
Скачиваний:
96
Добавлен:
05.06.2014
Размер:
4.61 Mб
Скачать

143

Это монохромный битовый образ с высотой и шириной в 8 пикселей.

Как будет показано в главе 9, вы можете создать битовый образ в виде небольшого файла в программе Microsoft Developer Studio и определить его в вашей программе как ресурс. Загружая его, вы получаете описатель битового образа:

hBitmap = LoadBitmap(hInstance, "Brick");

hBrush = CreatePatternBrush(hBitmap);

Когда у вас будет действительный контекст устройства, выберите кисть в контекст устройства и отобразите прямоугольник:

SelectObject(hdc, hBrush);

Rectangle(hdc, xLeft, yTop, xRight, yBottom);

Когда вы освободите контекст устройства, удалите кисть и битовый образ:

DeleteObject(hBrush);

DeleteObject(hBitmap);

Для удаления битового образа не нужно ждать, пока освободится контекст устройства. Вы можете сделать это в любой момент после создания кисти на основе битового образа.

Можно также описать пиксели битового образа в вашей программе как массив восьми беззнаковых целых. Каждое целое соответствует скан-линии в шаблоне битового образа. Бит, равный 1, используется для задания белого цвета, бит, равный 0 — для черного:

HBITMAP hBitmap;

HBRUSH hBrush;

static WORD wBrickBits [] =

{ 0xFF, 0x0C, 0x0C, 0x0C, 0xFF, 0xC0, 0xC0, 0xC0 };

Битовый образ создается функцией CreateBitmap с параметром — ссылкой на массив целых:

hBitmap = CreateBitmap(8, 8, 1, 1,(LPVOID) &wBrickBits); hBrush = CreatePatternBrush(hBitmap);

И далее продолжать, как указано выше.

Метафайлы

Метафайлы имеют такое же значение для векторной графики, как и битовые образы для растровой графики. Метафайлы конструируются человеком или компьютерной программой. Метафайл состоит из набора записей, соответствующих вызовам графических функций, например, рисующих прямые линии, кривые, закрашенные области и текст. Таким образом, метафайл — набор вызовов графических функций, закодированный в двоичной форме.

Программы рисования создают битовые образы, программы черчения — метафайлы. В программах черчения вы можете "захватить" конкретный графический объект (такой как линия) и переместить его в другое место. Это возможно потому, что все компоненты чертежа хранятся как отдельные записи. В программах рисования такие действия невозможны — вы можете только удалять и вставлять прямоугольные фрагменты битового образа.

Поскольку метафайл описывает изображение в терминах команд графического вывода, изображение может быть промасштабировано без потери разрешения. С битовыми образами это невозможно. Если вы отображаете битовый образ в увеличенном в два раза виде, то вы не получите двойного разрешения. Биты внутри битового образа будут просто повторяться горизонтально и вертикально.

144

Метафайл может быть преобразован в битовый образ без потери информации. Графические объекты, составляющие метафайл, теряют свою индивидуальность и соединяются вместе в одном большом образе. Преобразование битового образа в метафайл — гораздо более сложная задача, решаемая обычно только для простых битовых образов, и требующая высокой мощности процессора для выявления углов и контуров.

Метафайлы чаще всего используются для разделения изображений между программами посредством буфера обмена, хотя они могут также быть сохранены на диске в виде файлов. Поскольку метафайлы описывают изображение как набор вызовов GDI, для их хранения требуется значительно меньше места, и они более независимы от устройства, чем битовые образы.

Сначала мы рассмотрим функции работы с метафайлами, которые поддерживаются Windows, начиная с версии 1.0 и кончая Windows 95, а затем остановимся на "расширенных метафайлах", разработанных для Windows NT, но также поддерживаемых Windows 95. Расширенные метафайлы имеют серьезные преимущества в сравнении с метафайлами старого формата и значительно лучше приспособлены для дискового хранения.

Простое использование метафайлов памяти

Для создания метафайла сначала надо построить контекст устройства метафайла путем вызова функции CreateMetaFile. Затем вы можете использовать большинство функций рисования GDI в этом контексте метафайла. Эти вызовы функций GDI ничего не будут выводить на экран. Вместо этого они будут запоминаться в метафайле. Когда вы закроете контекст устройства метафайла, вы получите описатель метафайла. Затем, вы можете "проиграть" этот метафайл на реальном контексте устройства и выполнить функции GDI метафайла.

Функция CreateMetaFile имеет один параметр. Он может быть равен NULL или быть именем файла. Если NULL, то метафайл запоминается в оперативной памяти. Если указано имя файла (обычно с расширением .WMF — "Windows Metafile"), то метафайл запоминается как дисковый файл.

Программа METAFILE, приведенная на рис. 4.28, показывает, как создать метафайл в памяти во время обработки сообщения WM_CREATE и 100 раз вывести изображение во время обработки сообщения WM_PAINT.

METAFILE.MAK

#------------------------

# METAFILE.MAK make file

#------------------------

metafile.exe : metafile.obj

$(LINKER) $(GUIFLAGS) -OUT:metafile.exe metafile.obj $(GUILIBS)

metafile.obj : metafile.c

$(CC) $(CFLAGS) metafile.c

METAFILE.C

/*----------------------------------------------

METAFILE.C -- Metafile Demonstration Program

(c) Charles Petzold, 1996

----------------------------------------------*/

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)

{

static char szAppName [] = "Metafile";

HWND

hwnd;

MSG

msg;

WNDCLASSEX

wndclass;

wndclass.cbSize

= sizeof(wndclass);

wndclass.style

= CS_HREDRAW | CS_VREDRAW;

wndclass.lpfnWndProc

= WndProc;

wndclass.cbClsExtra

= 0;

wndclass.cbWndExtra

= 0;

wndclass.hInstance

= hInstance;

145

wndclass.hIcon

= LoadIcon(NULL, IDI_APPLICATION);

wndclass.hCursor

= LoadCursor(NULL, IDC_ARROW);

wndclass.hbrBackground

=(HBRUSH) GetStockObject(WHITE_BRUSH);

wndclass.lpszMenuName

= NULL;

wndclass.lpszClassName

= szAppName;

wndclass.hIconSm

= LoadIcon(NULL, IDI_APPLICATION);

RegisterClassEx(&wndclass);

hwnd = CreateWindow(szAppName, "Metafile Demonstration", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

ShowWindow(hwnd, iCmdShow);

UpdateWindow(hwnd);

while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

static HMETAFILE hmf;

static int

cxClient, cyClient;

HBRUSH

hBrush;

HDC

hdc, hdcMeta;

int

x, y;

PAINTSTRUCT

ps;

switch(iMsg)

{

case WM_CREATE:

hdcMeta = CreateMetaFile(NULL);

hBrush = CreateSolidBrush(RGB(0, 0, 255));

Rectangle(hdcMeta, 0, 0, 100, 100);

MoveToEx(hdcMeta, 0, 0, NULL);

LineTo (hdcMeta, 100, 100);

MoveToEx(hdcMeta, 0, 100, NULL);

LineTo (hdcMeta, 100, 0);

SelectObject(hdcMeta, hBrush);

Ellipse(hdcMeta, 20, 20, 80, 80);

hmf = CloseMetaFile(hdcMeta);

DeleteObject(hBrush); return 0;

case WM_SIZE:

cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); return 0;

case WM_PAINT:

hdc = BeginPaint(hwnd, &ps);

146

SetMapMode(hdc, MM_ANISOTROPIC);

SetWindowExtEx(hdc, 1000, 1000, NULL);

SetViewportExtEx(hdc, cxClient, cyClient, NULL);

for(x = 0; x < 10; x++) for(y = 0; y < 10; y++)

{

SetWindowOrgEx(hdc, -100 * x, -100 * y, NULL);

PlayMetaFile(hdc, hmf);

}

EndPaint(hwnd, &ps); return 0;

case WM_DESTROY: DeleteMetaFile(hmf); PostQuitMessage(0); return 0;

}

return DefWindowProc(hwnd, iMsg, wParam, lParam);

}

Рис. 4.28 Программа METAFILE

Эта программа демонстрирует использование четырех функций метафайлов, работающих с метафайлом памяти. Первая функция — CreateMetaFile, вызванная с параметром NULL в теле обработчика сообщения WM_CREATE. Эта функция возвращает описатель контекста устройства метафайла. Затем программа METAFILE рисует прямоугольник, две прямые и один голубой эллипс, используя данный контекст устройства метафайла. Вызовы этих 4-х функций запоминаются в двоичной форме в метафайле. Функция CloseMetaFile возвращает описатель метафайла. Обратите внимание, что описатель метафайла запоминается в статической переменной, поскольку он используется позднее.

Метафайл содержит двоичное представление вызовов функций GDI — одного вызова Rectangle, двух вызовов MoveToEx, двух вызовов LineTo, вызова SelectObject (задающего голубую кисть) и вызова Ellipse. Режим отображения или преобразования не описывается координатами. Они просто запоминаются в метафайле в числовом виде.

Рис. 4.29 Вывод программы METAFILE

Во время обработки сообщения WM_PAINT программа METAFILE устанавливает режим отображения и вызывает функцию PlayMetaFile для рисования объекта в окне 100 раз. Координаты вызовов функций в метафайле интерпретируются в соответствии с режимом отображения приемного контекста устройства. Вызывая PlayMetaFile, вы повторяете все вызовы функций, сделанные между вызовами функций CreateMetaFile и CloseMetaFile при первоначальном создании метафайла во время обработки сообщения WM_CREATE.

Как и другие объекты GDI, метафайлы должны быть тоже удалены до завершения программы. Процедура удаления реализуется в теле обработчика сообщения WM_DESTROY с помощью функции DeleteMetaFile.

Результат работы программы METAFILE приведен на рис. 4.29.

Соседние файлы в предмете Операционные системы