208 lines
4.6 KiB
C++
208 lines
4.6 KiB
C++
|
//*******************************************************************************************
|
||
|
//
|
||
|
// 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);
|
||
|
}
|