Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как определить итем в CTreeCtrl, на котором нажали, Как определить итем в CTreeCtrl, на кото 
V
    Опции темы
andrey_s
Дата 11.10.2006, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 11.10.2006

Репутация: нет
Всего: нет



Здравствуйте!
Как определить итем в CTreeCtrl, на котором нажали правую кнопку мыши.

Я думал нужно HTREEITEM hItem=m_Tree.GetSelectedItem(), но это не проходит.
Нужно как-то определить итем, на котором нажали правую кнопку,потом его выделить, а потом использовать GetSelectedItem().
Как?
PM MAIL   Вверх
Earnest
Дата 11.10.2006, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Лови либо WM_RBUTTONDOWN, либо уведомление NM_RCLICK. Вызывай HitTest, чтобы определить, какой итем кликнули, потом делай ему SelectItem.


--------------------
...
PM   Вверх
andrey_s
Дата 11.10.2006, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 11.10.2006

Репутация: нет
Всего: нет



Спасибо за ответ.


Я пробовал так:
определял положение курсора:

Код

CPoint point;
GetCursorPos( &point );

вызывал функцию:

Код

HTREEITEM hItem=m_Tree.HitTest( point,&uFlags);


но почему-то она возвращает NULL. Какие флаги нужно указывать для этой функции? Или что-то я делал не так?

PM MAIL   Вверх
Earnest
Дата 12.10.2006, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Нужно предварительно перевести координаты курсора (экранные) в клиентские:
ScreenToClient()


--------------------
...
PM   Вверх
andrey_s
Дата 12.10.2006, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 11.10.2006

Репутация: нет
Всего: нет



Спасибо, Earnest !
ScreenToClient() помогло!
Я, полазив по форумам, пытался сделать вот так:
Код

void CATreeCtrl::OnRclick(NMHDR* pNMHDR, LRESULT* pResult) 
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
HTREEITEM hItem=pNMTreeView->itemNew.hItem ;
MessageBox (this->GetItemText(hItem));
*pResult = 0;
}

Но MessageBox выводил пустую строку. 
А вот по двойному клику левой кнопки работает нормально:
Код

void CATreeCtrl::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) 
{
    HTREEITEM hItem=this->GetSelectedItem();
    MessageBox (this->GetItemText(hItem));
    *pResult = 0;
}

В чём причина?
PM MAIL   Вверх
Earnest
Дата 13.10.2006, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



1) В моем MSDN написано, что на NM_RCLICK дереву приходит простой NMHDR, а вовсе не NMTREVIEW, так что скорее всего, а hItem у тебя лажа. Врочем, сам отладчиком посмотри. Нужно спрашивать позицию курсора и вызывать HitTest.

2) По правому клику, по-умолчанию, итем не получает фокус, а по левому - получает.


--------------------
...
PM   Вверх
andrey_s
Дата 16.10.2006, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 11.10.2006

Репутация: нет
Всего: нет



Спасибо, Earnest, за ответы!
Вопрос решён. 
PM MAIL   Вверх
CityAC
Дата 4.4.2007, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 3.11.2006
Где: Украина Горловка

Репутация: 1
Всего: 1



Похожая ситуация, только нужно отследить итем, на крестик которого пользователь нажал левой кнопкой.
Выделять при этом итем не нужно, а нужно получить его текст.
Посоветовали TVN_ITEMEXPANDED.//СОБЫТИЕ РАЗВОРОТА УЗЛА
Код

void CprojDlg::OnTvnItemexpandedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
    
    // TODO: Add your control notification handler code here
    *pResult = 0;
}

А как из него можно вытащить нужную инфу.
Или не парится а попробовать выше описанный метод?
--------------------
Вижу цель, не вижу припятствий.  
PM MAIL ICQ   Вверх
CityAC
Дата 4.4.2007, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 3.11.2006
Где: Украина Горловка

Репутация: 1
Всего: 1



Сделал вот так
Код

void CprojDlg::OnTvnItemexpandedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
    CTreeCtrl* pTree = (CTreeCtrl*)GetDlgItem(IDC_TREE1);
    CPoint pt;
    GetCursorPos(&pt);
    ScreenToClient(&pt);
    HTREEITEM item = pTree->HitTest(pt);
    m_TreeCtrl.GetItemText(item);
    HelpFillTree(item);
    

    // TODO: Add your control notification handler code here
    *pResult = 0;
}




Только 
HTREEITEM item = pTree->HitTest(pt);
через раз возвращает не верные итемы.
Например щелкая на "Мои Документы",  возвращает вложенный в мои документы узел "Documents and Settings".
А например с диском G или H  - все корректно

В чем может быть проблема.
И как различить развернут узел или нет.

Еще, я заполняю дерево постепенно: нажал на узел заполнил  его детей первым уровнем иерархии. А как потом избежать повторного заполнения после того как свернул и снова развернул узел?

Это сообщение отредактировал(а) CityAC - 4.4.2007, 14:19
--------------------
Вижу цель, не вижу припятствий.  
PM MAIL ICQ   Вверх
Earnest
Дата 4.4.2007, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



В MSDN все написано:
Цитата

pnmtv
Pointer to an NMTREEVIEW structure. The itemNew member is a TVITEM structure that contains valid information about the parent item in the hItem, state, and lParam members. The action member indicates whether the list expanded or collapsed. For a list of possible values, see the description of the TVM_EXPAND message. 

Т.е. 
Код

LPNMTREEVIEW pnmtv = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
HTREEITEM hItem = pnmtv->itemNew->hItem;

Насчет состояния - смотри pnmtv->action, или можно тупо спросить GetItemState (hItem, TVIS_EXPANDED)

И убедись, что обработчик повешен на TVN_ITEMEXPANDED, а не на TVN_ITEMEXPANDING.


--------------------
...
PM   Вверх
CityAC
Дата 4.4.2007, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 3.11.2006
Где: Украина Горловка

Репутация: 1
Всего: 1



Код

void CprojDlg::OnTvnItemexpandingTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
    
    LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
    
    CPoint pt;
    GetCursorPos(&pt);
    ScreenToClient(&pt);
    HTREEITEM item = m_TreeCtrl.HitTest(pt);    
    


Если определять итем по координатам курсора, то как раз обработчик нужно вешать на TVN_ITEMEXPANDING, 
т.е. нужно получить итем под курсором до того как ветка развернется, иначе, если ветка окажется большая и будет иметь место скроллинг, 
то после развертки ветки под курсором окажется другой итем. Что собственно и происходило у меня когда обрабатывалось TVN_ITEMEXPANDED.

если же так как Вы, уважаемая Earnest, предложили в пред. посте то помоему все равно на какой обработчик. у меня по крайней мере на TVN_ITEMEXPANDING работает. Но я в отличие от Вас могу не знать каких то нюансов.

А можно ли к вставляемому узлу добавить свою информацию.
В частности мне нужно к узлу добавить информацию что я его уже заполнял чтобы при следующем открытии не заполнять его повторно.

Это сообщение отредактировал(а) CityAC - 4.4.2007, 17:08
--------------------
Вижу цель, не вижу припятствий.  
PM MAIL ICQ   Вверх
Earnest
Дата 4.4.2007, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



А просто спросить, есть ли у узла дети - не достаточно (ItemHasChildren)?
Но если нужна своя информация - то есть lParam в каждом итеме, он для того и предназначен.
Цитата(CityAC @  4.4.2007,  18:02 Найти цитируемый пост)
то помоему все равно на какой обработчик

Это зависит от задачи. Если требуется предваряющее действие, да еще и с возможностью отказаться - то OnExpanding, если post-обработка - то OnExpanded (скажем, заменить картинку). Во всяком случае, во время OnExpanded ты можешь точно спросить item, раскрыт ли он, и получишь правильный ответ.
А если ты их заполняешь - то пожалуй, да, нужно на OnExpanding.
Только у меня вызывает сомнение сам факт заполнения при раскрытии. Зачем?



--------------------
...
PM   Вверх
CityAC
Дата 4.4.2007, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 3.11.2006
Где: Украина Горловка

Репутация: 1
Всего: 1



Цитата

Только у меня вызывает сомнение сам факт заполнения при раскрытии. Зачем?


А когда в таком случае заполнять узел детьми?

--------------------
Вижу цель, не вижу припятствий.  
PM MAIL ICQ   Вверх
Earnest
Дата 4.4.2007, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



А сразу никак? При создании. Или при каком-то событии, когда узнаешь, что дерево нужно перестроить.
Если элементов немного (сотня-две) это довольно быстро делается. Только до и после поставь скобки SetRedraw(FALSE\TRUE), чтобы в процессе добавления итемов не моргало.


--------------------
...
PM   Вверх
CityAC
Дата 4.4.2007, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 3.11.2006
Где: Украина Горловка

Репутация: 1
Всего: 1



Я изучаю дерево пытаясь создать проводник. Можешь представить сколько у меня узлов нужно загрузить при создании.
Я отказался от идеи загрузки при создании после того как просидел 1 минуту пока отработали все рекурсии.

У меня корявый код, но он работает.
можно прислать на разбор?
--------------------
Вижу цель, не вижу припятствий.  
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0656 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.