Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Visual C++ 6.0 - CTreeCtrl  (Прочитано 19601 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Dimyan
Гость
« : 15-07-2003 07:40 » 

Как сделать, чтобы при нажатии на ту или иную ветку CTreeCtrl открывалась какая либо закладка таба (CTabCtrl).
Подскажите please, а лучше кусочек кода.
Записан
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #1 : 15-07-2003 09:15 » 

А по подробнее можно?
Если брать в общем и целом, то тебе надо в твоем окне перехватывать
NM_CLICK или NM_DBLCLK от твоего CTreeCntrl. И вызывать соответственный CTabCtrl::SetCurSel().
Записан

Megabyte be with you!
Dimyan
Гость
« Ответ #2 : 15-07-2003 10:13 » 

Вопрос в общем то в том, как мне узнать какая ветка CTreeCntrl выбрана в данный момент, и осуществить открытие закладки таба к ней привязанной (принцип осуществлен в программе WinSer).
Записан
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #3 : 15-07-2003 10:23 » 

Цитата

Вопрос в общем то в том, как мне узнать какая ветка CTreeCntrl выбрана в данный момент

CTreeCtrl::GetSelectedItem()
Если вернулось NULL, значит кликнулись в пустое место.

В догонку NM_CLICK и NM_DBLCLK передаются в сообщении WM_NOTIFY от CTreeCtrl к родительскому окну.
Записан

Megabyte be with you!
Dimyan
Гость
« Ответ #4 : 28-07-2003 10:51 » 

И все же можно кусочек кода, а тоя бьюсь над этим целую неделю - ничего не получается  Так больше нельзя... , наверное что то недоганяю Жаль
Записан
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #5 : 28-07-2003 11:09 » 

Ок. Вот пример. Диалог имеет класс CMyDlg.
Tree Control имеет id = IDC_MANUAL_TREE
Перехватываем двойной клик

MyDlg.h
Код:
class CMylDlg : public CDialog
{
// Construction
public:
CMyDlg(CWnd* pParent = NULL);   // standard constructor

// Dialog Data
//{{AFX_DATA(CMyDlg)
enum { IDD = IDD_MY_DIALOG };
CTreeCtrl m_tcTests;
//}}AFX_DATA


// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMyDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CMyDlg)
afx_msg void OnDblclkManualTree(NMHDR* pNMHDR, LRESULT* pResult); // объявляем метод, для обработки соббщения от TreeControl
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

Теперь MyDlg.cpp
Код:
CMyDlg::CManualDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMyDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMyDlg)
//}}AFX_DATA_INIT
}


void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CManualDlg)
DDX_Control(pDX, IDC_MANUAL_TREE, m_tcTests); // нужно для доступа к TreeControl через переменную m_tcTests;
//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
//{{AFX_MSG_MAP(CMyDlg)
ON_NOTIFY(NM_DBLCLK, IDC_MANUAL_TREE, OnDblclkManualTree)   // говорим, что при получении WM_NOTIFY от контрола с id = IDC_MANUAL_TREE и сообщением NM_DBLCLK вызывать функцию OnDblclkManualTtree
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CManualDlg message handlers
void CManualDlg::OnDblclkManualTree(NMHDR* pNMHDR, LRESULT* pResult)
{
//    Делаем, что нам нужно
    *pResult = 0;
}

« Последнее редактирование: 19-11-2007 07:01 от RXL » Записан

Megabyte be with you!
Dimyan
Гость
« Ответ #6 : 28-07-2003 11:31 » 

Спасибо
Но это все понятно я не в этом парюсь!
Я вот так делаю:

void COptimWinDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
   NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
   // TODO: Обрабатывается при выборе элемента
   
      TVITEM curItem;
      HTREEITEM hParentItem;
   
   hParentItem= m_tree.GetSelectedItem();
                curItem.mask= TVIF_HANDLE;
   curItem.hItem= hParentItem;
   m_tree.GetItem(&curItem);


   HTREEITEM hItem = pNMTreeView->itemNew.hItem;
   CString str = m_tree.GetItemText(hItem);

   *pResult = 0;
}

Потом с помощью switch пытаюсь проверить по элементу с каким именем кликнули, но switch начинает орать что значение не char я преобразовывал к char разными способами но нечего не выходит  Так больше нельзя...
Мне бы пример хотябы до того тестового момента когда счелкаеш по одному итему вылазит MessageBox с надписью типа: "Вы кликнули по итему с таким то именем", счелкаеш по другому опять  вылазит MessageBox с именем итема и т.д.
Записан
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #7 : 28-07-2003 11:56 » 

Для себя эту проблему я решил используя CTreeCtrl::SetItemData()
и CTreeCtrl::GetItemData(). С помощью SetItemData() записывается уникальный индентификатор типа DWORD. По GetItemData() он считывается и затем передается в switch(). Либо делать уникальные имена и анализировать строки.
Можно конечно еще использовать поля iImage, iSelectedImage , но это не совсем правильно. т.к. у меня в проектах эти поля используются по назначению, для отображения иконок.
Записан

Megabyte be with you!
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #8 : 28-07-2003 12:52 » 

switch плохо работает c char лучше делать как Lex говорит...

Вот я тут где то имел код такой - надо старые диски с архивами копнуть.
Записан

А птичку нашу прошу не обижать!!!
Dimyan
Гость
« Ответ #9 : 29-07-2003 03:35 » 

Гром, копни пожалуйста доки свои, очень надо, а совет Lex'а я обязательно попробую попоже сейчас другой работы много.
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #10 : 29-07-2003 07:39 » new

Код:
void ATreeView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) 
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
HTREEITEM hItem;
HTREEITEM hParent;
extern int FlagMainTest;


hItem = GetTreeCtrl().GetSelectedItem();
if (hItem == NULL)
{
FlagMainTest = 0;
*pResult = 0;
return;
}
CString ItemText = GetTreeCtrl().GetItemText(hItem);

hParent = GetTreeCtrl().GetParentItem(hItem);
if (hParent == NULL)
{
FlagMainTest = 0;
::PostMessage(this->GetParentFrame()->m_hWnd,WM_SELECTNEWTEST,0,0);
*pResult = 0;
return;
}
CString Parent = GetTreeCtrl().GetItemText(hParent);

if (strcmp(Parent,"Customs")!=0)
{
strcpy(SelChangeParam,ItemText);
FlagMainTest = 1;
::PostMessage(this->GetParentFrame()->m_hWnd,WM_SELECTNEWTEST,0,(LPARAM)SelChangeParam);
}
else
{
strcpy(SelChangeParam,ItemText);
FlagMainTest = 2;
::PostMessage(this->GetParentFrame()->m_hWnd,WM_SELECTNEWTEST,1,(LPARAM)SelChangeParam);
}
*pResult = 0;
}


BEGIN_MESSAGE_MAP(ATreeView, CTreeView)
//{{AFX_MSG_MAP(ATreeView)
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
ON_WM_RBUTTONDOWN()
ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
ON_COMMAND(ID_111_PROPERTIES, On111Properties)
ON_COMMAND(ID_111_RUNTEST, On111Runtest)
ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndlabeledit)
ON_COMMAND(ID_111_DELETE, On111Delete)
ON_COMMAND(ID_111_CLEARALLRESULTS, On111Clearallresults)
ON_WM_CHAR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

Писалось на MFC. Обрабатывается сообщение
Код:
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)

Чтение с контроля показано в функции обработчике.
По адгоритиму - у меня было 2 раздела тестов - внутри которых были списки тестовых процедур - в функции определяется hParent нажатого элемента и если он отсутствует - нажат элемент типа.
Если есть - то определяется имя типа
Код:
CString Parent = GetTreeCtrl().GetItemText(hParent);

Далее для привязки к контролю дерева списка - послыается сообщение

Код:
::PostMessage(this->GetParentFrame()->m_hWnd,WM_SELECTNEWTEST,0,(LPARAM)SelChangeParam)

Причем посылалось оно у меня не в сам CListCtrl а в папино окошко Main Frame.

Там соответственно обрабатывалось.
Причиной такого действия является достаточно высокая сложность программы и введения для всех операций управдления - которое осуществлял класс окна фреймов...
На экране иногда были: Дерево +  Спсиок, Дерево + процессинг тестов, просто управление пинами процессора и т.д. Это тебе не важно, но просто - дабы стало понятно, что это не обязательно.

Данные выводимые в контролях я хранил в ini вайлах.
Отдельно для списка и дерева.

Основной проблемой является то, что ты не можешь просто в качестве параметра передать ItemText так как он локален и его адресс по выходу из функции обработки клика исчезнет.

Надо иметь передаваемую строку, глобального свойства.

Код:
strcpy(SelChangeParam,ItemText);
« Последнее редактирование: 19-11-2007 07:01 от RXL » Записан

А птичку нашу прошу не обижать!!!
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines