Настройка стартового кода
Кроме методов, рассмотренных выше, мы убрали за ненадобностью метод GetRightPane, который добывает адрес представления, расположенного в правой части (рапе) расщепленного окна. Аналогичной редакции (редукции) подвергся и файл Leftview.h, который, тем не менее, справляется с начальной задачей – показ пустого окна, и в редуцированном виде. Однако этот класс необходимо начать развивать уже сейчас, придавая ему способность управлять деревом файлов. Введите в него объявления новых данных и методов так, чтобы файл LeftView.h приобрел вид:
#pragma once class CTreeDoc; // Упреждающее объявление class CLeftView: public CTreeView { protected: //====== Ссылка на объект элемета управления деревом CTreeCTRLS m_Tree; //====== Список значков узлов дерева CImageList *m_pImgList; CLeftView(); virtual void OnlnitialUpdate(); DECLARE_DYNCREATE(CLeftView) public: virtual ~CLeftView(); CTreeDoc* GetDocument() { return dynamic_cast<CTreeDoc*>(m_pDocument); } //====== Выбор системных значков void GetSysImgList (); //====== Вставка нового узла (ветви) void AddltemfHTREEITEM h, LPCTSTR s); //====== Поиск своих документов void SearchForDocs(CString s); //====== Проверка отсутствия файлов bool NotEmpty(CString s); //====== Вычисляет полный путь текущего узла дерева CString GetPath (HTREEITEM hCur); DECLARE_MESSAGE_MAP() };
Мы не собираемся поддерживать вывод на принтер, поэтому в файле реализации класса CLeftview (LeftView.cpp) уберите из карты сообщений класса все макросы, связанные с печатью. Удалите также заготовки тех функций, прототипы которых удалили в файле интерфейса класса (LeftView.h). Это функции PreCreateWindow, OnPreparePrinting, OnBeginPrinting, OnEndPrinting. AssertValid, Dump, GetDocument. Кроме директив препроцессора в файле должен остаться такой код:
IMPLEMENT_DYNCREATE(CLeftView, CTreeView), BEGIN_MESSAGE_MAP(CLeftView, CTreeView) END_MESSAGE_MAP() CLeftView::CLeftView(){} CLeftView::~CLeftView(){} void CLeftView:: OnlnitialUpdate {} { CTreeView::OnInitialUpdate(); }
Аналогичные упрощения рекомендуем проделать и в классе CRightView. Теперь приступим к анализу и развитию кода класса CLeftView. Внутри каждого объекта класса, производного от CTreeView, содержится объект класса CTreeCTRL, ссылку на который мы объявили в классе CLeftview. Как вы знаете (из курса ООП), единственным способом инициализировать ссылку на объект вложенного класса является ее явная инициализация в заголовке конструктора объемлющего класса. Поэтому измените тело конструктора (в файле LeftView.cpp) так, чтобы он был:
CLeftView::CLeftView() { : m Tree(GetTreeCTRL()) // Пустое тело конструктора }
Метод GetTreeCTRL класса cireeView позволяет добыть нужную ссылку, а вызов конструктора mjrree (GetTreeCTRL ()) инициализирует ее. Теперь мы будем управлять деревом на экране с помощью ссылки m_Tree. Начальные установки для дерева производятся в уже существующей версии виртуальной функции OnlnitialUpdate:
::SetWindowLongPtr (m_Tree.m_hWnd, GWL_STYLE, ::GetWindowLong(m_Tree.m_hWnd, GWL_STYLE) | TVS_HASBUTTONS | TVS_HASLINES | TVS_L1NESATROOT | TVS_SHOWSELALWAYS);
Вставьте эту строку в тело OnlnitialUpdate после строки с вызовом родительской версии. Функция SetWindowLongPtr имеет универсальное употребление. Она позволяет внести существенные изменения в поведение приложения, например, с ее помощью можно изменить адрес оконной процедуры или стиль окна. Второй параметр определяет одну из 9 категорий изменений. Задание индекса GWL_STYLE указывает системе на желание изменить стиль окна.
Симметричная функция GetWindowLong позволяет добыть переменную, биты которой определяют набор действующих стилей. С помощью побитовой операции ИЛИ мы добавляем стили, специфичные для окна типа Tree view. Префикс TVS означает Tree view styles, а префикс GWL – GetWindowLong. Смысл используемых констант очевиден. Если нет, то он легко выясняется с помощью эксперимента. Вы можете вставить, вслед за обсуждаемой строкой кода, такую:
m_Tree.Insertltem("Item", 0, 0);
И запустить приложение. Несмотря на отсутствие тел новых методов, объявленных в интерфейсе класса, вы увидите одну ветвь дерева с именем "Item".
Примечание
С помощью функций SetWindowLong и SetWindowLongPtr можно перемещать окна вверх или вниз внутри иерархии окон, определяемой отношением, которое называется Z-order. Дело в том, что окна на экране упорядочены в соответствии с Z-order. Считается, что ось Z направлена на нас. Z-order служит механизмом, определяющим, видимо ли окно в данный момент или скрыто другими окнами, которые располагаются выше в иерархии Z-order. Вы можете программно изменять этот порядок.