Вход/Регистрация
Программирование на Visual C++. Архив рассылки
вернуться

Jenter Алекс

Шрифт:

А не правда ли, было бы неплохо просто вызвать что-то вроде Load(m_szPathName) чтобы загрузить файл? Ага! Эта будет наш первый хитрый прием! Я решил написать класс, который будет иметь дело непосредственно с метафайлами, загружать их и воспроизводить (об этом подробнее см. дальше). Использование этого класса уменьшило необходимый код загрузки до следующего:

void CMetavw1Doc::Serialize(CArchive& ar) {

 if (ar.IsStoring) {}

 else {

cemf.Load(m_szPathName);

 }

}

Заметьте, что в обоих фрагментах я использовал переменную m_szPathName как аргумент при вызове функций GetEnhMetaFile и Load. Поначалу я думал, что можно получить полное имя файла из параметра типа CArchive функции Serialize. Ведь CArchive содержит переменную-член m_pDocument, которая указывает на сериализуемый в данный момент объект типа CDocument. Отлично, у CDocument есть очень удобная переменная-член, которая выглядела как раз как то, что мне было нужно: m_strPathName. К сожалению, m_pDocument->strPathName инициализируется нулем при открытии файла. Так что я решил получить имя файла и путь к нему перекрыв фукцию OnOpenDocument. Путь напрямую передавался в OnOpenDocument, так что я просто сделал копию внутри класса CMetavw1Doc в той самой переменной, которая передавалась в качестве параметра функциям GetEnhMetaFile и Load.

BOOL CMetavw1Doc::OnOpenDocument(LPCTSTR lpszPathName) {

 m_szPathName = lpszPathName;

 if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE;

 return TRUE;

}

Итак, что я получил практически ничего не делая? На этот вопрос легко ответить. Все, что перечислено в следующем списке (плюс многое другое, что я еще просто не успел оценить, я уверен) было предоставлено MFC:

• Стандартное диалоговое окно открытия файла

• Список недавно открытых файлов в меню Файл

• Возможность перетаскивать файлы из Проводника в мое приложение (они даже открываются!)

• Невообразимое ощущение легкости.

Прием №1: Класс расширенного метафайла: CEMF

После заполнения моего класса представления (METAVVW.CPP) кодом, необходимым для успешной отрисовки расширенного метафайла, мне стало ясно что я возвращаюсь к своим старым привычкам неорганизованного кодирования на C. Так что я решил убрать весь этот код из класса представления и создать класс, который будет заниматься загрузкой и воспроизведением метафайлов.

Для целей моего маленького приложения, Load и Draw были самыми важными функциями этого класса. Полностью в духе C++, я также написал несколько дополнительных функций для доступа к различным атрибутам метафайла, таким как дескриптор (handle), строка описания, и указатель на заголовок. Следующий код (взятый из CEMF.H) дает хорошее представление о том, что я сделал из этого класса. Заметьте, что я унаследовал класс от CObject, а не от CDC или CMetaFileDC. CDC включает в себя функции PlayMetaFile и AddMetaFileComment, и в ретроспективе, возможно, было бы более удобно унаследовать класс от CDC. Наследование от CMetaFileDC казалось неправильным, потому что я не создавал метафайлы, а просто просматривал уже существующие. Тем не менее, полностью функциональный класс метафайла мог бы быть унаследован и от CMetaFileDC. Да, есть много способов содрать с кота шкуру (прошу прошения у любителей кошек!)

class CEMF : public CObject {

 // Операции

public:

 CEMF;

 ~CEMF;

 BOOL Load(const char *szFileName);

 BOOL Draw(CDC* pDC, RECT* pRect);

 LPENHMETAHEADER GetEMFHeader {

return ((m_pEMFHdr) ? m_pEMFHdr : NULL);

 }

 LPTSTR GetEMFDescString {

return ((m_pDescStr) ? m_pDescStr : NULL);

 }

 HENHMETAFILE GetEMFHandle {

return ((m_hemf) ? m_hemf : NULL);

 }

protected:

 BOOL GetEMFCoolStuff;

 BOOL LoadPalette;

 // Данные

protected:

 CString m_szPathName;

 HENHMETAFILE m_hemf;

 LPENHMETAHEADER m_pEMFHdr;

 LPTSTR m_pDescStr;

 LPPALETTEENTRY m_pPal;

 UINT m_palNumEntries;

 LPLOGPALETTE m_pLogPal;

 LOGPALETTE m_LogPal;

 HPALETTE m_hPal;

};

Функция Load подозрительно смотрит на начало файла, как и мой предыдущий код в функции Serialize. Но теперь нет объекта типа CArchive со всеми его преимуществами. Нет проблем. Использование объекта типа CFile позволяет прочитать сигнатуру. Функции GetEMFCoolStuff и LoadPalette взяты из моей программы-примера EMFDCODE в MSDN. Они получают копии заголовка метафайла, строки описания, и палитры внедренной в метафайл. Конечно, они теперь находятся в классе CEMF.

  • Читать дальше
  • 1
  • ...
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: