windows-nt/Source/XPSP1/NT/shell/ext/cdfview/iconhand.cpp

1952 lines
49 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// iconhand.cpp
//
// The registered icon handler for cdf files. This handler returns icons for
// .cdf files.
//
// History:
//
// 3/21/97 edwardp Created.
//
////////////////////////////////////////////////////////////////////////////////
//
// Includes
//
#include "stdinc.h"
#include "resource.h"
#include "cdfidl.h"
#include "xmlutil.h"
#include "persist.h"
#include "iconhand.h"
#include "exticon.h"
#include "cdfview.h"
#include "tooltip.h"
#include "dll.h"
#include "chanapi.h"
#include <mluisupp.h>
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** MakeXMLErrorURL() ***
//
// Set the error based on the IXMLDocument * passed in
// Upon return CParseError will in an error state no matter what
// although it may not be in the CParseError::ERR_XML state
//
// This function returns the approriate URL to navigate to
// given the current error. Always changes *ppsz, but *ppsz maybe NULL
//
////////////////////////////////////////////////////////////////////////////////
#define CDFERROR_MAX_FOUND 100 // max char length for xml error found string
#define CDFERROR_MAX_EXPECTED 100 // max char length for xml error expected string
// format string for wsprintf of res:// ... URL
const LPTSTR CDFERROR_URL_FORMAT_TRAILER = TEXT("#%u#%ls#%ls");
// this is the number or extra chars (incl null) that CDFERROR_URL_FORMAT_TRAILER
// may have in comparison to the output buffer of wsprinf
const unsigned int CDFERROR_URL_FORMAT_EXTRA = 6;
// upper char # bound on result of building res URL
const unsigned CDFERROR_MAX_URL_LENGTH =
6 + // "res://"
MAX_PATH + // path to resource DLL
1 + // "/"
ARRAYSIZE(SZH_XMLERRORPAGE) + // "xmlerror.htm"
ARRAYSIZE(CDFERROR_URL_FORMAT_TRAILER) +
_INTEGRAL_MAX_BITS +
CDFERROR_MAX_EXPECTED +
CDFERROR_MAX_FOUND;
// upper char # bound on result of InternetCanonicalizeUrl
// with result from wsprintf with CDFERROR_URL_FORMAT
// for each funky char in the found and expected substrs, might be encoded as "%xx"
const unsigned CDFERROR_MAX_URL_LENGTH_ENCODED =
CDFERROR_MAX_URL_LENGTH + 2*(CDFERROR_MAX_EXPECTED + CDFERROR_MAX_FOUND);
HRESULT MakeXMLErrorURL( LPTSTR pszRet, DWORD dwRetLen, IXMLDocument *pXMLDoc )
{
IXMLError *pXMLError = NULL;
XML_ERROR xmle = { 0 };
HRESULT hr;
ASSERT(pXMLDoc);
hr =
( pXMLDoc ? pXMLDoc->QueryInterface(IID_IXMLError, (void **)&pXMLError) :
E_INVALIDARG );
if ( SUCCEEDED(hr) )
{
ASSERT(pXMLError);
hr = pXMLError->GetErrorInfo(&xmle);
if ( SUCCEEDED(hr) )
{
TCHAR szTemp[CDFERROR_MAX_URL_LENGTH];
WCHAR szExpected[CDFERROR_MAX_EXPECTED];
WCHAR szFound[CDFERROR_MAX_FOUND];
StrCpyNW( szExpected, xmle._pszExpected, ARRAYSIZE(szExpected) );
StrCpyNW( szFound, xmle._pszFound, ARRAYSIZE(szFound) );
// fill in the "res://<path>\cdfvwlc.dll" part of the res URL
hr = MLBuildResURLWrap(TEXT("cdfvwlc.dll"),
g_hinst,
ML_CROSSCODEPAGE,
SZH_XMLERRORPAGE,
szTemp,
ARRAYSIZE(szTemp),
TEXT("cdfview.dll"));
if (SUCCEEDED(hr))
{
int nCharsWritten;
int count;
nCharsWritten = lstrlen(szTemp);
count = wnsprintf(szTemp+nCharsWritten, ARRAYSIZE(szTemp)-nCharsWritten,
CDFERROR_URL_FORMAT_TRAILER, xmle._nLine, szExpected, szFound );
if ( count + CDFERROR_URL_FORMAT_EXTRA < ARRAYSIZE(CDFERROR_URL_FORMAT_TRAILER) )
{
// not all the chars were successfully written
hr = E_FAIL;
}
else
if ( !InternetCanonicalizeUrl( szTemp, pszRet, &dwRetLen, 0 ) )
hr = E_FAIL;
TraceMsg(TF_CDFPARSE, "Parse error string created: %s", pszRet );
}
SysFreeString(xmle._pszFound);
SysFreeString(xmle._pszExpected);
SysFreeString(xmle._pchBuf);
}
else
{
TraceMsg(TF_CDFPARSE, "Could not get IXMLError error info" );
}
pXMLError->Release();
}
else
{
TraceMsg(TF_CDFPARSE, "Could not get IXMLError" );
}
return hr;
}
//
// Constructor and destructor.
//
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::CIconHandler ***
//
// Constructor.
//
////////////////////////////////////////////////////////////////////////////////
CIconHandler::CIconHandler (
void
)
: m_cRef(1)
{
ASSERT(NULL == m_pIExtractIcon);
ASSERT(NULL == m_bstrImageURL);
ASSERT(NULL == m_bstrImageWideURL);
ASSERT(NULL == m_pszErrURL);
TraceMsg(TF_OBJECTS, "+ handler object");
DllAddRef();
return;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::~CIconHandler ***
//
// Destructor.
//
////////////////////////////////////////////////////////////////////////////////
CIconHandler::~CIconHandler (
void
)
{
ASSERT(0 == m_cRef);
if (m_pIExtractIcon)
m_pIExtractIcon->Release();
if (m_bstrImageURL)
SysFreeString(m_bstrImageURL);
if (m_bstrImageWideURL)
SysFreeString(m_bstrImageWideURL);
if (m_pcdfidl)
CDFIDL_Free(m_pcdfidl);
if (m_pszErrURL)
delete[] m_pszErrURL;
//
// Matching Release for the constructor Addref.
//
TraceMsg(TF_OBJECTS, "- handler object");
DllRelease();
return;
}
//
// IUnknown methods.
//
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::QueryInterface ***
//
// CIconHandler QI.
//
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CIconHandler::QueryInterface (
REFIID riid,
void **ppv
)
{
ASSERT(ppv);
HRESULT hr;
*ppv = NULL;
if (IID_IUnknown == riid || IID_IExtractIcon == riid)
{
*ppv = (IExtractIcon*)this;
}
#ifdef UNICODE
else if (IID_IExtractIconA == riid)
{
*ppv = (IExtractIconA*)this;
}
#endif
else if (IID_IPersistFile == riid || IID_IPersist == riid)
{
*ppv = (IPersistFile*)this;
}
else if (IID_IPersistFolder == riid)
{
*ppv = (IPersistFolder*)this;
}
else if (IID_IExtractImage == riid || IID_IExtractLogo == riid)
{
*ppv = (IExtractImage*)this;
}
else if (IID_IRunnableTask == riid)
{
*ppv = (IRunnableTask*)this;
}
if (*ppv)
{
((IUnknown*)*ppv)->AddRef();
hr = S_OK;
}
//
// REVIEW: QI on the following two objects doesn't come here.
//
else if (IID_IShellLink == riid
#ifdef UNICODE
|| IID_IShellLinkA == riid
#endif
)
{
if (!m_bCdfParsed)
ParseCdfShellLink();
if (m_pcdfidl)
{
hr = QueryInternetShortcut(m_pcdfidl, riid, ppv);
}
else
{
if ( m_pszErrURL && *m_pszErrURL)
{
hr = QueryInternetShortcut(m_pszErrURL, riid, ppv);
}
else
{
hr = E_FAIL;
}
}
}
else if (IID_IQueryInfo == riid)
{
hr = ParseCdfInfoTip(ppv);
}
else
{
hr = E_NOINTERFACE;
}
ASSERT((SUCCEEDED(hr) && *ppv) || (FAILED(hr) && NULL == *ppv));
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::AddRef ***
//
// CExtractIcon AddRef.
//
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG)
CIconHandler::AddRef (
void
)
{
ASSERT(m_cRef != 0);
ASSERT(m_cRef < (ULONG)-1);
return ++m_cRef;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::Release ***
//
// CIconHandler Release.
//
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG)
CIconHandler::Release (
void
)
{
ASSERT (m_cRef != 0);
ULONG cRef = --m_cRef;
if (0 == cRef)
delete this;
return cRef;
}
//
// IExtractIcon methods.
//
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::GetIconLocation ***
//
//
// Description:
// Returns a name index pair for the icon associated with this cdf item.
//
// Parameters:
// [In] uFlags - GIL_FORSHELL, GIL_OPENICON.
// [Out] szIconFile - The address of the buffer that receives the associated
// icon name. It can be a filename, but doesn't have to
// be.
// [In] cchMax - Size of the buffer that receives the icon location.
// [Out] piIndex - A pointer that receives the icon's index.
// [Out] pwFlags - A pointer the receives flags about the icon.
//
// Return:
// S_OK if an was found.
// S_FALSE if the shell should supply a default icon.
//
// Comments:
//
//
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CIconHandler::GetIconLocation(
UINT uFlags,
LPTSTR szIconFile,
UINT cchMax,
int *piIndex,
UINT *pwFlags
)
{
ASSERT(szIconFile);
ASSERT(piIndex);
ASSERT(pwFlags);
HRESULT hr;
TraceMsg(TF_CDFICON, "<IN > CIconHandler::GetIconLocation (Icon) tid:0x%x",
GetCurrentThreadId());
if (uFlags & GIL_ASYNC)
{
hr = E_PENDING;
}
else
{
hr = E_FAIL;
if ( IsDefaultChannel())
{
m_bstrImageURL = CPersist::ReadFromIni( TSTR_INI_ICON );
if ( m_bstrImageURL )
{
ASSERT( !m_pIExtractIcon );
m_pIExtractIcon = (IExtractIcon*)new CExtractIcon( m_bstrImageURL );
}
}
if (!m_pIExtractIcon && !m_bCdfParsed)
ParseCdfIcon();
if (m_pIExtractIcon)
{
hr = m_pIExtractIcon->GetIconLocation(uFlags, szIconFile, cchMax,
piIndex, pwFlags);
}
if (FAILED(hr) ||
(StrEql(szIconFile, g_szModuleName) &&
-IDI_CHANNEL == *piIndex) )
{
//
// Try and get the icon out of the desktop.ini file.
//
m_bstrImageURL = CPersist::ReadFromIni(TSTR_INI_ICON);
if (m_bstrImageURL)
{
BOOL bRemovePrefix =
(0 == StrCmpNIW(L"file://", m_bstrImageURL, 7));
if (SHUnicodeToTChar(
bRemovePrefix ? m_bstrImageURL + 7 : m_bstrImageURL,
szIconFile, cchMax))
{
LPTSTR pszExt = PathFindExtension(szIconFile);
if (*pszExt != TEXT('.') ||
0 != StrCmpI(pszExt, TSTR_ICO_EXT))
{
*piIndex = INDEX_IMAGE;
MungePath(szIconFile);
}
else
{
*piIndex = 0;
*pwFlags = 0;
}
hr = S_OK;
}
}
}
if (FAILED(hr))
{
//
// Try to return the default channel icon.
//
*pwFlags = 0;
StrCpyN(szIconFile, g_szModuleName, cchMax);
if (*szIconFile)
{
*piIndex = -IDI_CHANNEL;
hr = S_OK;
}
else
{
*piIndex = 0;
hr = S_FALSE; // The shell will use a default icon.
}
}
//
// If this a generated icon and it should contain a gleam prepend
// the string with a 'G'.
//
if (S_OK == hr && m_fDrawGleam)
{
TCHAR* pszBuffer = new TCHAR[cchMax];
if (m_pIExtractIcon)
{
CExtractIcon *pExtract = (CExtractIcon *)m_pIExtractIcon;
pExtract->SetGleam(m_fDrawGleam);
}
if (pszBuffer)
{
StrCpyN(pszBuffer, szIconFile, cchMax);
*szIconFile = TEXT('G');
cchMax--;
StrCpyN(szIconFile+1, pszBuffer, cchMax);
delete [] pszBuffer;
}
}
*pwFlags = (m_fDrawGleam || INDEX_IMAGE == *piIndex) ? GIL_NOTFILENAME :
0;
if (m_fDrawGleam)
*piIndex += GLEAM_OFFSET;
TraceMsg(TF_GLEAM, "%c Icon Location %s,%d", m_fDrawGleam ? '+' : '-',
SUCCEEDED(hr) ? szIconFile : TEXT("FAILED"), *piIndex);
ASSERT((S_OK == hr && *szIconFile) ||
(S_FALSE == hr && 0 == *szIconFile));
}
TraceMsg(TF_CDFICON, "<OUT> CIconHandler::GetIconLocation (Icon) %s",
szIconFile);
return hr;
}
#ifdef UNICODE
STDMETHODIMP
CIconHandler::GetIconLocation(
UINT uFlags,
LPSTR szIconFile,
UINT cchMax,
int *piIndex,
UINT *pwFlags
)
{
ASSERT(szIconFile);
ASSERT(piIndex);
ASSERT(pwFlags);
HRESULT hr;
TraceMsg(TF_CDFICON, "<IN > CIconHandler::GetIconLocationA (Icon) tid:0x%x",
GetCurrentThreadId());
WCHAR* pszIconFileW = new WCHAR[cchMax];
if (pszIconFileW == NULL)
return ERROR_OUTOFMEMORY;
hr = GetIconLocation(uFlags, pszIconFileW, cchMax, piIndex, pwFlags);
if (SUCCEEDED(hr))
SHUnicodeToAnsi(pszIconFileW, szIconFile, cchMax);
delete [] pszIconFileW;
return hr;
}
#endif
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::Extract ***
//
//
// Description:
// Return an icon given the name index pair returned from GetIconLocation.
//
// Parameters:
// [In] pszFile - A pointer to the name associated with the requested
// icon.
// [In] nIconIndex - An index associated with the requested icon.
// [Out] phiconLarge - Pointer to the variable that receives the handle of
// the large icon.
// [Out] phiconSmall - Pointer to the variable that receives the handle of
// the small icon.
// [Out] nIconSize - Value specifying the size, in pixels, of the icon
// required. The LOWORD and HIWORD specify the size of
// the large and small icons, respectively.
//
// Return:
// S_OK if the icon was extracted.
// S_FALSE if the shell should extract the icon assuming the name is a
// filename and the index is the icon index.
//
// Comments:
// The shell may cache the icon returned from this function.
//
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CIconHandler::Extract(
LPCTSTR pszFile,
UINT nIconIndex,
HICON *phiconLarge,
HICON *phiconSmall,
UINT nIconSize
)
{
HRESULT hr;
TraceMsg(TF_CDFICON, "<IN > CIconHandler::Extract (Icon) tid:0x%x",
GetCurrentThreadId());
DWORD dwType;
DWORD dwVal; // Bits per pixel
DWORD cbVal = sizeof(DWORD);
if ((SHGetValue(HKEY_CURRENT_USER, c_szHICKey, c_szHICVal, &dwType, &dwVal,
&cbVal) != ERROR_SUCCESS)
||
(REG_DWORD != dwType))
{
dwVal = 0;
}
// Convert bits per pixel to # colors
m_dwClrDepth = (dwVal == 16) ? 256 : 16;
if (m_fDrawGleam)
nIconIndex -= GLEAM_OFFSET;
if (m_pIExtractIcon)
{
hr = m_pIExtractIcon->Extract(pszFile, nIconIndex, phiconLarge,
phiconSmall, nIconSize);
//
// If an icon couldn't be extracted, try and display the default icon.
//
if (FAILED(hr))
{
hr = Priv_SHDefExtractIcon(g_szModuleName, -IDI_CHANNEL, 0,
phiconLarge, phiconSmall, nIconSize);
}
}
else
{
hr = S_FALSE;
}
TraceMsg(TF_GLEAM, "%c Icon Extract %s %s", m_fDrawGleam ? '+' : '-',
pszFile, (S_OK == hr) ? TEXT("SUCCEEDED") : TEXT("FAILED"));
TraceMsg(TF_CDFICON, "<OUT> CIconHandler::Extract (Icon) tid:0x%x",
GetCurrentThreadId());
return hr;
}
#ifdef UNICODE
STDMETHODIMP
CIconHandler::Extract(
LPCSTR pszFile,
UINT nIconIndex,
HICON *phiconLarge,
HICON *phiconSmall,
UINT nIconSize
)
{
HRESULT hr;
TraceMsg(TF_CDFICON, "<IN > CIconHandler::ExtractA (Icon) tid:0x%x",
GetCurrentThreadId());
int cch = lstrlenA(pszFile) + 1;
WCHAR* pszFileW = new WCHAR[cch];
if (pszFileW == NULL)
return ERROR_OUTOFMEMORY;
SHAnsiToUnicode(pszFile, pszFileW, cch);
hr = Extract(pszFileW, nIconIndex, phiconLarge, phiconSmall, nIconSize);
delete [] pszFileW;
return hr;
}
#endif
//
// IExtractImage methods.
//
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::GetLocation ***
//
//
// Description:
// Returns a string to associate with this files image.
//
// Parameters:
// [Out] pszPathBuffer - A buffer that receives this items string.
// [In] cch - The size of the buffer.
// [Out] pdwPriority - The priority of this item's image.
// [In/Out] pdwFlags - Flags associated with this call.
//
// Return:
// S_OK if a string is returned.
// E_FAIL otherwise.
//
// Comments:
// IExtractImage uses the returned value to share images accross multiple
// items. If three items in the same directory return "Default" all three
// would use the same image.
//
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CIconHandler::GetLocation(
LPWSTR pszPathBuffer,
DWORD cch,
DWORD* pdwPriority,
const SIZE * prgSize,
DWORD dwRecClrDepth,
DWORD* pdwFlags
)
{
LPWSTR pstrURL = NULL;
ASSERT(pszPathBuffer || 0 == cch);
ASSERT(pdwFlags);
HRESULT hr = E_FAIL;
TraceMsg(TF_CDFLOGO, "<IN > CIconHandler::GetIconLocation (Logo) tid:0x%x",
GetCurrentThreadId());
if ( !prgSize )
{
return E_INVALIDARG;
}
m_rgSize = *prgSize;
m_dwClrDepth = dwRecClrDepth;
if ( IsDefaultChannel() && !UseWideLogo(prgSize->cx))
{
// avoid having to partse the CDF if possible by
// pulling the entry from the desktop.ini file...
pstrURL = m_bstrImageURL = CPersist::ReadFromIni(TSTR_INI_LOGO);
}
if (pstrURL == NULL && !m_bCdfParsed)
ParseCdfImage(&m_bstrImageURL, &m_bstrImageWideURL);
pstrURL = (UseWideLogo(prgSize->cx) && m_bstrImageWideURL) ?
m_bstrImageWideURL :
m_bstrImageURL;
if (pstrURL)
{
ASSERT(0 != *m_bstrImageURL);
if (m_fDrawGleam && cch > 0)
{
*pszPathBuffer++ = L'G';
cch--;
}
if (StrCpyNW(pszPathBuffer, pstrURL, cch))
{
hr = S_OK;
}
else
{
if (m_bstrImageURL)
{
SysFreeString(m_bstrImageURL);
m_bstrImageURL = NULL;
}
if (m_bstrImageWideURL)
{
SysFreeString(m_bstrImageWideURL);
m_bstrImageWideURL = NULL;
}
}
}
if (FAILED(hr))
{
m_bstrImageURL = CPersist::ReadFromIni(TSTR_INI_LOGO);
m_bstrImageWideURL = CPersist::ReadFromIni(TSTR_INI_WIDELOGO);
pstrURL = (UseWideLogo(prgSize->cx) && m_bstrImageWideURL) ?
m_bstrImageWideURL :
m_bstrImageURL;
if (pstrURL)
{
if (m_fDrawGleam && cch > 0)
{
*pszPathBuffer++ = L'G';
cch--;
}
if (StrCpyNW(pszPathBuffer, pstrURL, cch))
hr = S_OK;
}
}
BOOL bAsync = *pdwFlags & IEIFLAG_ASYNC;
//
// REVIEW: Long URLs truncated in pszPathBuffer.
//
//TSTRToWideChar(m_szPath, pszPathBuffer, cch);
if (pdwPriority)
*pdwPriority = ITSAT_DEFAULT_PRIORITY; //0x10000; // Low priority since this could hit the net.
*pdwFlags = m_fDrawGleam ? IEIFLAG_GLEAM : 0;
TraceMsg(TF_GLEAM, "%c Logo Location %S", m_fDrawGleam ? '+' : '-',
SUCCEEDED(hr) ? pszPathBuffer : L"FAILED");
//
// REVIEW: Proper IEIFLAG_ASYNC handling.
//
TraceMsg(TF_CDFLOGO, "<OUT> CIconHandler::GetIconLocation (Logo) tid:0x%x",
GetCurrentThreadId());
return (SUCCEEDED(hr) && bAsync) ? E_PENDING : hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::Extract ***
//
//
// Description:
// Returns a hbitmap for use as a logo for this cdf file.
//
// Parameters:
// [Out] phBmp - The returned bitmap.
//
// Return:
// S_OK if an image was extracted.
// E_FAIL if an image couldn't be extracted.
//
// Comments:
// The returned bitmap is stretched to pSize.
//
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CIconHandler::Extract(
HBITMAP * phBmp
)
{
ASSERT(phBmp);
HRESULT hr = E_FAIL;
TraceMsg(TF_CDFLOGO, "<IN > CIconHandler::Extract (Logo) tid:0x%x",
GetCurrentThreadId());
if (m_bstrImageURL)
{
hr = ExtractCustomImage(&m_rgSize, phBmp);
}
// Let the extractor build a default logo.
//if (FAILED(hr))
// hr = ExtractDefaultImage(pSize, phBmp);
TraceMsg(TF_CDFLOGO, "<OUT> CIconHandler::Extract (Logo) tid:0x%x",
GetCurrentThreadId());
return hr;
}
//
// Helper functions.
//
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::IsDefaultChannel***
//
//
// Description:
// Checks to see if the channel we are dealing with is a default one.
//
// Parameters:
// None.
//
// Return:
// TRUE if it is a default channel.
// FALSE otherwise.
//
// Comments:
// This is used in an attempt to avoid parsing the CDF if the only
// information we need is already in the desktop.ini file.
//
////////////////////////////////////////////////////////////////////////////////
BOOL CIconHandler::IsDefaultChannel()
{
BOOL fDefault = FALSE;
// get the desktop.ini path and see if it points to the systemdir\web
BSTR pstrURL = CPersist::ReadFromIni( TSTR_INI_URL );
if ( pstrURL )
{
fDefault = Channel_CheckURLMapping( pstrURL );
SysFreeString( pstrURL );
}
return fDefault;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::ParseCdfIcon ***
//
//
// Description:
// Parses the cdf file associated with this folder.
//
// Parameters:
// None.
//
// Return:
// S_OK if the cdf file was found and successfully parsed.
// E_FAIL otherwise.
//
// Comments:
// This parse function gets the root channel item and uses it to create
// a CExtractIcon object. The CExtractIcon object is later called to get
// the icon location and extract the icon.
//
////////////////////////////////////////////////////////////////////////////////
HRESULT
CIconHandler::ParseCdfIcon(
void
)
{
HRESULT hr;
//
// Parse the file and get back the root channel element.
//
IXMLDocument* pIXMLDocument = NULL;
TraceMsg(TF_CDFICON, "Extracting icon URL for %s",
PathFindFileName(m_szPath));
TraceMsg(TF_CDFPARSE, "Extracting icon URL for %s",
PathFindFileName(m_szPath));
hr = CPersist::ParseCdf(NULL, &pIXMLDocument, PARSE_LOCAL);
if (SUCCEEDED(hr))
{
ASSERT(pIXMLDocument);
m_fDrawGleam = CPersist::IsUnreadCdf();
IXMLElement* pIXMLElement;
LONG nIndex;
hr = XML_GetFirstChannelElement(pIXMLDocument, &pIXMLElement, &nIndex);
if (SUCCEEDED(hr))
{
ASSERT(pIXMLElement);
PCDFITEMIDLIST pcdfidl = CDFIDL_CreateFromXMLElement(pIXMLElement,
nIndex);
if (pcdfidl)
{
//
// Create a CExtractIcon object for the root channel.
//
m_pIExtractIcon = (IExtractIcon*)new CExtractIcon(pcdfidl,
pIXMLElement);
hr = m_pIExtractIcon ? S_OK : E_OUTOFMEMORY;
CDFIDL_Free(pcdfidl);
}
pIXMLElement->Release();
}
}
if (pIXMLDocument)
pIXMLDocument->Release();
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::ParseCdfImage ***
//
//
// Description:
// Parses the cdf file associated with this folder.
//
// Parameters:
// [In] pbstrURL - A pointer that receives the URL for the image associated
// with the root channel.
//
// Return:
// S_OK if the URL was found.
// E_FAIL if the URL wasn't found.
//
// Comments:
// This function parses the cdf file and returns an URL to the image
// associated with this cdf file.
//
////////////////////////////////////////////////////////////////////////////////
HRESULT
CIconHandler::ParseCdfImage(
BSTR* pbstrURL,
BSTR* pbstrWURL
)
{
ASSERT(pbstrURL);
HRESULT hr;
*pbstrURL = NULL;
IXMLDocument* pIXMLDocument = NULL;
//
// Parse the file.
//
TraceMsg(TF_CDFPARSE, "Extracting logo URL for %s",
PathFindFileName(m_szPath));
TraceMsg(TF_CDFLOGO, "Extracting logo URL for %s",
PathFindFileName(m_szPath));
hr = CPersist::ParseCdf(NULL, &pIXMLDocument, PARSE_LOCAL);
if (SUCCEEDED(hr))
{
ASSERT(pIXMLDocument);
m_fDrawGleam = CPersist::IsUnreadCdf();
//
// Get the first channel element.
//
IXMLElement* pIXMLElement;
LONG nIndex;
hr = XML_GetFirstChannelElement(pIXMLDocument, &pIXMLElement, &nIndex);
if (SUCCEEDED(hr))
{
ASSERT(pIXMLElement);
//
// Get the logo URL of the first channel element.
//
*pbstrURL = XML_GetAttribute(pIXMLElement, XML_LOGO);
hr = *pbstrURL ? S_OK : E_FAIL;
*pbstrWURL = XML_GetAttribute(pIXMLElement, XML_LOGO_WIDE);
pIXMLElement->Release();
}
}
if (pIXMLDocument)
pIXMLDocument->Release();
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** Name ***
//
//
// Description:
//
//
// Parameters:
//
//
// Return:
//
//
// Comments:
//
//
////////////////////////////////////////////////////////////////////////////////
HRESULT
CIconHandler::ParseCdfShellLink(
void
)
{
//
// Parse the file and get back the root channel element.
//
IXMLDocument* pIXMLDocument = NULL;
TraceMsg(TF_CDFPARSE, "Extracting IShellLink for %s",
PathFindFileName(m_szPath));
HRESULT hr = CPersist::ParseCdf(NULL, &pIXMLDocument,
PARSE_LOCAL | PARSE_REMOVEGLEAM);
if (SUCCEEDED(hr))
{
ASSERT(pIXMLDocument);
IXMLElement* pIXMLElement;
LONG nIndex;
hr = XML_GetFirstChannelElement(pIXMLDocument, &pIXMLElement, &nIndex);
if (SUCCEEDED(hr))
{
ASSERT(pIXMLElement);
m_pcdfidl = CDFIDL_CreateFromXMLElement(pIXMLElement,
nIndex);
pIXMLElement->Release();
}
}
else if (OLE_E_NOCACHE == hr)
{
//
// If it wasn't in the cache pass the url of the cdf so it gets reloaded.
//
BSTR bstrURL = CPersist::ReadFromIni(TSTR_INI_URL);
if (bstrURL)
{
if (InternetGetConnectedState(NULL, 0))
{
int cch = StrLenW(bstrURL) + 1;
m_pszErrURL = new TCHAR[cch];
if (m_pszErrURL)
{
if (!SHUnicodeToTChar(bstrURL, m_pszErrURL, cch))
{
delete []m_pszErrURL;
m_pszErrURL = NULL;
}
}
}
else
{
TCHAR szResURL[INTERNET_MAX_URL_LENGTH];
ASSERT(NULL == m_pszErrURL);
if (SUCCEEDED(MLBuildResURLWrap(TEXT("cdfvwlc.dll"),
g_hinst,
ML_CROSSCODEPAGE,
TEXT("cacheerr.htm#"),
szResURL,
ARRAYSIZE(szResURL),
TEXT("cdfview.dll"))))
{
int cchPrefix = StrLen(szResURL);
int cch = StrLenW(bstrURL) + cchPrefix + 1;
m_pszErrURL = new TCHAR[cch];
if (m_pszErrURL &&
(!StrCpy(m_pszErrURL, szResURL) ||
!SHUnicodeToTChar(bstrURL, m_pszErrURL + cchPrefix, cch - cchPrefix)))
{
delete []m_pszErrURL;
m_pszErrURL = NULL;
}
}
}
SysFreeString(bstrURL);
}
}
else
{
DWORD dwSize = sizeof(TCHAR[CDFERROR_MAX_URL_LENGTH_ENCODED]); // count in bytes
if (NULL==m_pszErrURL)
m_pszErrURL = new TCHAR[CDFERROR_MAX_URL_LENGTH_ENCODED];
if (m_pszErrURL)
{
if (pIXMLDocument)
{
if ( FAILED(MakeXMLErrorURL(m_pszErrURL, dwSize / sizeof(TCHAR), pIXMLDocument)) )
{
delete[] m_pszErrURL;
m_pszErrURL = NULL;
}
}
}
}
if (pIXMLDocument)
pIXMLDocument->Release();
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** Name ***
//
//
// Description:
//
//
// Parameters:
//
//
// Return:
//
//
// Comments:
//
//
////////////////////////////////////////////////////////////////////////////////
HRESULT
CIconHandler::ParseCdfInfoTip(
void** ppv
)
{
ASSERT(ppv);
HRESULT hr;
//
// Parse the file and get back the root channel element.
//
IXMLDocument* pIXMLDocument = NULL;
TraceMsg(TF_CDFPARSE, "Extracting IQueryInfo for %s",
PathFindFileName(m_szPath));
hr = CPersist::ParseCdf(NULL, &pIXMLDocument, PARSE_LOCAL);
if (SUCCEEDED(hr))
{
ASSERT(pIXMLDocument);
IXMLElement* pIXMLElement;
LONG nIndex;
hr = XML_GetFirstChannelElement(pIXMLDocument, &pIXMLElement, &nIndex);
if (SUCCEEDED(hr))
{
ASSERT(pIXMLElement);
*ppv = (IQueryInfo*)new CQueryInfo(pIXMLElement, XML_IsFolder(pIXMLElement));
hr = *ppv ? S_OK : E_FAIL;
pIXMLElement->Release();
}
}
else
{
//
// Even if the cdf isn't in the cache, return a IQueryInfo interface.
// The caller can stil call GetInfoFlags.
//
*ppv = (IQueryInfo*)new CQueryInfo(NULL, FALSE);
hr = *ppv ? S_OK : E_FAIL;
}
if (pIXMLDocument)
pIXMLDocument->Release();
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::ExtractCustomImage ***
//
//
// Description:
// Extract an image from an URL.
//
// Parameters:
// [In] pSize - The requested size of the image.
// [Out] phBmp - The returned bitmap.
//
// Return:
// S_OK if the bitmap was successfully extracted.
// E_FAIL otherwise.
//
// Comments:
// The URL of the image is in m_bstrImageURL and was set when the cdf
// file was parsed.
//
////////////////////////////////////////////////////////////////////////////////
HRESULT
CIconHandler::ExtractCustomImage(
const SIZE* pSize,
HBITMAP* phBmp
)
{
ASSERT(pSize);
ASSERT(phBmp);
HRESULT hr;
IImgCtx* pIImgCtx;
hr = CoCreateInstance(CLSID_IImgCtx, NULL, CLSCTX_INPROC_SERVER,
IID_IImgCtx, (void**)&pIImgCtx);
BOOL bCoInit = FALSE;
if ((CO_E_NOTINITIALIZED == hr || REGDB_E_IIDNOTREG == hr) &&
SUCCEEDED(CoInitialize(NULL)))
{
bCoInit = TRUE;
hr = CoCreateInstance(CLSID_IImgCtx, NULL, CLSCTX_INPROC_SERVER,
IID_IImgCtx, (void**)&pIImgCtx);
}
if (SUCCEEDED(hr))
{
ASSERT(pIImgCtx);
hr = SynchronousDownload(pIImgCtx,
(UseWideLogo(pSize->cx) && m_bstrImageWideURL) ?
m_bstrImageWideURL :
m_bstrImageURL);
//
// If the load of the wide logo failed try and use the regular logo.
//
if (FAILED(hr) && UseWideLogo(pSize->cx) && m_bstrImageWideURL &&
m_bstrImageURL)
{
hr = SynchronousDownload(pIImgCtx, m_bstrImageURL);
SysFreeString(m_bstrImageWideURL);
m_bstrImageWideURL = NULL;
}
if (SUCCEEDED(hr))
{
hr = GetBitmap(pIImgCtx, pSize, phBmp);
if (FAILED(hr))
*phBmp = NULL;
}
pIImgCtx->Release();
}
if (bCoInit)
CoUninitialize();
ASSERT((SUCCEEDED(hr) && *phBmp) || (FAILED(hr) && NULL == *phBmp));
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::ExtractDefaultImage ***
//
//
// Description:
// Returns the default channel bitmap.
//
// [In] pSize - The requested size of the image.
// [Out] phBmp - The returned bitmap.
//
// Return:
// S_OK if the bitmap was successfully extracted.
// E_FAIL otherwise.
//
// Comments:
// If a cdf doesn't specify a logo image or the logo image couldn't be
// downloaded a default image is used.
//
////////////////////////////////////////////////////////////////////////////////
/*HRESULT
CIconHandler::ExtractDefaultImage(
const SIZE* pSize,
HBITMAP* phBmp
)
{
ASSERT(pSize);
ASSERT(phBmp);
HRESULT hr;
hr = GetBitmap(NULL, pSize, phBmp);
if (FAILED(hr))
*phBmp = NULL;
ASSERT((SUCCEEDED(hr) && *phBmp) || (FAILED(hr) && NULL == *phBmp));
return hr;
}*/
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::GetBitmap ***
//
//
// Description:
// Gets the requested bitmap
//
// Parameters:
// [In] pIImgCtx - The ImgCtx of the image. NULL if the default image is
// to be returned.
// [In] pSize - The requested size of the image.
// [Out] phBmp - A pointer that receives the returned image.
//
// Return:
// S_OK if the image was extracted.
// E_FAIL otherwise.
//
// Comments:
// This function conatins code that is shared by the custom image extractor
// and the default image extractor. The pIImhCtx parameter is used as a
// flag indicating which image - default or custom - is to be extracted.
//
////////////////////////////////////////////////////////////////////////////////
HRESULT
CIconHandler::GetBitmap(
IImgCtx* pIImgCtx,
const SIZE* pSize,
HBITMAP* phBmp
)
{
ASSERT(pSize);
ASSERT(phBmp);
HRESULT hr = E_FAIL;
//
// REVIEW: Pallete use for 8bpp DCs?
//
HDC hdcScreen = GetDC(NULL);
if (hdcScreen)
{
HDC hdcDst = CreateCompatibleDC(NULL);
if (hdcDst)
{
LPVOID lpBits;
struct {
BITMAPINFOHEADER bi;
DWORD ct[256];
} dib;
dib.bi.biSize = sizeof(BITMAPINFOHEADER);
dib.bi.biWidth = pSize->cx;
dib.bi.biHeight = pSize->cy;
dib.bi.biPlanes = 1;
dib.bi.biBitCount = (WORD) m_dwClrDepth;
dib.bi.biCompression = BI_RGB;
dib.bi.biSizeImage = 0;
dib.bi.biXPelsPerMeter = 0;
dib.bi.biYPelsPerMeter = 0;
dib.bi.biClrUsed = ( m_dwClrDepth <= 8 ) ? (1 << m_dwClrDepth) : 0;
dib.bi.biClrImportant = 0;
if ( m_dwClrDepth <= 8 )
{
HPALETTE hpal = NULL;
// need to get the right palette....
hr = pIImgCtx->GetPalette( & hpal );
if ( SUCCEEDED( hr ) && hpal )
{
GetPaletteEntries(hpal, 0, 256, (LPPALETTEENTRY)&dib.ct[0]);
for (int i = 0; i < (int)dib.bi.biClrUsed; i ++)
dib.ct[i] = RGB(GetBValue(dib.ct[i]),GetGValue(dib.ct[i]),GetRValue(dib.ct[i]));
}
}
*phBmp = CreateDIBSection(hdcDst, (LPBITMAPINFO)&dib, DIB_RGB_COLORS, &lpBits, NULL, 0);
HBITMAP hOld = (HBITMAP) SelectObject( hdcDst, *phBmp );
if (*phBmp && hOld)
{
RECT rc;
rc.top = rc.left = 0;
rc.bottom = pSize->cy;
rc.right = pSize->cx;
// black background...
HBRUSH hbr = (HBRUSH) GetStockObject( BLACK_BRUSH );
FillRect( hdcDst, &rc, hbr );
DeleteObject( hbr );
if (pIImgCtx)
{
hr = StretchBltCustomImage(pIImgCtx, pSize, hdcDst);
}
else
{
hr = E_FAIL; //StretchBltDefaultImage(pSize, hdcDst);
}
SelectObject( hdcDst, hOld );
}
DeleteDC(hdcDst);
}
ReleaseDC(NULL, hdcScreen);
}
ASSERT((SUCCEEDED(hr) && *phBmp) || FAILED(hr));
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::StretchBltCustomImage ***
//
//
// Description:
// Stretches the image associated with IImgCtx to the given size and places
// the result in the given DC.
//
// Parameters:
// [In] pIImgCtx - The image context for the image.
// [In] pSize - The size of the resultant image.
// [In/Out] hdcDst - The destination DC of the stretch blt.
//
// Return:
// S_OK if the image was successfully resized into the destination DC.
// E_FAIL otherwise.
//
// Comments:
// The destination DC already a bitmap of pSize selected into it.
//
////////////////////////////////////////////////////////////////////////////////
HRESULT
CIconHandler::StretchBltCustomImage(
IImgCtx* pIImgCtx,
const SIZE* pSize,
HDC hdcDst
)
{
ASSERT(pIImgCtx);
ASSERT(hdcDst);
HRESULT hr;
SIZE sz;
ULONG fState;
hr = pIImgCtx->GetStateInfo(&fState, &sz, FALSE);
if (SUCCEEDED(hr))
{
HPALETTE hpal = NULL;
HPALETTE hpalOld;
hr = pIImgCtx->GetPalette( &hpal );
if (hpal)
{
hpalOld = SelectPalette( hdcDst, hpal, TRUE );
RealizePalette( hdcDst );
}
if (UseWideLogo(pSize->cx) && NULL == m_bstrImageWideURL)
{
hr = pIImgCtx->StretchBlt(hdcDst, 0, 0, LOGO_WIDTH, pSize->cy, 0, 0,
sz.cx, sz.cy, SRCCOPY);
if (SUCCEEDED(hr))
{
//
// Color fill the logo.
//
COLORREF clr = GetPixel(hdcDst, 0, 0);
if (m_dwClrDepth <= 8)
clr = PALETTEINDEX(GetNearestPaletteIndex(hpal, clr));
HBRUSH hbr = CreateSolidBrush(clr);
if (hbr)
{
RECT rc;
rc.top = 0;
rc.bottom = pSize->cy;
rc.left = LOGO_WIDTH;
rc.right = pSize->cx;
FillRect(hdcDst, &rc, hbr);
DeleteObject(hbr);
}
}
}
else
{
hr = pIImgCtx->StretchBlt(hdcDst, 0, 0, pSize->cx, pSize->cy, 0, 0,
sz.cx, sz.cy, SRCCOPY);
}
if (SUCCEEDED(hr) && m_fDrawGleam)
DrawGleam(hdcDst);
if ( hpal )
{
SelectPalette( hdcDst, hpalOld, TRUE );
RealizePalette( hdcDst );
}
}
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::StretchBltDefaultImage ***
//
//
// Description:
// Stretches the deafult channel image to fit the requested size.
//
// Parameters:
// [In] pSize - The requested size of the image.
// [In/Out] hdcDest - The destination DC for the resized image.
//
// Return:
// S_OK if the image is successfully resized into the destination DC.
// E_FAIL otherwise.
//
// Comments:
// This function creates a source DC, copies the deafult bitmap into the
// the source DC, then strch blts the source DC into the destination DC.
//
////////////////////////////////////////////////////////////////////////////////
/*HRESULT
CIconHandler::StretchBltDefaultImage(
const SIZE* pSize,
HDC hdcDst
)
{
ASSERT(hdcDst);
HRESULT hr = E_FAIL;
HBITMAP hBmp = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_DEFAULT));
if (hBmp)
{
HDC hdcSrc = CreateCompatibleDC(NULL);
if (hdcSrc && SelectObject(hdcSrc, hBmp))
{
BITMAP bmp;
if (GetObject(hBmp, sizeof(BITMAP), (void*)&bmp))
{
if (StretchBlt(hdcDst, 0, 0, pSize->cx, pSize->cy,
hdcSrc, 0, 0, bmp.bmWidth, bmp.bmHeight,
SRCCOPY))
{
hr = S_OK;
}
}
DeleteDC(hdcSrc);
}
DeleteObject(hBmp);
}
return hr;
}*/
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::DrawGleam ***
//
//
// Description:
//
// Parameters:
//
// Return:
//
// Comments:
//
////////////////////////////////////////////////////////////////////////////////
HRESULT
CIconHandler::DrawGleam(
HDC hdcDst
)
{
ASSERT(hdcDst)
HRESULT hr = E_FAIL;
HICON hGleam = (HICON)LoadImage(g_hinst, TEXT("LOGOGLEAM"),
IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
if (hGleam)
{
if (DrawIcon(hdcDst, 1, 1, hGleam))
hr = S_OK;
DestroyIcon(hGleam);
}
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::SynchronousDownload ***
//
//
// Description:
// Synchronously downloads the image associated with the image context.
//
// Parameters:
// [In] pIImgCtx - A pointer to the image context.
//
// Return:
// S_OK if the image was successfully downloaded.
// E_FAIL if the image wasn't downloaded.
//
// Comments:
// The image context object doesn't directly support synchronous download.
// Here a message loop is used to make sure ulrmon keeps geeting messages
// and the download progresses.
//
////////////////////////////////////////////////////////////////////////////////
HRESULT
CIconHandler::SynchronousDownload(
IImgCtx* pIImgCtx,
LPCWSTR pwszURL
)
{
ASSERT(pIImgCtx);
HRESULT hr;
TCHAR szLocalFile[MAX_PATH];
TCHAR szURL[INTERNET_MAX_URL_LENGTH];
SHUnicodeToTChar(pwszURL, szURL, ARRAYSIZE(szURL));
hr = URLGetLocalFileName(szURL, szLocalFile, ARRAYSIZE(szLocalFile), NULL);
TraceMsg(TF_GLEAM, "%c Logo Extract %s", m_fDrawGleam ? '+' : '-',
szLocalFile);
if (SUCCEEDED(hr))
{
TraceMsg(TF_CDFLOGO, "[URLGetLocalFileName %s]", szLocalFile);
#ifdef UNIX
unixEnsureFileScheme(szLocalFile);
#endif /* UNIX */
WCHAR szLocalFileW[MAX_PATH];
SHTCharToUnicode(szLocalFile, szLocalFileW, ARRAYSIZE(szLocalFileW));
hr = pIImgCtx->Load(szLocalFileW, 0);
if (SUCCEEDED(hr))
{
ULONG fState;
SIZE sz;
pIImgCtx->GetStateInfo(&fState, &sz, TRUE);
if (!(fState & (IMGLOAD_COMPLETE | IMGLOAD_ERROR)))
{
m_fDone = FALSE;
hr = pIImgCtx->SetCallback(ImgCtx_Callback, &m_fDone);
if (SUCCEEDED(hr))
{
hr = pIImgCtx->SelectChanges(IMGCHG_COMPLETE, 0, TRUE);
if (SUCCEEDED(hr))
{
MSG msg;
BOOL fMsg;
// HACK: restrict the message pump to those messages we know that URLMON and
// HACK: the imageCtx stuff needs, otherwise we will be pumping messages for
// HACK: windows we shouldn't be pumping right now...
while(!m_fDone )
{
fMsg = PeekMessage(&msg, NULL, WM_USER + 1, WM_USER + 4, PM_REMOVE );
if (!fMsg)
{
fMsg = PeekMessage( &msg, NULL, WM_APP + 2, WM_APP + 2, PM_REMOVE );
}
if (!fMsg)
{
// go to sleep until we get a new message....
WaitMessage();
continue;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
pIImgCtx->Disconnect();
}
hr = pIImgCtx->GetStateInfo(&fState, &sz, TRUE);
if (SUCCEEDED(hr))
hr = (fState & IMGLOAD_COMPLETE) ? S_OK : E_FAIL;
}
}
else
{
TraceMsg(TF_CDFLOGO, "[URLGetLocalFileName %s FAILED]",szURL);
}
TraceMsg(TF_CDFPARSE, "[IImgCtx downloading logo %s %s]", szLocalFile,
SUCCEEDED(hr) ? TEXT("SUCCEEDED") : TEXT("FAILED"));
TraceMsg(TF_CDFLOGO, "[IImgCtx downloading logo %s %s]", szLocalFile,
SUCCEEDED(hr) ? TEXT("SUCCEEDED") : TEXT("FAILED"));
return hr;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::Run ***
//
// IRunnableTask method.
//
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CIconHandler::Run(
void
)
{
return E_NOTIMPL;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::Kill ***
//
// IRunnableTask method.
//
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CIconHandler::Kill(
BOOL fWait
)
{
m_fDone = TRUE;
return S_OK;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::Suspend ***
//
// IRunnableTask method.
//
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CIconHandler::Suspend(
void
)
{
return E_NOTIMPL;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::Resume ***
//
// IRunnableTask method.
//
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CIconHandler::Resume(
void
)
{
return E_NOTIMPL;
}
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
//
// *** CIconHandler::IsRunning ***
//
// IRunnableTask method.
//
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG)
CIconHandler::IsRunning(
void
)
{
return E_NOTIMPL;
}