Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

346 lines
9.6 KiB

//____________________________________________________________________________
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995 - 1996.
//
// File: icon.cxx
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 4/5/1996 RaviR Created
//
//____________________________________________________________________________
#include "..\pch\headers.hxx"
#pragma hdrstop
#include "dbg.h"
#include "macros.h"
#include "..\inc\resource.h"
#include "resource.h"
#include "jobicons.hxx"
extern HINSTANCE g_hInstance;
CJobIcon::CJobIcon(void)
{
m_himlSmall = NULL; // init so that if anything fails before any list
m_himlLarge = NULL; // gets created, the destructor will not fault.
m_himlXLarge = NULL;
//
// Load and setup the small overlay imagelist
//
// if (!LoadImageList(&m_himlSmall, BMP_JOBSTATES, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)))
if (!LoadImageList(&m_himlSmall, BMP_JOBSTATES, 16, 16))
{
DEBUG_OUT((DEB_ERROR, "Small image list failed to load.\n"));
return;
}
//
// Load and setup the large overlay imagelist
//
// if (!LoadImageList(&m_himlLarge, BMP_JOBSTATEL, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)))
if (!LoadImageList(&m_himlLarge, BMP_JOBSTATEL, 32, 32))
{
DEBUG_OUT((DEB_ERROR, "Large image list failed to load.\n"));
return;
}
//
// Load and setup the Xtralarge overlay imagelist
// extra large icons are 48x48
//
if (!LoadImageList(&m_himlXLarge, BMP_JOBSTATEXL, 48, 48))
{
DEBUG_OUT((DEB_ERROR, "XLarge image list failed to load.\n"));
return;
}
}
bool CJobIcon::LoadImageList(HIMAGELIST* phiml, UINT nBmpToLoad, int cx, int cy)
{
//
// Load and setup the overlay imagelist
//
*phiml = ImageList_Create(cx, cy, ILC_COLOR32 | ILC_MASK, 1, 1);
if (!phiml)
{
DEBUG_OUT((DEB_ERROR, "ImageList_Create returned NULL.\n"));
return false;
}
HBITMAP hBmp = (HBITMAP)LoadImage(g_hInstance, MAKEINTRESOURCE(nBmpToLoad), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
if (!hBmp)
{
DEBUG_OUT((DEB_ERROR, "LoadImage returned NULL.\n"));
return false;
}
int i = ImageList_AddMasked(*phiml, hBmp, RGB(0, 255, 0));
// delete this here regardless of whether above call failed so that it won't get leaked by an early return
DeleteObject(hBmp);
if (i == -1)
{
DEBUG_OUT((DEB_ERROR, "ImageList_AddMasked returned -1.\n"));
return false;
}
if ( !ImageList_SetOverlayImage(*phiml, 0, 1) ||
!ImageList_SetOverlayImage(*phiml, 1, 2))
{
DEBUG_OUT((DEB_ERROR, "ImageList_SetOverlayImage returned 0.\n"));
return false;
}
return true;
}
HICON GetDefaultAppIcon(UINT nIconSize)
{
TRACE_FUNCTION(GetDefaultAppIcon);
return (HICON)LoadImage(g_hInstance, (LPCTSTR)IDI_GENERIC, IMAGE_ICON, nIconSize, nIconSize, LR_CREATEDIBSECTION);
}
void
CJobIcon::GetIcons(
LPCTSTR pszApp,
BOOL fEnabled,
HICON * phiconLarge,
HICON * phiconSmall,
UINT nIconSize)
{
TRACE(CJobIcon, GetIcons);
UINT nLargeSize = nIconSize & 0x0000ffff;
UINT nSmallSize = (nIconSize & 0xffff0000) >> 16;
if (nLargeSize && phiconLarge)
{
TS_ExtractIconEx(pszApp, 0, phiconLarge, 1, nLargeSize);
_OverlayIcons(phiconLarge, fEnabled, nLargeSize);
}
if (nSmallSize && phiconSmall)
{
TS_ExtractIconEx(pszApp, 0, phiconSmall, 1, nSmallSize);
_OverlayIcons(phiconSmall, fEnabled, nSmallSize);
}
}
//+--------------------------------------------------------------------------
//
// Member: CJobIcon::GetTemplateIcons
//
// Synopsis: Fill out pointers with large and small template icons
//
// Arguments: [phiconLarge] - NULL or ptr to icon handle to fill
// [phiconSmall] - ditto
//
// History: 5-15-1997 DavidMun Created
//
//---------------------------------------------------------------------------
void
CJobIcon::GetTemplateIcons(
HICON * phiconLarge,
HICON * phiconSmall,
UINT nIconSize)
{
TRACE(CJobIcon, GetTemplateIcons);
UINT nLargeSize = nIconSize & 0x0000ffff; // nIconSize contains the large size in the low word
UINT nSmallSize = (nIconSize & 0xffff0000) >> 16; // nIconSize contains the small size in the high word
if (nLargeSize && phiconLarge)
{
*phiconLarge = (HICON) LoadImage(g_hInstance,
MAKEINTRESOURCE(IDI_TEMPLATE),
IMAGE_ICON,
nLargeSize,
nLargeSize,
LR_CREATEDIBSECTION);
if (!*phiconLarge)
{
DEBUG_OUT_LASTERROR;
}
}
if (nSmallSize && phiconSmall)
{
*phiconSmall = (HICON) LoadImage(g_hInstance,
MAKEINTRESOURCE(IDI_TEMPLATE),
IMAGE_ICON,
nSmallSize,
nSmallSize,
LR_CREATEDIBSECTION);
if (!*phiconSmall)
{
DEBUG_OUT_LASTERROR;
}
}
}
void
CJobIcon::_OverlayIcons(
HICON * phicon,
BOOL fEnabled,
UINT nIconSize)
{
HICON hiconTemp;
if (phicon != NULL)
{
if (*phicon == NULL)
{
*phicon = GetDefaultAppIcon(nIconSize);
}
hiconTemp = OverlayStateIcon(*phicon, fEnabled, nIconSize);
DestroyIcon(*phicon);
*phicon = hiconTemp;
}
}
HICON
CJobIcon::OverlayStateIcon(
HICON hicon,
BOOL fEnabled,
UINT nIconSize)
{
TRACE(CJobIcon, OverlayStateIcon);
HICON hiconOut;
UINT nLargeSize = GetSystemMetrics(SM_CXICON);
UINT nSmallSize = GetSystemMetrics(SM_CXSMICON);
// dont destroy rhiml !!
HIMAGELIST &rhiml = (nIconSize > nLargeSize) ? m_himlXLarge : ((nIconSize > nSmallSize) ? m_himlLarge : m_himlSmall);
int i = ImageList_AddIcon(rhiml, hicon);
hiconOut = ImageList_GetIcon(rhiml, i, INDEXTOOVERLAYMASK((fEnabled ? 1 : 2)));
ImageList_Remove(rhiml, i);
return hiconOut;
}
//+--------------------------------------------------------------------------
//
// Function: TS_ExtractIconEx
//
// Synopsis: Extract the desired icons from an executable. The file is pre-
// processed to avoid NULL and empty files, and files which are
// actually links (they weren't resolved to their exes because they
// are MSI apps -- e.g. Office apps) get resolved to the actual
// executable so that an icon can be obtained.
//
// Arguments: Same as for ExtractIconEx:
//
// LPCTSTR lpszFile, // file name
// int nIconIndex, // icon index
// HICON* phiconLarge, // large icon array
// HICON* phiconSmall, // small icon array
// UINT nIcons, // number of icons to extract
// UINT nIconSize // large (low word) and small (high word) sizes
//
// History: 08-28-2001 ShBrown Created in response to bug #446344
//
//---------------------------------------------------------------------------
UINT TS_ExtractIconEx(
LPCTSTR lpszFile, // file name
int nIconIndex, // icon index
HICON* phicon, // icon array
UINT nIcons, // number of icons to extract
UINT nIconSize // width or height (they're the same)
)
{
if (lpszFile != NULL && *lpszFile != TEXT('\0'))
{
LPTSTR ptszExt = PathFindExtension(lpszFile);
if (ptszExt && !_tcsicmp(ptszExt, TEXT(".LNK")))
{
TCHAR szLnkPath[MAX_PATH];
ResolveLnk(lpszFile, szLnkPath);
return SHExtractIconsW(szLnkPath, nIconIndex, nIconSize, nIconSize, phicon, NULL, nIcons, LR_CREATEDIBSECTION);
}
else
return SHExtractIconsW(lpszFile, nIconIndex, nIconSize, nIconSize, phicon, NULL, nIcons, LR_CREATEDIBSECTION);
}
return 0;
}
//+--------------------------------------------------------------------------
//
// Function: ResolveLnk
//
// Synopsis: Helper for TS_ExtractIconEx. Take a link and find its exe.
//
// Arguments: LPCTSTR lpszLnkPath, // path to link
// LPTSTR lpszExePath // path to exe
//
// History: 08-28-2001 ShBrown Created in response to bug #446344
//
// Mainly stolen from wizard\walklib.cxx and modified
//
//---------------------------------------------------------------------------
void ResolveLnk(
LPCTSTR lpszLnkPath, // path to link
LPTSTR lpszExePath // path to exe
)
{
// Get a pointer to the IShellLink interface.
IShellLink* psl;
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
if (SUCCEEDED(hres))
{
// Get a pointer to the IPersistFile interface.
IPersistFile* ppf;
hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
if (SUCCEEDED(hres))
{
WCHAR wsz[MAX_PATH];
lstrcpyn(wsz, lpszLnkPath, ARRAYLEN(wsz));
// Load the shell link.
hres = ppf->Load(wsz, STGM_READ);
if (SUCCEEDED(hres))
{
TCHAR szGotPath[MAX_PATH];
lstrcpyn(szGotPath, lpszLnkPath, MAX_PATH);
// Get the path to the link target.
WIN32_FIND_DATA wfdExeData;
hres = psl->GetPath(szGotPath, MAX_PATH, &wfdExeData, SLGP_SHORTPATH );
if (SUCCEEDED(hres))
{
if (lstrlen(szGotPath) > 0)
{
lstrcpyn(lpszExePath, szGotPath, MAX_PATH);
}
}
}
// Release pointer to IPersistFile interface.
ppf->Release();
}
// Release pointer to IShellLink interface.
psl->Release();
}
}