EDN Admin
Well-known member
Hi Everyone,
I have written a Namespace Extension, and I am having problems extracting the associated icon for registered file types, specifically in XP.
I have the following code that works for Vista and Windows 7, but when I run it for XP, it just shows the default "No associated app" icons for everything, including the folders.
Basically, the NSE shows file names that are extracted from a database, not from the file system, and we would like them to be displayed with the same icons they would be displayed with if they were shown as native files from the file system in Explorer.
The code that works on Vista and 7 is as follows :
<pre class="prettyprint /*---------------------------------------------------------------*/
// IExtractIcon methods
/*---------------------------------------------------------------*/
STDMETHODIMP CExtractIcon::GetIconLocation(UINT uFlags,
LPTSTR /* szIconFile */, UINT /* cchMax */, LPINT /* piIndex */ , LPUINT puFlags )
{
*puFlags = GIL_DONTCACHE | GIL_NOTFILENAME;
<span class="x_Apple-tab-span" style="white-spacere return S_OK; // Return OK so Extract() gets called
}
STDMETHODIMP CExtractIcon::Extract(LPCTSTR /* pszFile */, UINT nIconIndex,
HICON* phiconLarge, HICON* phiconSmall, UINT /* nIconSize */)
{
PWSTR fileName = m_pPidlMgr->GetData(m_pidl);
SHFILEINFO sfi;
SecureZeroMemory(&sfi, sizeof sfi);
BOOL isFolder = m_pPidlMgr->IsFolder(m_pidl);
if(!isFolder)
{
// Get the icon
SHGetFileInfo(fileName,
FILE_ATTRIBUTE_NORMAL,
&sfi, sizeof(sfi),
SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES); // SHGFI_LARGEICON, SHGFI_SMALLICON
nIconIndex = sfi.iIcon;
*phiconSmall = sfi.hIcon;
SHGetFileInfo(fileName,
FILE_ATTRIBUTE_NORMAL,
&sfi, sizeof(sfi),
SHGFI_ICON | SHIL_EXTRALARGE | SHGFI_USEFILEATTRIBUTES ); // | SHGFI_USEFILEATTRIBUTES
nIconIndex = sfi.iIcon;
*phiconLarge = sfi.hIcon;
return S_OK;
}
else
{
// Get the small icon
//SHGetFileInfo(
//fileName,
//FILE_ATTRIBUTE_DIRECTORY,
//&sfi, sizeof sfi,
//SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES);
//nIconIndex = sfi.iIcon;
//// *phiconSmall = sfi.hIcon;
//// Get the large icon
//SHGetFileInfo(
//fileName,
//FILE_ATTRIBUTE_DIRECTORY,
//&sfi, sizeof sfi,
//SHGFI_ICON | SHGFI_LARGEICON | SHGFI_USEFILEATTRIBUTES);
//nIconIndex = sfi.iIcon;
//// *phiconLarge = sfi.hIcon;
// Just return S_OK without doing anything if the Pidl represents a Folder.
return S_OK;
}
}
[/code]
GetIconLocation simply returns S_OK so that ::Extract is called.
The thing I dont fully understand about this code is that while the if(!isFolder) block works, it returns icons with low resolution that appear fuzzy when displayed in Explorer. Also, the else{} block for when the PIDL names a Directory, doesnt do anything,
it just returns S_OK. However, the high definition icon for a Folder is displayed perfectly, which doesnt really make any sense because Im just returning OK, without setting the values of the two icon handles that are meant to be returned. The whole
thing fails in XP and just displays the default "No associated application" icon.
I had asked a similar question a few months ago, and ExtractAssociatedIcon() was mentioned as a potential fix, but I didnt have any luck with that route either.
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/39786dd5-43b5-4089-9e43-97818e0b4cda
I attempted to use that function in ::Extract as follows :
<pre class="prettyprint <span class="x_Apple-tab-span" style="white-spacere WORD idx;
HICON icon = ExtractAssociatedIcon(g_hInst, fileName, &idx );
*phiconLarge = icon;
*phiconSmall = icon;[/code]
But wound up blowing up the heap. I didnt spend much time debugging this as a colleague pointed me to the code you see above, which works okay, unless you are trying to us XP, and if you dont mind the low res icons.
Has anybody had any luck implementing IExtractIcon in a manner that works on all platforms XP forward ?
Thanks in advance for any advice.
JT.
View the full article
I have written a Namespace Extension, and I am having problems extracting the associated icon for registered file types, specifically in XP.
I have the following code that works for Vista and Windows 7, but when I run it for XP, it just shows the default "No associated app" icons for everything, including the folders.
Basically, the NSE shows file names that are extracted from a database, not from the file system, and we would like them to be displayed with the same icons they would be displayed with if they were shown as native files from the file system in Explorer.
The code that works on Vista and 7 is as follows :
<pre class="prettyprint /*---------------------------------------------------------------*/
// IExtractIcon methods
/*---------------------------------------------------------------*/
STDMETHODIMP CExtractIcon::GetIconLocation(UINT uFlags,
LPTSTR /* szIconFile */, UINT /* cchMax */, LPINT /* piIndex */ , LPUINT puFlags )
{
*puFlags = GIL_DONTCACHE | GIL_NOTFILENAME;
<span class="x_Apple-tab-span" style="white-spacere return S_OK; // Return OK so Extract() gets called
}
STDMETHODIMP CExtractIcon::Extract(LPCTSTR /* pszFile */, UINT nIconIndex,
HICON* phiconLarge, HICON* phiconSmall, UINT /* nIconSize */)
{
PWSTR fileName = m_pPidlMgr->GetData(m_pidl);
SHFILEINFO sfi;
SecureZeroMemory(&sfi, sizeof sfi);
BOOL isFolder = m_pPidlMgr->IsFolder(m_pidl);
if(!isFolder)
{
// Get the icon
SHGetFileInfo(fileName,
FILE_ATTRIBUTE_NORMAL,
&sfi, sizeof(sfi),
SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES); // SHGFI_LARGEICON, SHGFI_SMALLICON
nIconIndex = sfi.iIcon;
*phiconSmall = sfi.hIcon;
SHGetFileInfo(fileName,
FILE_ATTRIBUTE_NORMAL,
&sfi, sizeof(sfi),
SHGFI_ICON | SHIL_EXTRALARGE | SHGFI_USEFILEATTRIBUTES ); // | SHGFI_USEFILEATTRIBUTES
nIconIndex = sfi.iIcon;
*phiconLarge = sfi.hIcon;
return S_OK;
}
else
{
// Get the small icon
//SHGetFileInfo(
//fileName,
//FILE_ATTRIBUTE_DIRECTORY,
//&sfi, sizeof sfi,
//SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES);
//nIconIndex = sfi.iIcon;
//// *phiconSmall = sfi.hIcon;
//// Get the large icon
//SHGetFileInfo(
//fileName,
//FILE_ATTRIBUTE_DIRECTORY,
//&sfi, sizeof sfi,
//SHGFI_ICON | SHGFI_LARGEICON | SHGFI_USEFILEATTRIBUTES);
//nIconIndex = sfi.iIcon;
//// *phiconLarge = sfi.hIcon;
// Just return S_OK without doing anything if the Pidl represents a Folder.
return S_OK;
}
}
[/code]
GetIconLocation simply returns S_OK so that ::Extract is called.
The thing I dont fully understand about this code is that while the if(!isFolder) block works, it returns icons with low resolution that appear fuzzy when displayed in Explorer. Also, the else{} block for when the PIDL names a Directory, doesnt do anything,
it just returns S_OK. However, the high definition icon for a Folder is displayed perfectly, which doesnt really make any sense because Im just returning OK, without setting the values of the two icon handles that are meant to be returned. The whole
thing fails in XP and just displays the default "No associated application" icon.
I had asked a similar question a few months ago, and ExtractAssociatedIcon() was mentioned as a potential fix, but I didnt have any luck with that route either.
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/39786dd5-43b5-4089-9e43-97818e0b4cda
I attempted to use that function in ::Extract as follows :
<pre class="prettyprint <span class="x_Apple-tab-span" style="white-spacere WORD idx;
HICON icon = ExtractAssociatedIcon(g_hInst, fileName, &idx );
*phiconLarge = icon;
*phiconSmall = icon;[/code]
But wound up blowing up the heap. I didnt spend much time debugging this as a colleague pointed me to the code you see above, which works okay, unless you are trying to us XP, and if you dont mind the low res icons.
Has anybody had any luck implementing IExtractIcon in a manner that works on all platforms XP forward ?
Thanks in advance for any advice.
JT.
View the full article