Get associated file icon with only extension name using C++ on Windows

Summary

A C++ solution is presented for retrieving associated file icons on Windows using only the file extension. The core of the approach involves the SHGetFileInfo function, utilizing SHGFI_ICON and SHGFI_USEFILEATTRIBUTES flags. For larger icon sizes like 48x48 or 256x256, the method extends to use SHGetImageList and IImageList::GetIcon to fetch icons from the system image list. Developers can use the provided getFileIcon function, passing the extension (e.g., ".txt") and a specified icon size type to obtain the desired HICON. A helper function, stringToLPCWSTR, is also included for necessary string conversions.

I have searched on Google for a few examples on how to get associated file icon with only file extension name using C++ on Windows. There are some useful information provided on MSDN which explains the use of SHGetFileInfo() function.It also gives an example code, but it doesn't say how to do it with only the extension name. 

Here I give an example code on how to achieve this after I gathered and summarized some  useful information from Internet. I have tested the code on my PC, it works fine.

/*
 * @method
 *        getFileIcon()
 * @param
 *        int       : icon type--FILE_ICON_SMALL                     0     16x16
 *                                         FILE_ICON_MEDIUM                  1     32x32
 *                                         FILE_ICON_LARGE                      2      48x48
 *                                         FILE_ICON_EXTRALARGE        3      256x256
 * @return
 *      HICON : the return icon
 * @description
 *      Get associated file icon from the extension name
 */
HICON getFileIcon(const string ext,int type){
    HICON hIcon;
    SHFILEINFO sfi={0};
    UINT flag = SHGFI_ICON|SHGFI_USEFILEATTRIBUTES;

    switch(type){
    case FILE_ICON_SMALL       : flag|=SHGFI_SMALLICON;break;
    case FILE_ICON_MEDIUM     : flag|=SHGFI_LARGEICON;break;
    case FILE_ICON_LARGE         :
    case FILE_ICON_EXTRALARGE : flag|=SHGFI_SYSICONINDEX;break;
    }
  HRESULT hr=SHGetFileInfo(stringToLPCWSTR(ext),FILE_ATTRIBUTE_NORMAL,&sfi,sizeof(sfi),flag);
    if(SUCCEEDED(hr)){
        if(type==FILE_ICON_LARGE||type==FILE_ICON_EXTRALARGE){
            // Retrieve the system image list.
            HIMAGELIST* imageList; 
             hr = SHGetImageList(((type==FILE_ICON_EXTRALARGE)?SHIL_JUMBO:SHIL_EXTRALARGE), IID_IImageList, (void**)&imageList);

            if (SUCCEEDED(hr)) {
                // Get the icon we need from the list. Note that the HIMAGELIST we retrieved
                // earlier needs to be casted to the IImageList interface before use.
                hr = ((IImageList*)imageList)->GetIcon(sfi.iIcon, ILD_TRANSPARENT, &hIcon);
            }
        }else{
            hIcon=sfi.hIcon;
        }
    }
    return hIcon;
}

LPCWSTR stringToLPCWSTR(const string& str){
    #ifdef UNICODE
    LPCWSTR result = wstring(str.begin(), str.end()).c_str();
    #else
    LPCWSTR result = str.c_str();
    #endif
    return result;
}

The parameters which we need to pass are the ext which should have the format ".ext"(don't forget the dot before the extension name) and type which is the file icon size. You can create an enum type to store these 4 type values in your C++ code.

Hope this will help those who are searching solutions about this problem. If you have ant questions. Please comment below and we can discuss together.

References :
[1].http://pogopixels.com/blog/getting-the-48x48-or-256x256-icon-of-a-file-on-windows/
[2].http://stackoverflow.com/questions/27220/how-to-convert-stdstring-to-lpcwstr-in-c-unicode

WINDOWS C++ FILE ICON ASSOCIATION EXTENSION NAME

  RELATED

  COMMENTS

0

No comment for this article.