Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
WinAPI.docx
Скачиваний:
49
Добавлен:
16.12.2018
Размер:
3.43 Mб
Скачать

4.12.3 Заглянем внутрь

Программа EMF2 строит дисковый метафайл.

Обратите внимание, что первый параметр функции CreateEnhMetaFile — это описатель контекста устройства. GDI использует этот параметр для вставки метрической информации в заголовок метафайла. Если этот параметр установлен в NULL, то GDI берет эту метрическую информацию из контекста устройства дисплея.

Второй параметр функции CreateEnhMetaFile — это имя файла. Если вы установите этот параметр в NULL (как в программе EMF1), то функция построит метафайл в памяти. Программа EMF2 строит дисковый метафайл с именем EMF2.EMF.

Третий параметр функции — адрес структуры типа RECT, описывающей общие размеры метафайла. Эта часть важнейшей информации (та, что отсутствовала в предыдущем формате метафайлов Windows) заносится в заголовок метафайла. Если вы установите этот параметр в NULL, то GDI определит размеры за вас. Приятно, что операционная система делает это для нас, поэтому имеет смысл устанавливать этот параметр в NULL. Если производительность вашего приложения критична, то вы можете использовать этот параметр для того, чтобы избежать лишней работы GDI.

Наконец, последний параметр — текстовая строка, описывающая метафайл. Эта строка делится на две части: Первая часть — имя приложения (не обязательно имя программы), за которым следует NULL-символ. Вторая часть описывает визуальный образ. Эта часть завершается двумя NULL-символами. Например, используя нотацию языка C ‘\0’ для NULL-символа, можно получить строку описания следующего вида "HemiDemiSemiCad V6.4\0Flying Frogs\0\0". Поскольку C обычно помещает NULL-символ в конец строки, заданной в кавычках, вам нужен только один символ ‘\0’ в конце строки, как показано в программе EMF2.

После создания метафайла программа EMF2 работает так же, как программа EMF1, вызывая несколько функций GDI и используя описатель контекста устройства, возвращенный функцией CreateEnhMetaFile. Эти функции рисуют прямоугольник и две линии, соединяющие его противоположные вершины. Затем программа вызывает функцию CloseEnhMetaFile для уничтожения описателя контекста устройства и получения описателя сформированного метафайла.

Затем, еще при обработке сообщения WM_CREATE, программа EMF2 делает то, чего не делала программа EMF1: сразу после получения описателя метафайла программа вызывает функцию DeleteEnhMetaFile. Этот вызов освобождает все ресурсы памяти, необходимые для построения метафайла. Однако дисковый метафайл сохраняется. (Если вы когда-нибудь захотите избавиться от этого файла, то используйте обычные функции удаления файлов.)

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

Теперь, для использования созданного метафайла программе EMF2 необходимо получить доступ к дисковому файлу. Она делает это при обработке сообщения WM_PAINT путем вызова функции GetEnhMetaFile.

Единственный параметр этой функции — имя метафайла. Функция возвращает описатель метафайла. Программа EMF2 передает этот описатель в функцию PlayEnhMetaFile, так же как программа EMF1. Изображение из метафайла выводится в прямоугольник, заданный последним параметром функции. Но в отличие от программы EMF1, программа EMF2 удаляет метафайл перед завершением обработки сообщения WM_PAINT. При обработке последующих сообщений WM_PAINT программа EMF2 опять получает метафайл, проигрывает его и потом удаляет.

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

Поскольку программа EMF2 оставляет не удаленным дисковый метафайл, вы можете взглянуть на него. Он состоит из записей переменной длины, описываемых структурой ENHMETARECORD, определенной в заголовочных файлах Windows. Расширенный метафайл всегда начинается с заголовка типа структуры ENHMETAHEADER.

Вам не нужен доступ к физическому дисковому метафайлу для получения заголовочной информации. Если у вас есть описатель метафайла, то вы можете использовать функцию GetEnhMetaFileHeader:

GetEnhMetaFileHeader(hemf, cbSize, &emh);

Первый параметр — описатель метафайла. Последний — указатель на структуру типа ENHMETAHEADER, а второй — размер этой структуры. Вы можете использовать функцию GetEnhMetaFileDescription для получения строки описания. Поле rclBounds структуры ENHMETAHEADER — структура прямоугольника, хранящая размеры изображения в пикселях. Поле rclFrame структуры ENHMETAHEADER — структура прямоугольника, хранящая размеры изображения в других единицах (0.01 мм).

Заголовочная запись завершается двумя структурами типа SIZE, содержащими два 32-разрядных поля, szlDevice и szlMillimeters. Поле szlDevice хранит размеры устройства вывода в пикселях, а поле szlMillimeters хранит размеры устройства вывода в миллиметрах. Эти данные основываются на контексте устройства, описатель которого передается в функцию CreateEnhMetaFile первым параметром. Если этот параметр равен NULL, то GDI использует экран дисплея. GDI получает метрические данные с помощью функции GetDeviceCaps.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]