0

我们读取注册表项GetOverlayInfo()IsMemberOf()方法来确定是否显示覆盖图标。S_FALSE如果未设置注册表项,我们将从这两种方法中返回。

问题是GetOverlayInfo()未设置何时调用注册表项,但在会话后期设置。我注意到一旦GetOverlayInfo()返回S_FALSE,shell 就不会IsMemberOf()进一步调用。

此注册表项是从不同的进程(我们的应用程序)设置/重置的,同时在资源管理器GetOverlayInfo()IsMemberOf()运行(这很明显)

我正在寻找使我的方案工作的想法,即在以某种方式切换注册表项后GetOverlayInfo()至少应该调用一次。到目前为止,我还没有在网络上找到任何方法。

我试图删除“Iconcache.db”文件,但这并没有强制资源管理器GetOverlayInfo()再次调用。

我们可以以编程方式清除资源管理器的缓存吗?这可能会强制资源管理器GetOverlayInfo()再次调用?

编辑 1 -
我在某处读到有一篇文章发表在 Window's Journal(WDJ) 的 98 期,标题为“重建 Internet shell 图标缓存”。也许这篇文章会有所帮助,但我在网上找不到。有人有线索吗?

编辑 2- 这是示例代码。由于我S_FALSEGetOverlayInfo()方法返回,这意味着我们告诉资源管理器从现在开始忽略当前会话的此覆盖图标,因此资源管理器不要IsMemberOf()进一步调用。现在,如果稍后切换注册表值,那么我希望资源管理器GetOverlayInfo()再次调用。那可能吗 ?

STDMETHOD(IsMemberOf)(LPCWSTR path, DWORD attr)
{

     ......
     ......
    // Check if icons are visible...
    if(!s_bOverlay)
    {
        return S_FALSE;
    }

    return S_OK;
}

STDMETHOD(GetOverlayInfo)(LPWSTR pwszIconFile, int iLength, int* piIndex, DWORD* pdwFlags)
{       
    // Check if icons are visible...
    if(!IsHandler(0))
    {
        return S_OK;
    }

    if(g_moduleName[0])
    {
        wcsncpy(pwszIconFile, g_moduleName, iLength - 1);

        // Retrieve the icon index...
        *piIndex  = static_cast<T*>(this)->GetIconIndex();
        *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;

        return S_OK;
    }

    return E_FAIL;
}


bool IsHandler(const UINT uiState)
{
    s_bOverlay = true;  // static variable
    if(ERROR_SUCCESS == reg.Open(HKEY_CURRENT_USER, L"SOFTWARE\\XYZ\\ABC", KEY_READ))
    {
        DWORD value = 1;

        reg.QueryDWORDValue(L"PQR", value);

        if(0 == value)
        {
            s_bOverlay = false;
        }
    }
return s_bOverlay; 
}
4

1 回答 1

1

对于那些关注这个帖子的人。这是我在评论部分与雷蒙德讨论的摘要。

在会话中,您只会调用一次 GetOverlayInfo() 方法。如果您从中返回无效值,则甚至不会调用 IsMemberOf() 方法。但是,如果您从 GetOverlayInfo() 返回有效值,则会调用 IsMemberOf()。而且我们不能以编程方式重置 Icon 的缓存。

于 2013-11-15T08:37:46.210 回答