C++ CListViewCtrl中重复的图标

C++ CListViewCtrl中重复的图标,c++,winapi,mfc,C++,Winapi,Mfc,我知道主要问题来自递归调用FindFile()。通过递归调用此函数,myi变为0。但我不明白如何解决这个问题 如果可能的话,就如何在不完全修改以下所有功能的情况下修复此错误给出建议。或者提供一个链接,您可以在该链接中阅读CListViewCtrl中图标的正确初始化 void Finder::FindFile(CString szPath) { HIMAGELIST hSmall{}; CFindFile F; CString S = szPath + TEXT("

我知道主要问题来自递归调用
FindFile()
。通过递归调用此函数,my
i
变为0。但我不明白如何解决这个问题

如果可能的话,就如何在不完全修改以下所有功能的情况下修复此错误给出建议。或者提供一个链接,您可以在该链接中阅读
CListViewCtrl
中图标的正确初始化

void Finder::FindFile(CString szPath)
{
    HIMAGELIST hSmall{};
    CFindFile F;
    CString S = szPath + TEXT("\\*.*");
    int i = 0;
    BOOL bFlag = F.FindFile(S);
    if (!bFlag)
    {
        MessageBox(TEXT("Error"), TEXT("File not found"), 0);
    }
    else
    {
        do
        {
            if (F.IsDots() == TRUE)
            {
                continue;
            }
            else
            {
                if (F.IsDirectory() == TRUE)
                {
                    View_List(F.GetFileName(), i, F.GetFilePath());
                    i++;
                    FindFile(F.GetFilePath());
                }
                else
                {
                    View_List(F.GetFileName(), i, F.GetFilePath());
                    i++;
                }
            }
        } while (F.FindNextFileW());
        F.Close();
        InitListViewImage(i, S);
    }
}

void Finder::View_List(CString name, int i, CString path)
{
    CString nameWithoutEx=std::get<0>(Split(name));
    CString extention= std::get<1>(Split(name));
    lvItem.mask = LVIF_IMAGE | LVIF_TEXT;
    lvItem.state = 0;
    lvItem.stateMask = 0;
    lvItem.iItem = i;
    lvItem.iImage = i;
    lvItem.iSubItem = 0;
    lvItem.pszText = (LPWSTR)nameWithoutEx.GetString();
    lvItem.cchTextMax = nameWithoutEx.GetLength();
    myListView.InsertItem(&lvItem);
    myListView.SetItemText(i, 1, extention.GetString());
    myListView.SetItemText(i, 2, path.GetString());
}

std::tuple<CString, CString> Finder::Split(CString buf)
{
    CString tmp = buf;
    if (buf.Find(TEXT(".")) == -1)
    {
        return { buf.GetString(),TEXT("Directory") };
    }
    else
    {
        int index = buf.Find(TEXT("."))+1;
        if (buf.Find(TEXT("."),index) != -1)
        {
            while (buf.Find(TEXT("."), index) != -1)
            {
                index = buf.Find(TEXT("."), index)+1;
            }
        }
        buf.Delete(index-1, buf.GetLength());
        tmp.Delete(0, index-1);
        return{ buf.GetString(),tmp.GetString() };
    }
}


BOOL Finder::InitListViewImage(int size, CString path)
{
    CFindFile F;
    HIMAGELIST hSmall;
    SHFILEINFO lp{};
    hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK | ILC_COLOR32, size, 1);
    bool hFind = F.FindFile(path);
    if (!hFind)
    {
        MessageBox(TEXT("Error"), TEXT("File not found"), MB_OK | MB_ICONWARNING);
    }
    else
    {
        do
        {
            if (F.IsDots() == TRUE)
            {
                continue;
            }
            DWORD num = GetFileAttributesW(F.GetFilePath());
            SHGetFileInfoW(F.GetFilePath(), num, &lp, sizeof(lp), SHGFI_SYSICONINDEX | SHGFI_ICON | SHGFI_USEFILEATTRIBUTES);
            ImageList_AddIcon(hSmall, lp.hIcon);
            DestroyIcon(lp.hIcon);
        } while (F.FindNextFileW());
        F.Close();
    }
    myListView.SetImageList(hSmall, 1);
    return TRUE;
}
void Finder::FindFile(CString szPath)
{
HIMAGELIST hSmall{};
cfindf文件;
CString S=szPath+TEXT(\\*.*);
int i=0;
BOOL bFlag=F.FindFile(S);
如果(!bFlag)
{
MessageBox(文本(“错误”)、文本(“未找到文件”)、0;
}
其他的
{
做
{
如果(F.IsDots()==TRUE)
{
继续;
}
其他的
{
if(F.IsDirectory()==TRUE)
{
视图列表(F.GetFileName(),i,F.GetFilePath());
i++;
FindFile(F.GetFilePath());
}
其他的
{
视图列表(F.GetFileName(),i,F.GetFilePath());
i++;
}
}
}而(F.FindNextFileW());
F.关闭();
InitListViewImage(i,S);
}
}
无效查找器::查看列表(CString名称、int i、CString路径)
{
CString nameWithoutEx=std::get(Split(name));
CString extension=std::get(Split(name));
lvItem.mask=LVIF_图像| LVIF_文本;
lvItem.state=0;
lvItem.stateMask=0;
lvItem.iItem=i;
lvItem.iImage=i;
lvItem.iSubItem=0;
lvItem.pszText=(LPWSTR)nameWithoutEx.GetString();
lvItem.cchTextMax=nameWithoutEx.GetLength();
myListView.InsertItem(&lvItem);
SetItemText(i,1,extention.GetString());
myListView.SetItemText(i,2,path.GetString());
}
std::tuple Finder::Split(CString buf)
{
CString tmp=buf;
如果(基本查找(文本(“.”)=-1)
{
返回{buf.GetString(),TEXT(“Directory”)};
}
其他的
{
int index=buf.Find(文本(“.”)+1;
if(buf.Find(文本(“.”,索引)!=-1)
{
while(buf.Find(文本(“.”,索引)!=-1)
{
索引=buf.Find(文本(“.”,索引)+1;
}
}
buf.Delete(index-1,buf.GetLength());
tmp.删除(0,索引-1);
返回{buf.GetString(),tmp.GetString()};
}
}
BOOL Finder::InitListViewImage(int大小,CString路径)
{
cfindf文件;
HIMAGELIST hSmall;
SHFILEINFO lp{};
hSmall=ImageList_Create(GetSystemMetrics(SM_CXSMICON)、GetSystemMetrics(SM_CYSMICON)、ILC_MASK | ILC_COLOR32,大小,1);
bool hFind=F.FindFile(路径);
if(!hFind)
{
MessageBox(文本(“错误”)、文本(“未找到文件”)、MB_OK | MB_图标警告);
}
其他的
{
做
{
如果(F.IsDots()==TRUE)
{
继续;
}
DWORD num=GetFileAttributesW(F.GetFilePath());
SHGetFileInfoW(F.GetFilePath(),num,&lp,sizeof(lp),SHGFI_SYSICONINDEX | SHGFI_ICON | SHGFI_USEFILEATTRIBUTES);
ImageList_AddIcon(hSmall,lp.hIcon);
Destroycon(lp.hIcon);
}而(F.FindNextFileW());
F.关闭();
}
myListView.SetImageList(hSmall,1);
返回TRUE;
}

您需要传递
i
的值作为对
FindFile
的引用,这样当您递归调用它时,该值将继续递增

void Finder::FindFile(CString szPath, int& i)
{
    HIMAGELIST hSmall{};
    CFindFile F;
    CString S = szPath + TEXT("\\*.*");
//    int i = 0;  <-- not declared here, as it is now an argument
    BOOL bFlag = F.FindFile(S);
    if (!bFlag)
    {
        MessageBox(TEXT("Error"), TEXT("File not found"), 0);
    }
    else
    {
        do
        {
            if (F.IsDots() == TRUE)
            {
                continue;
            }
            else
            {
                if (F.IsDirectory() == TRUE)
                {
                    View_List(F.GetFileName(), i, F.GetFilePath());
                    i++;
                    FindFile(F.GetFilePath(), i); // <-- pass i to the recursive function
                }
                else
                {
                    View_List(F.GetFileName(), i, F.GetFilePath());
                    i++;
                }
            }
        } while (F.FindNextFileW());
        F.Close();
        InitListViewImage(i, S);
    }
}

从您的问题中不清楚您期望从该代码中得到什么以及您得到了什么。有4个函数,但没有可以作为起点的
main
或其他代码。所有其他函数仅支持此函数。所以,没有理由把我的主函数的代码放在这里。从你的问题中,你仍然不清楚你期望从这段代码中得到什么以及得到什么。在FindFile()函数中,我搜索文件。如果我在所需目录中找到文件,我将调用View_List()函数在CListViewCtrl中插入文件信息。但,若我找到了文件夹,我会再次调用我目录中文件夹的FindFile()函数,以获取该文件夹中文件的所有信息。而且,只有在我获取了目录中所有文件的所有信息后,我才调用这个函数。InitListViewImage()插入我的文件信息的图标。但我的图标不正确,它们是重复的。图标重复,因为我的变量I,当我递归调用我的FindFile()时,它变为0。变量I用作图像的索引。但因为它变为0,所以一切都不起作用。
main()
{
    int i = 0;
    FindFile("C:\", i);
}