[WinApi] Связка TreeVew с ListView через lParam

 
0
 
C++
ava
CynicRus | 22.03.2013, 12: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?
Kommentare (8)
ava
CynicRus | 22.03.2013, 11:27 #
Ну а если я в lParam структуру пакую, то на выходе получаю всё равно балалайку:


tvinsert.item.lParam=reinterpret_cast<int>(current);
ava
artsb | 24.03.2013, 19:10 #
А вы пишете под Windows CE? Почему я спрашиваю? Потому что TV_INSERTSTRUCT относится к Windows CE. Если вы пишете просто под Windows, то вам нужна TVINSERTSTRUCT. Скорее всего, из-за такого не соответствия и возникают "приколы".
ava
CynicRus | 25.03.2013, 08:19 #
Во как...Спасибо, не знал.
ava
CynicRus | 25.03.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.
ava
artsb | 25.03.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. Что я не так сделал?
ava
CynicRus | 25.03.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 дней мозгового штурма! Хахахаха! Спасибо!
ava
HANDLE | 09.04.2013, 14:15 #
Не мешало бы проверить что возвращает TreeView_GetItem(), может ошибка.
И в маске item.mask = TVIF_TEXT | TVIF_PARAM; флажок TVIF_TEXT лишний,
потому что для текста нужно еще задать буфер и размер буфера в item.
ava
artsb | 09.04.2013, 14:43 #
HANDLE, всё верно. Но так как указана длина буфера 0, то этот флаг просто проигнорируется.
Registrieren Sie sich oder melden Sie sich an, um schreiben zu können.
Unternehmen des Tages
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Mitwirkende
ava  artsb   HANDLE   CynicRus
advanced
Absenden