TreeView добавить иконки оболочки

Я уже создал вид дерева, где я могу добавить некоторые элементы. В основном я хочу просматривать все каталоги и файлы с иконками, связанными с ними. Итак, у меня есть эти функции:

  1. Добавление элементов в древовидную структуру

    HTREEITEM AddItemToTree(HWND hwndTree, char *text, int nLevel)
    {
        TVINSERTSTRUCT tvins;
        static HTREEITEM hPrev = (HTREEITEM)TVI_FIRST;
        static HTREEITEM hRootItem = NULL;
        static HTREEITEM hPrevLev2Item = NULL;
        AddIconToTree(hwndTree, text); //////////// THIS IS THE FUNCTION BELOW...
        tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIS_STATEIMAGEMASK;
        tvi.iImage = 0;
        tvi.iSelectedImage = 0;
        tvi.pszText = GetFileNameFromPath(text);
        tvins.hInsertAfter = hPrev;
        tvins.item = tvi;
    
        if(nLevel == 1)
        {
            tvins.hParent = TVI_ROOT;
        }
        else if(nLevel == 2)
        {
            tvins.hParent = hRootItem;
        }
        else
        {
            TVITEM tviSetup;
            tviSetup.hItem = hPrev;
            tviSetup.mask = TVIF_PARAM;
            TVITEM * tviLocal = &tviSetup;
            TreeView_GetItem(hwndTree, tviLocal);
    
            if(nLevel > tviLocal->lParam)
            {
                tvins.hParent = hPrev;
            }
            else
            {
                HTREEITEM hPrevLocal = TreeView_GetParent(hwndTree, hPrev);
                tviLocal->hItem = hPrevLocal;
                TreeView_GetItem(hwndTree, tviLocal);
                for(int i = nLevel; i <= tviLocal->lParam;)
                {
                    HTREEITEM hPrevLocalTemp = TreeView_GetParent(hwndTree, hPrevLocal);
                    hPrevLocal = hPrevLocalTemp;
                    tviLocal->hItem = hPrevLocal;
                    TreeView_GetItem(hwndTree, tviLocal);
                }
                tviLocal->mask = TVIF_TEXT;
                TreeView_GetItem(hwndTree, tviLocal);
                tvins.hParent = hPrevLocal;
    
            }
        }
    
        hPrev = (HTREEITEM)SendMessage(hwndTree, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
    
        if(hPrev == 0)
        {
            return false;
        }
        if(nLevel == 1)
        {
            hRootItem = hPrev;
        }
    
        return hPrev;
    }
    
  2. ДОБАВЛЕНИЕ ЗНАЧКОВ В ТРИВАН:

    int AddIconToTree(HWND hwndTree, char *strPath)
    {
        SHFILEINFO sfi;
        memset(&sfi, 0, sizeof(sfi));
        SHGetFileInfo(strPath, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON);
        int index = sfi.iIcon;
    
        ICONINFO iconinfo;
        GetIconInfo(sfi.hIcon, &iconinfo);
        HBITMAP hBitmap = iconinfo.hbmColor;
        DestroyIcon(sfi.hIcon);
    
        himg = ImageList_Create(16, 16, ILC_COLOR32, 1, 1);
        int iImageList = ImageList_Add(himg, hBitmap, NULL);
        DeleteObject(hBitmap);
    
        //TreeView_SetImageList(hwndTree, himg, TVSIL_NORMAL);
        SendMessage(hwndTree, TVM_SETIMAGELIST, (WPARAM)TVSIL_NORMAL, (LPARAM)(HIMAGELIST)himg);
        MessageBox(hwnd, strPath, "Path:", MB_OK); /* Because of this msgbox I found out what is
        really happening, because without it everything I have seen when I run the program was
        treeview with icon of the last file, which was folder...So blank icon.*/
        return index;
    }
    

Моя главная проблема в том, что когда я устанавливаю какой-либо значок, он устанавливается не только для одного элемента, как я ожидаю, но и для всех элементов в древовидном представлении. Таким образом, в основном значок каждого элемента перезаписывается значком нового элемента. Кстати, я знаю, что если я хочу получить значок папки, мне нужно использовать FILE_ATTRIBUTE_DIRECTORY... Итак, это все. Любая помощь будет очень ценна! Заранее спасибо:-)

1 ответ

Решение

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

Кроме того, вы можете получить дескриптор списка изображений оболочки с помощью SHGetImageList функции, а затем назначить его непосредственно в дерево. Если вам не нужно добавлять какие-либо свои собственные изображения в список изображений дерева, это гораздо более простой способ отображения системных значков для файлов и папок, поскольку список изображений оболочки обрабатывает все это за вас.

// To initialise the tree's image list - do this one time only
HIMAGELIST himg;
if (SUCCEEDED(SHGetImageList(SHIL_SMALL, IID_IImageList, reinterpret_cast<void**>(&himg))))
    SendMessage(hwndTree, TVM_SETIMAGELIST, (WPARAM)TVSIL_NORMAL, (LPARAM)himg);

Тогда ваш AddIconToTree функция просто становится:

int AddIconToTree(HWND hwndTree, char *strPath)
{
    SHFILEINFO sfi;
    memset(&sfi, 0, sizeof(sfi));

    // SHGFI_SYSICONINDEX will return the icon's index within the shell image list
    SHGetFileInfo(strPath, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi),
        SHGFI_SYSICONINDEX | SHGFI_USEFILEATTRIBUTES);
    return sfi.iIcon;
}

И когда вы на самом деле добавляете элементы в список, убедитесь, что вы присвоили индекс элементу:

tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIS_STATEIMAGEMASK;
tvi.iImage = tvi.iSelectedImage = AddIconToTree(hwndTree, text);
Другие вопросы по тегам