Шаг 177 - Общие выводы о работе с деревом

Итак, у дерева есть несколько элементов. Можно считать, что есть корневые элементы, есть ветвления и есть подчиненные элементы. Общее представление можно получить посмотрев картинку внизу.

177_1.gif (5968 b)

Важное место при работе с деревом занимает указатель HTREEITEM, который указывает на элемент дерева. Именно этот указатель возвращается при многих операциях с деревом, например, получение текущего элемента, получение элемента выше или подчиненных элементов. Имея этот указатель можно получить доступ ко многим операциям над элементами и свойствам элемента. Практически все функции класса CTreeCtrl используют этот указатель в качестве параметров. Но это только указатель.

У дерева есть стили, с помощью которых можно управлять аспектами его отображения. Описание каждого стиля можно посмотреть в подробностях.

TVS_HASLINES
TVS_LINESATROOT
TVS_HASBUTTONS 
TVS_EDITLABELS 
TVS_SHOWSELALWAYS   

Стили устанавливаются при создании окна. Для этого нужно перегрузить функцию Create вида наследника от CTreeView. В последствии стили можно изменить используя функции GetWindowLong и SetWindowLong.

Для добавления пункта необходимо послать сообщение TVM_INSERTITEM, это сообщение вернет указатель HTREEITEM однозначно определяющий пункт дерева. К счастью MFC скрывает от нас подобные подробности. Давайте посмотрим как это делается. Для вставки элемента мы должны послать сообщение и указать в параметрах структуру TVINSERTSTRUCT, которая содержит структуру TVITEM. Сложно ??? Класс CTreeCtrl скрывает эти подробности позволяя вместо посылки сообщений вызывать функции. Например, вот так это выглядит.

GetTreeCtrl().InsertItem(GetTreeCtrl().GetItemText(hi),notselect,select,hit,0);

В данном коде никаких сообщений посылать не надо.

Внимание !!! Работать с элементами управления Windows нужно на основе сообщений. Классы ....CTRL заменяют посылку сообщений вызывами функций классов. Это значительно упрощает программирование. Но вероятно и ведет к усечению ряда возможностей. Еще раз посылка сообщений заменена вызовом функции. Это очень важно для понимания работы многих элементов управления. Вот так реализована подмена сообщения.

_AFXCMN_INLINE BOOL CTreeCtrl::GetItem(TVITEM* pItem) const
	{ ASSERT(::IsWindow(m_hWnd)); return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)pItem); }

С этим понятно. Теперь надо разобраться, как получить информацию от элемента дерева. Если без MFC, то нужно послать сообщение, а с MFC вызвать функцию GetItem, что одно и тоже. Вот она.

BOOL GetItem( TVITEM* pItem );

В эту функцию передается адрес структуры TVITEM, вот её описание.

typedef struct tagTVITEM
{
    UINT      mask;
    HTREEITEM hItem;
    UINT      state; 
    UINT      stateMask;    
    LPTSTR    pszText;
    int       cchTextMax;    
    int       iImage;
    int       iSelectedImage;
    int       cChildren;
    LPARAM    lParam;
} TVITEM, FAR *LPTVITEM;

Что здесь главное, ну во-первых, hItem должен указывать на элемент дерева, который существует. Дальше mask, а вот здесь указывается какие данные мы хотим извлечь.

Обратите внимание на то, что название это LPTSTR. То есть нужен буфер, в который она поместится. Вот пример кода извлекающего имя активного элемента.

void CLeftView::OnTest() 
{
HTREEITEM hi;
hi=GetTreeCtrl().GetSelectedItem();  
if (hi!=NULL)
	{ 
	TV_ITEM   pItem;			// структура
	char szBuffer[20];			// буфер для названия
	memset(&pItem,0,sizeof(pItem)); 	// обнуляем структуру
	pItem.hItem=hi;				// этого элемента информацию мы хотим получить
	pItem.mask= TVIF_TEXT ;			// тип получаемой информации
	pItem.pszText = szBuffer;		// куда вернуть	
	pItem.cchTextMax=19; 			// размер буфера = размер char-1 для завершения строки
	GetTreeCtrl().GetItem(&pItem);		// получить информацию
	AfxMessageBox(pItem.pszText);

	}
else AfxMessageBox("Not Selected Item");
}

Итак, воспользовавшись этим можно получить всю информацию о элементе дерева и перевести указатель HTREEITEM в реальную структуру TV_ITEM.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 2.05.2000