Winapi 如何为命名空间扩展中的虚拟文件设置图标?

Winapi 如何为命名空间扩展中的虚拟文件设置图标?,winapi,com,windows-shell,Winapi,Com,Windows Shell,我正在尝试向命名空间扩展中的虚拟文件添加图标。这些文件是.docx、.pdf和其他非windows默认扩展名,但我不清楚如何做到这一点。接受图标的文件路径和图标Id。调用SHGetFileInfo以获取图标路径和索引无法返回路径,但返回成功。SHGetFileInfo将向系统图标缓存返回正确的图标索引,我想使用它,但将该索引传递给SetNormalIcon(NULL,idx)无法设置正确的图标。如何设置文件图标 STDMETHODIMP CShellFolder::GetUIObjectOf(H

我正在尝试向命名空间扩展中的虚拟文件添加图标。这些文件是.docx、.pdf和其他非windows默认扩展名,但我不清楚如何做到这一点。接受图标的文件路径和图标Id。调用SHGetFileInfo以获取图标路径和索引无法返回路径,但返回成功。SHGetFileInfo将向系统图标缓存返回正确的图标索引,我想使用它,但将该索引传递给SetNormalIcon(NULL,idx)无法设置正确的图标。如何设置文件图标

STDMETHODIMP CShellFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *rgfReserved, void **ppv) {
    *ppv        = NULL;
    HRESULT hr  = E_NOTIMPL;
    if (IID_IExtractIcon == riid) {
        IDefaultExtractIconInit *pdxi   = NULL;
        hr                              = SHCreateDefaultExtractIcon(IID_PPV_ARGS(&pdxi));
        if (SUCCEEDED(hr)) {
            BOOL isFolder   = FALSE;
            hr              = m_pPidlMgr->IsFolder(apidl[0], &isFolder);
            if(SUCCEEDED(hr)) {
                pdxi->SetFlags(GIL_FORSHELL);
                hr = pdxi->SetNormalIcon(L"Shell32.dll", isFolder ? 4 : 1);
                if (SUCCEEDED(hr)) 
                    hr = pdxi->QueryInterface(riid, ppv);
            }
            pdxi->Release();
        }
    }
    return hr;
}

没有真正的文档记录,但当您将NULL作为文件名传递时,索引是一个,而不是一个系统imagelist索引!您可以看到上的示例中使用的
SIID.*
值。如果您只知道系统映像列表索引,我不确定是否可以使用
idefaultextracticonit


如果名称空间扩展仅返回系统映像列表中的图标,那么您可能只需要在shell文件夹实现中支持即可。否则,您可能必须创建自定义IExtractCon对象。

更简单的方法是将
IExtractCon
委托给文件系统
IShellFolder
+一个简单的pidl。我感谢您分享您的专业知识,Raymond。