Развитие класса документа
Теперь, когда мы имеем вспомогательные классы (CDPoint и CPolygon), можно подумать о структуре данных класса CTreeDoc. Нам понадобятся:
- массив (контейнер) полигонов, которые соответствуют файлам документов, обнаруженных в текущем каталоге;
- массив строк текста с файловыми путями этих документов;
- один "дежурный" полигон, который в данный момент редактируется, то есть выбран для демонстрации в окне третьего представления (CDrawView);
- размеры документа в логической системе координат (Page space);
- коэффициент увеличения размеров при переходе из World в Page-пространство.
Кроме этого, нам понадобятся методы для управления тремя окнами: CLeftview, CRightView и CDrawView. Последний класс будет управлять окном, в котором полигон может быть отредактирован. Этот класс надо еще создать.
Замените существующий интерфейс класса CTreeDoc на тот, который приведен ниже. Здесь мы также провели упрощение начальной заготовки по схеме, обсуждавшейся выше:
class CTreeDoc: public CDocument { //==== Все 3 представления имеют право доступа //==== к данным документа friend class CLeftView; friend class CRightView; friend class CDrawView; protected: virtual ~ CTreeDoc (); CTreeDoc (); DECLARE_DYNCREATE(CTreeDoc) public: // ========== Данные документа ============ // CPolygon m_Poly; // Дежурный полигон VECPOLY m_Shapes; // Контейнер полигонов // ====== Контейнер имен файлов vector<CString> m_sFiles; //====== Размер документа в Page space CSize m_szDoc; //== Коэффициент увеличения при переходе World › Page OINT m_nLogZoom; //====== Флаг: открыто окно типа CTreeFrame bool m_bTreeExist; //=====Флаг: открыто окно типа CDrawFrame bool m_bDrawExist; //======Новые методы класса документ =====// //====== Поиск нужного представления CView* GetViewfconst CRuntimeClass* pClass); //====== Создание нужного представления bool MakeViewO; //====== Преобразование координат World › Page CPoint MapToLogPt(CDPointS pt); //====== Преобразование координат Page › World CDPoint MapToWorldPt(CPolntS pt); //===== Перерисовка окна редактирования void UpdateDrawView(); // Чтение найденных документов и их демонстрация void ProcessDocs(); //====== Освобождение контейнеров void FreeDocs(); //====== Поиск выбранной точки int FindPoint(CDPointS pt); // Overrides public: virtual BOOL OnNewDocument(); virtual void Serialize(CArchiveS ar); // Generated message map functions protected: DECLARE_MESSAGE_MAP() );
Некоторым из данных документа можно присвоить значения по умолчанию. Обычно это делается в конструкторе класса. Зададимся неким произвольным размером (2000 х 2000) документа в логической (Page) системе координат. Чем больше эта область, тем точнее будут отражены детали конструкции, так как вещественные (World) координаты претерпят округление при приведении к целым (Page) координатам. Вспоминая, что две из наших тестовых фигур имеют габариты в 2 единицы в пространстве World, определяем коэффициент увеличения m_nLogZoom = 700. В этом случае габариты фигур в пространстве Page будут равны 1400 единиц, то есть они целиком поместятся в области документа.
Выбрав произвольные начальные цвета фигуры и учтя соображения относительно установки обратного указателя, получим следующую версию конструктора класса CTreeDoc:
CTreeDoc::CTreeDoc(): m_szDoc(2000.2000), m_Poly() { //====== Установка обратного указателя и //====== атрибутов дежурного полигона m_Poly.Set(<strong>this</strong>, RGB(240.255.250), RGB(0.96.0), 2); m_nLogZoom = 700; }