Программирование на Visual C++. Архив рассылки
Шрифт:
Программирование на Visual C++
Выпуск №48 от 1 июля 2001 г.
Здравствуйте, уважаемые подписчики!
Прежде всего, конечно, хочу попросить прощения на трехнедельный перерыв. Защита выпускной работы – дело серъезное, особенно если на выполнение этой работы осталась всего пара недель ;) Но я успешно защитился, с чем себя и поздравляю. А так же поздравляю вас, дорогие друзья, поскольку сей факт дал вам возможность вновь лицезреть свежие выпуски любимой рассылки на своих мониторах.
Сегодня хочу предложить вашему вниманию одну забавную статью , которая, хотя и написана достаточно давно, во многом не потеряла своей актуальности. А живой язык автора делает чтение по-настоящему
СТАТЬЯ
Я никогда не буду использовать MFC
Автор: Dennis Crain
Перевод: Алекс Jenter
Источник: MSDN
Скачать программу-пример METAVIEW (22k)
Программирование всегда доставляло мне удовольствие. То есть, программирование на C. Кто может сказать, что C не может дать человеку все, что нужно для выполнения работы? Мне казалось, что вся эта рекламная шумиха вокруг C++ и MFC – не более чем старание хитрецов из отдела по маркетингу оправдать свою зарплату. Ведь как бы то ни было, а я и во сне мог писать подпрограммы для Windows. Мне нравились изящные, плавные отступы массивных операторов switch, которые могли позаботиться обо всем, и даже больше, что могло прийти в голову любому Windows-приложению. Я был полон решимости не попасть в водоворот. Черная дыра абстракции меня не получит. Нет уж.
Но я почувствовал, что я как будто был один. Создал в интернете группу для тех, кто интересуется C, – и был единственным, кто в нее записался! Все мои коллеги уже носили костюмчики C++ с завязками из MFC для работы. Когда я программировал, мне часто стали говорить: "В MFC это было бы гораздо проще". Но мне не нужно было "проще"! Мне был нужен полный контроль! А комбинация C++ и MFC уводила еще дальше от уже достаточно абстракного мира Windows на C. Меня стала мучить депрессия. Я начал задаваться вопросом о своей компетентности. (Не правда ли, это зашло достаточно далеко?)
Как раз тогда вмешался мой друг Найджел. Он попросил меня написать программу на основе MFC, использующую архитектуру документ/представление. Очень нехотя, я дал ему положительный ответ. И тут же его уточнил, сказав: "И зачем только я хочу заниматься этим скучным делом?"
Ниже следует отчет о процессе написания программы. А точнее, это обсуждение тех областей, где мне пришлось повозиться с некоторыми исследованиями, чтобы получить нужную для приложения функциональность. Можете считать это свидетельством в пользу способности MFC освободить программистов от той рутинной черновой работы, с которой нам приходилось иметь дело еще со времен Windows версии 1.0. Я немного запоздал? Возможно. Но я уверен, что многие из вас тоже задержались в пути.
Как я заметил выше, Найджел попросил меня написать программу, использующую архитектуру документ/представление в MFC. Конечной целью этого испытания было мое полное вовлечение в мир MFC. Как гласило техническое задание, это Win32 приложение должно было использовать расширенные метафайлы (enhanced metafiles) в качестве документа (более подробную иноформацию о расширенных метафайлах см. в статье "Enhanced Metafiles in Win32" в MSDN), и выводить документ на экран в различных представлениях: либо в виде изображения, либо в виде заголовка метафайла отображаемого как текст. Кроме того, программа должна была позаботиться о печати вместе с предварительным просмотром. Имея все это в виду, я приступил к работе. Как вы увидите, в процессе пришлось воспользоваться некоторыми искусственными приемами. Хотя они и не были неотъемлемой частью приложения, они помогли реализовать нужную функциональность. Можете считать их полезными советами.
Здесь нет ничего сверхсложного. Я просто воспользовался мастером AppWizard Microsoft Visual C++.
Хорошо, и где же в такой системе происходит открытие документа? Я неверно предположил, что это будет происходить в ответ на выбор пользователя команды Открыть из меню Файл. Ну и глупец же я. Это было бы слишком очевидно. В течение некоторого времени я шел этой дорогой, пока не понял, что фактически делаю всю работу сам. Я-то думал, что MFC будет мне помогать! "Неважно", подумал я, "просто спущусь в офис к Найджелу и спрошу его". Как оказалось, мне нужно было обрабатывать открытие файла в функции Serialize, принадлежащей классу документа. Следующий код иллюстрирует мою первую попытку сделать это.
Интересующий нас код находится в блоке else. Этот код просто читает первые sizeof(UINT) байт из файла, чтобы убедиться что они являются сигнатурой расширенного метафайла. Если это так, данные загружаются с помощью GetEnhMetaFile. Так как я пока не сохраняю никаких документов, в ответ на IsStoring нет никакого кода.
А не правда ли, было бы неплохо просто вызвать что-то вроде Load(m_szPathName) чтобы загрузить файл? Ага! Эта будет наш первый хитрый прием! Я решил написать класс, который будет иметь дело непосредственно с метафайлами, загружать их и воспроизводить (об этом подробнее см. дальше). Использование этого класса уменьшило необходимый код загрузки до следующего:
Заметьте, что в обоих фрагментах я использовал переменную m_szPathName как аргумент при вызове функций GetEnhMetaFile и Load. Поначалу я думал, что можно получить полное имя файла из параметра типа CArchive функции Serialize. Ведь CArchive содержит переменную-член m_pDocument, которая указывает на сериализуемый в данный момент объект типа CDocument. Отлично, у CDocument есть очень удобная переменная-член, которая выглядела как раз как то, что мне было нужно: m_strPathName. К сожалению, m_pDocument->strPathName инициализируется нулем при открытии файла. Так что я решил получить имя файла и путь к нему перекрыв фукцию OnOpenDocument. Путь напрямую передавался в OnOpenDocument, так что я просто сделал копию внутри класса CMetavw1Doc в той самой переменной, которая передавалась в качестве параметра функциям GetEnhMetaFile и Load.