Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > [WinApi] Связка TreeVew с ListView через lParam


Автор: CynicRus 22.3.2013, 11:01
Приветствую уважаемых форумчан. Потребовалось мне к маленькой консольной тулзе прикрутить маленький GUI. Выбор пал на чистый WinApi, благо я давно собирался это освоить. Так вот, собственно на форме имеются ListView, TreeView и кнопка. По нажатию кнопки заполняется структура. Мне необходимо засунуть в lParam TVITEM индекс, под которым этот элемент был добавлен в дерево. 

Код записи:
Код

  TV_INSERTSTRUCT tvinsert;
                int TreeCount=TreeView_GetCount(GetDlgItem(hwnd,NAMETREE));

                if (TreeCount!=0)
                  {
                      for(int i=0;i<=TreeCount;i++)
                        TreeView_DeleteAllItems(GetDlgItem(hwnd,NAMETREE));
                  }
//
for (int i = 0; i < MyStructItemCount; i++) {
                  current = mystruct[i].item ;
                  if (i==0){
                            tvinsert.hParent=NULL; 

                            tvinsert.hInsertAfter=TVI_ROOT;

                            tvinsert.item.mask=TVIF_TEXT|TVIF_PARAM;
                            tvinsert.item.lParam=i;

                            tvinsert.item.pszText=current->cFriendlyName;
                            tvinsert.item.iImage=0; 
                            tvinsert.item.iSelectedImage=1; 
                            Parent=(HTREEITEM)SendDlgItemMessage(hwnd,NAMETREE,
                            TVM_INSERTITEM,0,(LPARAM)&tvinsert);
                            Root=Parent;
                           Before=Parent;

                            }else {
                                tvinsert.hParent=Root;        
                                  tvinsert.hInsertAfter=TVI_LAST;   
                                  tvinsert.item.pszText=current->cFriendlyName;
                                  tvinsert.item.mask=TVIF_TEXT|TVIF_PARAM;
                                  tvinsert.item.lParam=i;
                                  Parent=(HTREEITEM)SendDlgItemMessage(hwnd,NAMETREE,
                                    TVM_INSERTITEM,0,(LPARAM)&tvinsert);
                            }



в lParam тут пишется I, вроде всё замечательно.

Затем мне необходимо по даблклике на элементе TreeView добавить из структуры в listview. Соответственно, мне надо забрать из lParam индекс. Вот тут и начинаются проблемы. Пытаюсь забрать данные следующим образом:

Код

                TVITEM tvit;
                HTREEITEM hTreeItem = TreeView_GetSelection(hTree);
                tvit.hItem = hTreeItem;
                tvit.mask = TVIF_TEXT|TVIF_PARAM;
                TreeView_GetItem(hTree, &tvit);
                

               int i =tvit.lParam;
               struct mystruct * current = mystruct[i].item;


Так вот в i после этого оказывается всё что угодно, кроме того что я туда записывал. Вот собственно и вопрос - как правильно связать TreeView с ListView?

Автор: CynicRus 22.3.2013, 11:27
Ну а если я в lParam структуру пакую, то на выходе получаю всё равно балалайку:

Код

tvinsert.item.lParam=reinterpret_cast<int>(current);

Автор: artsb 24.3.2013, 19:10
А вы пишете под Windows CE? Почему я спрашиваю? Потому что http://msdn.microsoft.com/en-us/library/ms914063.aspx относится к Windows CE. Если вы пишете просто под Windows, то вам нужна http://msdn.microsoft.com/ru-RU/library/windows/desktop/bb773452%28v=vs.85%29.aspx. Скорее всего, из-за такого не соответствия и возникают "приколы".

Автор: CynicRus 25.3.2013, 08:19
Во как...Спасибо, не знал.

Автор: CynicRus 25.3.2013, 10:07
Тем не менее - не помогло.

Я уже попробовал структуру, содержащую int для передачи индекса:

Код

struct CurrIndex
{
 int index;
};


Пакую в lParam:

Код

{
                 struct CurrIndex *idx = new CurrIndex;
                  idx->index = i;
                  tvinsert.item.lParam=reinterpret_cast<LPARAM>(idx);
}


Пытаюсь достать:

Код

               CurrIndex* idx = new CurrIndex;
               idx = reinterpret_cast<CurrIndex*>(tvit.lParam);
               int i =idx->index;
               delete(idx);


И в idx всегда одно и тоже значение 0x215.

Автор: artsb 25.3.2013, 11:25
Код

int iIndex;
HWND hwndTV;
TVINSERTSTRUCT ins;
TVITEM item;

hwndTV = CreateWindowEx(0,
        WC_TREEVIEW,
        L"Tree View",
        WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES,
        0,
        0,
        100,
        100,
        this->Handle,
        0,
        hInstance,
        NULL);

if(!hwndTV)
{
    return;
}

memset(&ins, 0, sizeof(ins));

ins.hParent = NULL;
ins.hInsertAfter = TVI_ROOT;
ins.item.mask = TVIF_TEXT | TVIF_PARAM;
ins.item.lParam = 55;
ins.item.pszText = L"Item 1";

TreeView_InsertItem(hwndTV, &ins);

memset(&item, 0, sizeof(item));

item.hItem = TreeView_GetFirstVisible(hwndTV);
item.mask = TVIF_TEXT | TVIF_PARAM;

TreeView_GetItem(hwndTV, &item);

iIndex = (int)item.lParam;

DestroyWindow(hwndTV);

iIndex  = 55. Что я не так сделал?

Автор: CynicRus 25.3.2013, 11:42
Цитата(artsb @ 25.3.2013,  11:25)
Код

int iIndex;
HWND hwndTV;
TVINSERTSTRUCT ins;
TVITEM item;

hwndTV = CreateWindowEx(0,
        WC_TREEVIEW,
        L"Tree View",
        WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES,
        0,
        0,
        100,
        100,
        this->Handle,
        0,
        hInstance,
        NULL);

if(!hwndTV)
{
    return;
}

memset(&ins, 0, sizeof(ins));

ins.hParent = NULL;
ins.hInsertAfter = TVI_ROOT;
ins.item.mask = TVIF_TEXT | TVIF_PARAM;
ins.item.lParam = 55;
ins.item.pszText = L"Item 1";

TreeView_InsertItem(hwndTV, &ins);

memset(&item, 0, sizeof(item));

item.hItem = TreeView_GetFirstVisible(hwndTV);
item.mask = TVIF_TEXT | TVIF_PARAM;

TreeView_GetItem(hwndTV, &item);

iIndex = (int)item.lParam;

DestroyWindow(hwndTV);

iIndex  = 55. Что я не так сделал?

Вы получаете и отдаёте индекс в рамках одной функции. Попробуйте в одной функции число записать а из другой его прочитать. Мне ведь необходимо в этот парам записывать индекс внутреннего дерева, чтобы затем по клике на TreeView выдать в ListView нужную ветвь.


Хахахахахахаха, странно - но заработало. после 3 дней мозгового штурма! Хахахаха! Спасибо!

Автор: HANDLE 9.4.2013, 14:15
Не мешало бы проверить что возвращает TreeView_GetItem(), может ошибка.
И в маске item.mask = TVIF_TEXT | TVIF_PARAM; флажок TVIF_TEXT лишний,
потому что для текста нужно еще задать буфер и размер буфера в item.

Автор: artsb 9.4.2013, 14:43
HANDLE, всё верно. Но так как указана длина буфера 0, то этот флаг просто проигнорируется.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)