首页 文章

TreeView添加Shell图标

提问于
浏览
1

我已经创建了treeview,我可以添加一些项目 . 基本上我想树视图所有目录和文件与图标相关联 . 所以我有这些功能:

  • 将项目添加到树视图
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;
}
  • 向TREEVIEW添加图标:
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;
}

我的主要问题是,当我期待,但是在树视图中的所有项目 . 所以基本上每个项目's icon is overwritten by new item'的图标 . 顺便说一下,我知道如果我想得到文件夹的图标,我需要使用 FILE_ATTRIBUTE_DIRECTORY ......就是这样 . 任何帮助都会受到极大的关注!先感谢您 :-)

1 回答

  • 4

    在您的 AddIconToTree 功能中,您每次都会创建一个全新的图像列表,其中只有一个图标 . 您需要维护相同的图像列表并向其添加其他图标,而不是为每个项目重新创建它 .

    或者,您可以使用SHGetImageList函数获取shell imagelist的句柄,然后直接将其分配给树 . 如果您没有't need to add any of your own images to the tree'的图像列表,这是一种更简单的方式来显示文件和文件夹的系统图标,因为shell图像列表可以处理所有这些 .

    // 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);
    

相关问题