В литературе TreeCtrl
называют - древовидный список, по аналогии с деревом. После создания дерева
(TreeCtrl) с ветвями, или узлами(item)
у начинающего программиста непременно воспоследует вопрос :

А как же обработать нажатие на ветвь,
чтобы что -то произошло?

В данной статье я попытаюсь на него ответить.

Итак начнём с самого начала, создадим проект на основе диалога и на него
поместим наше дерево TreeCtrl. Ещё нам потребуется
два Edit Boxa.
В редакторе диалоговых окон установите атрибуты стиля элемента управления
«древовидный список», как показано на рисунке:

treectrl.jpg

В файле TreeCtrlDlg.cpp найдём код
инициализации диалога и строку // TODO: Add extra initialization
here
под которой необходимо размещать наш код. Запрограммируем наш
древовидный список:

// TODO: Add extra initialization
here

CTreeCtrl* pTree = (CTreeCtrl*) GetDlgItem(IDC_TREE);

// здесь можно устанавливать цвет текста и фона
pTree->SetTextColor(RGB(0, 0, 255));
pTree->SetBkColor(RGB(255,255,128));
pTree->Invalidate();

//общие значения древовидной структуры

TV_INSERTSTRUCT tvin;
tvin.hParent = NULL;
tvin.hInsertAfter = TVI_LAST;
tvin.item.mask = TVIF_TEXT | TVIF_PARAM;
tvin.item.hItem = NULL;
tvin.item.state = 0;
tvin.item. stateMask = 0;
tvin.item.cChildren = 0;
tvin.item.lParam = 0;

// верхний уровень
tvin.item.pszText = "Первый";
tvin.item.lParam = 5;
HTREEITEM hFirst = pTree->InsertItem(&tvin);
tvin.item.pszText = "Второй";
tvin.item.lParam = 6;
HTREEITEM hSecond = pTree->InsertItem(&tvin);

// второй уровень
tvin.hParent = hFirst;
tvin.item.pszText = "A";

pTree->InsertItem(&tvin);
tvin.item.lParam = 0;
tvin.item.pszText = "B";
tvin.item.lParam = 1;
pTree->InsertItem(&tvin);

// второй уровень
tvin.hParent = hSecond;
tvin.item.pszText = "A";

tvin.item.lParam = 2;
pTree->InsertItem(&tvin);
tvin.item.pszText = "B";
tvin.item.lParam = 3;
pTree->InsertItem(&tvin);
tvin.item.pszText = "C";
tvin.item.lParam = 4;
HTREEITEM hOther = pTree->InsertItem(&tvin);

Kод устанавливает в TV_INSERTSTRUCT
общие значения, а затем вызывает Insertltem для создания узлов
в древовидной структуре.Компилируем наш проект и запускаем. Отлично, древовидный
список создан и даже при кликах по нему раскрывается и закрывается. Теперь
обучимся делать так, чтобы при одинарном,двойном клике и при выделении ветвей(они
же узлы, они же Item - ы) происходили события.
Для этого создадим обработчики событий NM_CLICK, NM_DLCLCK
для объекта IDC_TREE с помощью ClassWizard
. Также обратите внимание на значение поля lParam,
которое мы задаем при заполнении структуры TV_INSERTSTRUCT,
этими значениями следует пользоваться в обработчиках событий
NM_CLICK, NM_DLCLCK
.Так же необходимо завести две переменные с помощью
Class Wizard
. Открываем вкладку Member Variable
и назначаем переменные,для IDC_EDIT тип String
переменная m_l и для IDC_EDIT_1
тип String переменная m_a,
для IDC_TREE тип CTreeCtrl
имя m_hTree. Запрограммируем одиночное нажатие
клавишей мыши:

void CTreeCtrlDlg::OnClickTree(NMHDR* pNMHDR,
LRESULT* pResult)
{

// TODO: Add your control notification handler code here
CPoint point;
GetCursorPos(&point);
m_hTree.ScreenToClient(&point);
UINT uFlags;
HTREEITEM hItem = m_hTree.HitTest(point, &uFlags);

// && - логическое И, & операция
адресации,которая возвращает адрес операнда

if ((hItem != NULL) && (TVHT_ONITEM & uFlags))

{ m_hTree.Select(hItem, TVGN_CARET);
m_hTree.ClientToScreen(&point);
DWORD ItemData=m_hTree.GetItemData(hItem);

if (ItemData= =0)
m_l="A";

UpdateData(FALSE);

if (ItemData= =1)
m_l="B";

UpdateData(FALSE);

if (ItemData= =2)
m_l="A";

UpdateData(FALSE);

if (ItemData= =3)
m_l="B";

UpdateData(FALSE);

if (ItemData= =4)
m_l="C";

UpdateData(FALSE);

if (ItemData==5)
m_a="Находимся в первом";

UpdateData(FALSE);

if (ItemData==6)
m_a="Находимся во втором";

UpdateData(FALSE);

}
*pResult = 0;

Теперь при одиночном клике на одном из узлов
в EditBox должны отображаться буквы и текст, который
мы запрограммировали. Теперь напишем код для двойного нажатия клавиши мыши:

void CTreeCtrlDlg::OnDblclkTree(NMHDR* pNMHDR,
LRESULT* pResult)
{

// TODO: Add your control notification handler code here
CPoint point;
GetCursorPos(&point);
m_hTree.ScreenToClient(&point);
UINT uFlags;
HTREEITEM hItem = m_hTree.HitTest(point, &uFlags);

if ((hItem != NULL) && (TVHT_ONITEM & uFlags))

{

m_hTree.Select(hItem, TVGN_CARET);
m_hTree.ClientToScreen(&point);
DWORD ItemData=m_hTree.GetItemData(hItem);

if (ItemData==5)
*pResult = 0;
else
if (ItemData==6)
*pResult = 0;
else
AfxMessageBox(" Dblclk Button Click ");

}

*pResult = 0;

}

Теперь при при клике по одной из раскрытых
веток должно появиться сообщение:

afx.jpg

В данных примерах при помощи функции HitTest() мы запрограмировали так, что клик будет обрабатываться только при условии нахождения курсора мыши на элементе дерева.

загрузить исходник

© Goodluck Дмитрий (Cema)

От dmitry

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *