Прототип к варианту 16 - МикроГраф, страница 4

Вместо блоков памяти в Win32 также можно было воспользоваться байтовыми массивами, поскольку функции метафайлов Win32 в качестве параметров получают указатели на блоки памяти. Однако поскольку в процессе преобразования код WinlG, работающий с метафайлами, реально работает с глобальными манипуляторами, я решил воспользоваться глобальными блоками памяти на обеих платформах. Для функции SetMetaFileBitsEx (получающей байтовый массив) был создан псевдоним с именем SetMetaFileBitsBuffer (получающий переменную типа Long с адресом).

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

Листинг 8.7. QUIKDRAW.BAS

Функция SaveTheMetafile выполняет операции LoadTheMetafile в обратном порядке. Сначала она создает файл, затем заполняет структуру METAFILEHEADER. Структура инициализируется значениями ключа, габаритов и произвольным количеством единиц метафайла на дюйм (в документации Windows рекомендуется использовать число, меньшее 1440). В структуру включается контрольная сумма, при помощи которой программа, загружающая метафайл, может убедиться в его целостности (или, по крайней мере, в целостности заголовка). Контрольная сумма вычисляется выполнением операции XOR («исключающее ИЛИ») к первым 10 целым в структуре. Обратите внимание на то, что в приведенном фрагменте в вычисления не включаются поля Left и Тор ограничивающего прямоугольника. Дело в том, что эти значения всегда равны 0, а объединение любого числа с 0 операцией «исключающего ИЛИ» всегда дает исходное число.

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

На этом 16- и 23-разрядная версии кода программы расходятся. В Win 16 существует функция GetMetaFileBits, выделяющая метафайлу глобальный манипулятор. Этот манипулятор фиксируется (locked) для получения адреса памяти, а буфер записывается непосредственно в дисковый файл. В Win32 необходимо сначала определить размер буфера функцией GetMetaFileBitsEx, а затем выделить буфер и заполнить его повторным вызовом функции. После этого буфер можно записать на диск.

Рекомендации для самостоятельной работы

Приложение QuikDraw, как и все остальные примеры в этой книге, было написано для того, чтобы продемонстрировать использование функции API. По этой причине оно далеко не идеально. Для тренировки попробуйте реализовать в нем следующие возможности:

-поддержка дополнительных графических функций GDI;

-возможность предварительного просмотра текущего объекта в метафайле перед его включением в метафайл;

-поддержка различных режимов ROP2 и заполнения фона; О улучшенный пользовательский интерфейс;

-возможность удаления объектов из метафайла (подсказка: сначала просмотрите следующий пример Analyze);

-возможность загрузки метафайла и превращения его в текущий глобальный метафайл.