int Entry::extract_icon(ICONCACHE_FLAGS flags) { TCHAR path[MAX_PATH]; ICON_ID icon_id = ICID_NONE; if (_etype!=ET_SHELL && get_path(path, COUNTOF(path))) // not for ET_SHELL to display the correct desktop icon if (!(flags & ICF_MIDDLE)) // not for ICF_MIDDLE to extract 24x24 icons because SHGetFileInfo() doesn't support this icon size icon_id = g_Globals._icon_cache.extract(path, flags); if (icon_id == ICID_NONE) { if (!(flags & ICF_OVERLAYS)) { IExtractIcon* pExtract; if (SUCCEEDED(GetUIObjectOf(0, IID_IExtractIcon, (LPVOID*)&pExtract))) { unsigned gil_flags = 0; int idx; if (flags & ICF_OPEN) gil_flags |= GIL_OPENICON; if (SUCCEEDED(pExtract->GetIconLocation(GIL_FORSHELL, path, COUNTOF(path), &idx, &gil_flags))) { if (gil_flags & GIL_NOTFILENAME) icon_id = g_Globals._icon_cache.extract(pExtract, path, idx, flags); else { if (idx == -1) idx = 0; // special case for some control panel applications ("System") icon_id = g_Globals._icon_cache.extract(path, idx, flags); } /* using create_absolute_pidl() [see below] results in more correct icons for some control panel applets (NVidia display driver). if (icon_id == ICID_NONE) { SHFILEINFO sfi; if (SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_ICON|SHGFI_SMALLICON)) icon_id = g_Globals._icon_cache.add(sfi.hIcon)._id; } */ /* if (icon_id == ICID_NONE) { LPBYTE b = (LPBYTE) alloca(0x10000); SHFILEINFO sfi; FILE* file = fopen(path, "rb"); if (file) { int l = fread(b, 1, 0x10000, file); fclose(file); if (l) icon_id = g_Globals._icon_cache.add(CreateIconFromResourceEx(b, l, TRUE, 0x00030000, 16, 16, LR_DEFAULTCOLOR)); } } */ } } } if (icon_id == ICID_NONE) { const ShellPath& pidl_abs = create_absolute_pidl(); LPCITEMIDLIST pidl = pidl_abs; icon_id = g_Globals._icon_cache.extract(pidl, flags); } } return icon_id; }
QString FhoIcon::getImageIdForFile(IShellFolder *psfParentItem, LPITEMIDLIST pidlChildItem) { HRESULT hres; IExtractIcon *pExtractIcon = NULL; hres = psfParentItem->GetUIObjectOf(NULL, 1, const_cast<LPCITEMIDLIST *>(&pidlChildItem), IID_IExtractIcon, NULL, reinterpret_cast<LPVOID *>(&pExtractIcon)); if (SUCCEEDED(hres)) { TCHAR str[MAX_PATH] = {0}; int index; UINT flags; // Get the file location where the icons are stored. hres = pExtractIcon->GetIconLocation(0, str, MAX_PATH, &index, &flags); if (SUCCEEDED(hres)) { QString iconResourceFile = QString::fromWCharArray(str); // this may return "*" and does not always refer to a real existing file; see above! QString imageId = "@" + iconResourceFile + "," + QString::number(index); // did we already expand the resource file name? return imageId; } else { return getImageIdForFile(pidlChildItem); } pExtractIcon->Release(); } else { return getImageIdForFile(pidlChildItem); } }
/* * Class: sun_awt_shell_Win32ShellFolder * Method: getIcon * Signature: (JJZ)J */ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder_getIcon__JJZ (JNIEnv* env, jobject folder, jlong parentIShellFolder, jlong relativePIDL, jboolean getLargeIcon) { IShellFolder* pParent = (IShellFolder*)parentIShellFolder; if (pParent == NULL) { return 0; } LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL; if (pidl == NULL) { return 0; } IExtractIcon* pIcon; if (pParent->GetUIObjectOf(NULL, 1, const_cast<LPCITEMIDLIST*>(&pidl), IID_IExtractIcon, NULL, (void**)&pIcon) != S_OK) { return 0; } CHAR szBuf[MAX_PATH]; INT index; UINT flags; if (pIcon->GetIconLocation( GIL_FORSHELL, szBuf, MAX_PATH, &index, &flags) != S_OK) { pIcon->Release(); return 0; } HICON hIcon; HICON hIconLarge; if (pIcon->Extract(szBuf, index, &hIconLarge, &hIcon, (16 << 16) + 32) != S_OK) { pIcon->Release(); return 0; } return (jlong)(getLargeIcon ? hIconLarge : hIcon); }
QImage FhoIcon::getIconForFile(IShellFolder *psfParentItem, LPITEMIDLIST pidlChildItem) { HRESULT hres; IExtractIcon *pExtractIcon = NULL; hres = psfParentItem->GetUIObjectOf(NULL, 1, const_cast<LPCITEMIDLIST *>(&pidlChildItem), IID_IExtractIcon, NULL, reinterpret_cast<LPVOID *>(&pExtractIcon)); if (SUCCEEDED(hres)) { TCHAR str[MAX_PATH] = {0}; int index; UINT flags; // Get the file location where the icons are stored. hres = pExtractIcon->GetIconLocation(0, str, MAX_PATH, &index, &flags); //hres = pExtractIcon->GetIconLocation(GIL_FORSHELL, str, MAX_PATH, &index, &flags); if (SUCCEEDED(hres)) { QString iconResourceFile = QString::fromWCharArray(str); // do not use 'general' getIconFromResource() -> ExtractIcon()! // use 'specific' pExtractIcon->Extract() instead! // this is because iconResourceFile returned may be "*" and not refer to a real file! pExtractIcon->Extract() will handle this, ExtractIcon() cannot handle this! // "*" is dangerous for caching the imageId! we could check if iconResourceFile refers to an existing file!? HICON hIconLarge = NULL; UINT nIconSize = MAKELONG(0, 0); // this requests the default size!? hres = pExtractIcon->Extract(str, index, &hIconLarge, NULL, nIconSize); if (hres == NOERROR) { if (hIconLarge) { QImage image = getIconFromHandle(hIconLarge); DestroyIcon(hIconLarge); return image; } else { return getIconFromResource(iconResourceFile, index); } } else { return getIconFromResource(iconResourceFile, index); } } else { return getIconForFile(pidlChildItem); } pExtractIcon->Release(); } else { return getIconForFile(pidlChildItem); } }
int ShellEntry::extract_icon() { TCHAR path[MAX_PATH]; ICON_ID icon_id = ICID_NONE; if (get_path(path, COUNTOF(path))) icon_id = g_Globals._icon_cache.extract(path); if (icon_id == ICID_NONE) { IExtractIcon* pExtract; if (SUCCEEDED(GetUIObjectOf(0, IID_IExtractIcon, (LPVOID*)&pExtract))) { unsigned flags; int idx; if (SUCCEEDED(pExtract->GetIconLocation(GIL_FORSHELL, path, MAX_PATH, &idx, &flags))) { if (flags & GIL_NOTFILENAME) icon_id = g_Globals._icon_cache.extract(pExtract, path, idx); else { if (idx == -1) idx = 0; // special case for some control panel applications ("System") icon_id = g_Globals._icon_cache.extract(path, idx); } /* using create_absolute_pidl() [see below] results in more correct icons for some control panel applets ("NVidia"). if (icon_id == ICID_NONE) { SHFILEINFO sfi; if (SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_ICON|SHGFI_SMALLICON)) icon_id = g_Globals._icon_cache.add(sfi.hIcon)._id; } */ /* if (icon_id == ICID_NONE) { LPBYTE b = (LPBYTE) alloca(0x10000); SHFILEINFO sfi; FILE* file = fopen(path, "rb"); if (file) { int l = fread(b, 1, 0x10000, file); fclose(file); if (l) icon_id = g_Globals._icon_cache.add(CreateIconFromResourceEx(b, l, TRUE, 0x00030000, 16, 16, LR_DEFAULTCOLOR)); } } */ } } if (icon_id == ICID_NONE) { SHFILEINFO sfi; const ShellPath& pidl_abs = create_absolute_pidl(); LPCITEMIDLIST pidl = pidl_abs; HIMAGELIST himlSys = (HIMAGELIST) SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX|SHGFI_PIDL|SHGFI_SMALLICON); if (himlSys) icon_id = g_Globals._icon_cache.add(sfi.iIcon); /* if (SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL|SHGFI_ICON|SHGFI_SMALLICON)) icon_id = g_Globals._icon_cache.add(sfi.hIcon)._id; */ } } return icon_id; }