Иллюстрированный самоучитель по Visual Studio .NET

Реакция на уведомляющие сообщения CTreeCTRL

Бит состояния TVIS_EXPANDED не равен нулю, когда узел уже раскрыт. Мы хотим выделить обратный случай, поэтому пользуемся операцией логического отрицания. Метод cwnd::SetRedraw позволяет установить флаг перерисовки. Если он снят, то система не будет перерисовывать содержимое окна. Вставьте изменения В тело функции обработки Onltemexpanded:

void CLeftView::OnItemexpanded (NMHDR* pNMHDR, LRESULT* pResult) {
NMJTREEVIEW* p = (NMJTREEVIEW*)pNMHDR;
//====== Создаем курсор ожидания
CWaitCursor wait;
//====== Признак раскрытия узла (а не его закрытия)
if (p › itemNew.state & TVIS_EXPANDED)
{
// Описатели раскрываемого и 1-го вложенного узла
HTREEITEM hCur = p › itemNew.hltem,
h = m_Tree.GetChildItem(hCur);
//====== Если имя вложенного узла пусто,
//====== то ветвь еще не раскрывалась
if (m_Tree.GetItemText(h) == "")
{
//====== Удаляем муляж
m_Tree.DeleteItem(h);
//====== Вычисляем полный путь
CString s = GetPath(hCur) + "*.*";
//====== Наполнение раскрытой ветви
CFileFind cff; BOOL bFound = cff.FindFile(s);
while (bFound) {
bFound = cff.FindNextFile();
if (cff.IsDirectory() &&!cff.IsDots())
AddItem(hCur, cff.GetFilePath ()); } }
// ====== Разрешаем перерисовку
SetRedraw(TRUE); }
*pResult = 0;
}

Здесь реализованы два варианта развития событий: узел открывается впервые и узел отрывается повторно. Признаком первого варианта является наличие пустого элемента с нулевым индексом изображения и пустой строкой текста внутри раскрываемой ветви. Мы удаляем такой элемент, определяем полный файловый путь раскрываемого узла (папки или диска), сканируем файловый адрес и наполняем дерево новыми элементами.

Алгоритм заполнения содержимого папки сходен с алгоритмом заполнения логического диска. Также воспользуемся пустым узлом для пометки папок, которые имеет смысл раскрывать, так как в них есть вложенные папки или файлы. Функция GetPath должна пройти вверх по иерархической структуре дерева и вычислить полный файловый путь узла, заданного параметром. Введите коды этой функции в файл LeftView.cpp:

CString CLeftView::GetPath (HTREEITEM hCur)
{
//====== Вычисляет полный файловый путь узла hCur
CString s = "";
for (HTREEITEM h=hCur; h; h=m_Tree.GetParentItem(h))
s = m_Tree.GetItemText(h) + '\\' + s;
return s; }

Размеры левого окна были заданы в момент создания стартовой заготовки и они, пожалуй, маловаты. Исправьте начальные размеры окна, которые задаются при вызове CreateView внутри функции CTreeFrame::OnCreateClient. Посмотрите справку по этой функции и задайте горизонтальный размер окна равным 200.

Запустите приложение и протестируйте работу дерева. Теперь его поведение должно соответствовать тем требованиям, которые были сформулированы в начале разработки проекта. В такие моменты полезно провести эксперименты, чтобы лучше уяснить смысл некоторых действий. Например, временно уберите битовый флаг SHGFI_SMALLICON при вызове SHGetFileinf о и посмотрите, как изменится вид узлов дерева. Затем временно исключите вызов функции SetRedraw в обработчике Onitemexpanding и пронаблюдайте поведение дерева при раскрытии папки, содержащей большое количество вложенных объектов, например winNT.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.