|
|
//*******************************************************************************************
//
// Filename : XIcon.cpp
//
// Implementation file for CIconTemp and CXIcon
//
// Copyright (c) 1994 - 1996 Microsoft Corporation. All rights reserved
//
//*******************************************************************************************
#include "Pch.H"
#include "ThisDll.H"
#include "Unknown.H"
#include "XIcon.H"
class CIconTemp : public CObjTemp { public: CIconTemp() : CObjTemp() {} CIconTemp(HICON hi) : CObjTemp() {Attach(hi);} ~CIconTemp() {if (m_hObj) DestroyIcon(Detach());}
operator HICON() const {return((HICON)m_hObj);}
HICON Attach(HICON hObjNew) {return((HICON)CObjTemp::Attach((HANDLE)hObjNew));} HICON Detach() {return((HICON)CObjTemp::Detach());} } ;
BOOL CXIcon::Init(HWND hwndLB, UINT idiDef) { m_hwndLB = hwndLB;
m_cimlLg.Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 8); m_cimlSm.Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 8);
HICON hIcon = LoadIcon(g_ThisDll.GetInstance(), MAKEINTRESOURCE(idiDef));
return(m_cimlLg && m_cimlSm && AddIcon(hIcon)>=0); }
UINT CXIcon::GetIDString(LPTSTR pszIDString, UINT uIDLen, LPCTSTR szIconFile, int iIndex, UINT wFlags) { static const TCHAR szIDFmt[] = TEXT("\"%s\" %d %08x"); TCHAR szIDString[MAX_PATH + 2*ARRAYSIZE(szIDFmt)];
int iRet = wsprintf(szIDString, szIDFmt, szIconFile, iIndex, wFlags); lstrcpyn(pszIDString, szIDString, uIDLen);
return(iRet + 1); }
int CXIcon::GetCachedIndex(LPCTSTR szIconFile, int iIndex, UINT wFlags) { TCHAR szIDString[MAX_PATH*2]; GetIDString(szIDString, ARRAYSIZE(szIDString), szIconFile, iIndex, wFlags); int iLB = ListBox_FindStringExact(m_hwndLB, -1, szIDString);
if (iLB < 0) { return(-1); }
return (int)((INT_PTR)ListBox_GetItemData(m_hwndLB, iLB)); }
int CXIcon::CacheIcons(HICON hiLarge, HICON hiSmall, LPCTSTR szIconFile, int iIndex, UINT wFlags) { CIconTemp ciLarge(hiLarge); CIconTemp ciSmall(hiSmall);
if (!hiLarge || !hiSmall) { return(-1); }
TCHAR szIDString[MAX_PATH*2]; GetIDString(szIDString, ARRAYSIZE(szIDString), szIconFile, iIndex, wFlags); int iLB = ListBox_AddString(m_hwndLB, szIDString);
if (iLB < 0) { return(-1); }
int iLarge = AddIcon(ciLarge, AI_LARGE); if (iLarge >= 0) { int iSmall = AddIcon(ciSmall, AI_SMALL); if (iSmall >= 0) { if (iLarge == iSmall) { // Should always happen;
ListBox_SetItemData(m_hwndLB, iLB, iLarge); return(iLarge); }
ImageList_Remove(m_cimlSm, iSmall); }
ImageList_Remove(m_cimlLg, iLarge); }
ListBox_DeleteString(m_hwndLB, iLB); return(-1); }
HRESULT CXIcon::ExtractIcon(LPCTSTR szIconFile, int iIndex, UINT wFlags, HICON *phiconLarge, HICON *phiconSmall, DWORD dwSizes) { return(E_NOTIMPL); }
int CXIcon::GetIcon(IShellFolder *psf, LPCITEMIDLIST pidl) { int iImage = -1;
IExtractIcon *pxi; HRESULT hres = psf->GetUIObjectOf(NULL, 1, &pidl, IID_IExtractIcon, NULL, (LPVOID *)&pxi);
if (FAILED(hres)) { return(0); } CEnsureRelease erExtractIcon(pxi);
TCHAR szIconFile[MAX_PATH]; int iIndex; UINT wFlags = 0;
hres = pxi->GetIconLocation(GIL_FORSHELL, szIconFile, ARRAYSIZE(szIconFile), &iIndex, &wFlags); if (FAILED(hres)) { return(0); }
//
// if GIL_DONTCACHE was returned by the icon handler, dont
// lookup the previous icon, assume a cache miss.
//
if (!(wFlags & GIL_DONTCACHE)) { iImage = GetCachedIndex(szIconFile, iIndex, wFlags); }
// if we miss our cache...
if (iImage == -1) { HICON hiconLarge = NULL; HICON hiconSmall = NULL;
int cxIcon = GetSystemMetrics(SM_CXICON); int cxSmIcon = GetSystemMetrics(SM_CXSMICON);
// try getting it from the Extract member fuction
hres = pxi->Extract(szIconFile, iIndex, &hiconLarge, &hiconSmall, MAKELONG(cxIcon, cxSmIcon));
// S_FALSE means can you please do it
if (hres == S_FALSE) { hres = ExtractIcon(szIconFile, iIndex, wFlags, &hiconLarge, &hiconSmall, MAKELONG(cxIcon, cxSmIcon)); } if (SUCCEEDED(hres)) { // Let CacheIcons check and destroy the hicon's
iImage = CacheIcons(hiconLarge, hiconSmall, szIconFile, iIndex, wFlags); }
// if we failed in any way pick a default icon
if (iImage == -1) { if (wFlags & GIL_SIMULATEDOC) { iImage = 0; // II_DOCUMENT;
} else if ((wFlags & GIL_PERINSTANCE) && PathIsExe(szIconFile)) { iImage = 0; // II_APPLICATION;
} else { iImage = 0; // II_DOCNOASSOC;
} } }
if (iImage < 0) { iImage = 0; // II_DOCNOASSOC;
}
return(iImage); }
|