irsis
irsis

Reputation: 1054

Can we enforce shell extension to call IShellIconOverlayIdentifier::GetOverlayInfo explicitly?

We read a registry key in GetOverlayInfo() and IsMemberOf() methods to determine whether to show the overlay icons or not. From both of these methods we return S_FALSE if registry key is not set.

Problem is that when GetOverlayInfo() is called registry key is not set but it is set later in the session. I've noticed once GetOverlayInfo() returns S_FALSE, shell doesn't call IsMemberOf() further.

This registry key is set/reset from a different process(our application) while GetOverlayInfo() and IsMemberOf() runs within explorer (which is obvious)

I am looking for ideas to make my scenario work i.e. After registry key is toggled somehow GetOverlayInfo() should be called at least once. I've not found any way to do on web so far.

I tried to delete "Iconcache.db" file but that didn't enforce explorer to call GetOverlayInfo() again.

Can we clear explorer's cache programmatically ? That might enforce explorer to call GetOverlayInfo() again?

Edit 1 -
I read somewhere that there was article published in 98 issue of Window's Journal(WDJ) under title "rebuilding internet shell icons cache". Perhaps this article will help but I don't find it on web. Anybody has clue ?

Edit 2- Here is the sample code. Since I am returning S_FALSE from GetOverlayInfo() method which means we are telling explorer to ignore this overlay icon from now on for current session therefore explorer don't call IsMemberOf() further. Now if sometime later registry value is toggled then I want explorer to call GetOverlayInfo() again. Is that possible ?

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; 
}

Upvotes: 0

Views: 1022

Answers (1)

irsis
irsis

Reputation: 1054

For those following this thread.Here is the summary of discussions I had with Raymond in comment section.

You get only one call of GetOverlayInfo() method in a session. If you return an invalid value from it then IsMemberOf() method will not even be called. But if you return valid value from GetOverlayInfo() then IsMemberOf() will be called. And we can't reset Icon's cache programatically.

Upvotes: 1

Related Questions