|
|
#include "general.h"
#include "folder.h"
#include "utils.h"
#include <mluisupp.h>
#define CPP_FUNCTIONS
#include <crtfree.h>
// string displayed to represent missing data
TCHAR g_szUnknownData[64];
int CompareVersion(LPCTSTR lpszVersion1, LPCTSTR lpszVersion2);
///////////////////////////////////////////////////////////////////////////////
// IShellFolder methods
CControlFolder::CControlFolder() { DebugMsg(DM_TRACE,TEXT("cf - CControlFolder() called.")); m_cRef = 1; DllAddRef();
// initialize g_szUnknownData, a string used to represent missing data
if (g_szUnknownData[0] == 0) MLLoadString(IDS_UNKNOWNDATA, g_szUnknownData, ARRAYSIZE(g_szUnknownData)); }
CControlFolder::~CControlFolder() { Assert(m_cRef == 0); // should always have zero
DebugMsg(DM_TRACE, TEXT("cf - ~CControlFolder() called."));
if (m_pidl) ILFree(m_pidl);
DllRelease(); }
STDAPI ControlFolder_CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppvOut) { *ppvOut = NULL; // null the out param
if (punkOuter) return CLASS_E_NOAGGREGATION;
CControlFolder *pCFolder = new CControlFolder; if (!pCFolder) return E_OUTOFMEMORY;
HRESULT hr = pCFolder->QueryInterface(riid, ppvOut); pCFolder->Release();
return hr; }
HRESULT CControlFolder::QueryInterface(REFIID iid, void **ppv) { DebugMsg(DM_TRACE, TEXT("cf - QueryInterface() called.")); if ((iid == IID_IUnknown) || (iid == IID_IShellFolder)) { *ppv = (void *)(IShellFolder*)this; } else if ((iid == IID_IPersistFolder) || (iid == IID_IPersist)) { *ppv = (void *)(IPersistFolder*)this; } else if (iid == IID_IPersistFolder2) { *ppv = (void *)(IPersistFolder2*)this; } else if (iid == IID_IContextMenu) { *ppv = (void *)(IContextMenu*)this; } else if (iid == IID_IShellView) { // this is a total hack... return our view object from this folder
//
// the desktop.ini file for "Temporary Internet Files" has UICLSID={guid of this object}
// this lets us implment only ths IShellView for this folder, leaving the IShellFolder
// to the default file system. this enables operations on the pidls that are stored in
// this folder that would otherwise faile since our IShellFolder is not as complete
// as the default (this is the same thing the font folder does).
//
// to support this with defview we would either have to do a complete wrapper object
// for the view implemenation, or add this hack that hands out the view object, this
// assumes we know the order of calls that the shell makes to create this object
// and get the IShellView implementation
//
return ControlFolderView_CreateInstance(this, m_pidl, ppv); } else { *ppv = NULL; // null the out param
return E_NOINTERFACE; }
AddRef(); return S_OK; }
ULONG CControlFolder::AddRef() { return ++m_cRef; }
ULONG CControlFolder::Release() { if (--m_cRef) return m_cRef;
delete this; return 0; }
HRESULT CControlFolder::ParseDisplayName( HWND hwndOwner, LPBC pbcReserved, LPOLESTR lpszDisplayName, ULONG *pchEaten, LPITEMIDLIST *ppidl, ULONG *pdwAttributes) { DebugMsg(DM_TRACE, TEXT("cf - sf - ParseDisplayName() called.")); *ppidl = NULL; // null the out param
return E_FAIL; }
HRESULT CControlFolder::EnumObjects( HWND hwndOwner, DWORD grfFlags, LPENUMIDLIST *ppenumIDList) { DebugMsg(DM_TRACE, TEXT("cf - sf - EnumObjects() called."));
// Cannot filter on grfFlags yet - Corel Gallery expects to receive
// an empty enumerator.
return CControlFolderEnum_CreateInstance(m_pidl, grfFlags, ppenumIDList); }
HRESULT CControlFolder::BindToObject( LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, void **ppvOut) { DebugMsg(DM_TRACE, TEXT("cf - sf - BindToObject() called.")); *ppvOut = NULL; // null the out param
return E_FAIL; }
HRESULT CControlFolder::BindToStorage( LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, void **ppv) { DebugMsg(DM_TRACE, TEXT("cf - sf - BindToStorage() called.")); *ppv = NULL; // null the out param
return E_NOTIMPL; }
HRESULT CControlFolder::CompareIDs( LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { DebugMsg(DM_TRACE, TEXT("cf - sf - CompareIDs() called."));
int iRet; LPCONTROLPIDL pcpidl1 = (LPCONTROLPIDL)pidl1; LPCONTROLPIDL pcpidl2 = (LPCONTROLPIDL)pidl2; LPCSTR lpszStr[2] = {NULL, NULL};
if (pcpidl1 == NULL || pcpidl2 == NULL) return E_INVALIDARG; switch (lParam) { case SI_CONTROL: iRet = lstrcmpi( GetStringInfo(pcpidl1, SI_CONTROL), GetStringInfo(pcpidl2, SI_CONTROL)); break;
case SI_VERSION: lpszStr[0] = GetStringInfo(pcpidl1, SI_VERSION); lpszStr[1] = GetStringInfo(pcpidl2, SI_VERSION); if (lstrcmp(lpszStr[0], g_szUnknownData) == 0) iRet = -1; else if (lstrcmp(lpszStr[1], g_szUnknownData) == 0) iRet = 1; else iRet = CompareVersion(lpszStr[0], lpszStr[1]); break;
case SI_CREATION: case SI_LASTACCESS: { FILETIME time[2]; GetTimeInfo(pcpidl1, (int)lParam, &(time[0])); GetTimeInfo(pcpidl2, (int)lParam, &(time[1])); iRet = CompareFileTime(&(time[0]), &(time[1])); } break;
case SI_STATUS: iRet = GetStatus(pcpidl1) - GetStatus(pcpidl2); break; case SI_TOTALSIZE: { DWORD dwSize1 = GetSizeSaved((LPCONTROLPIDL)pidl1); DWORD dwSize2 = GetSizeSaved((LPCONTROLPIDL)pidl2); iRet = (dwSize1 == dwSize2 ? 0 : (dwSize1 > dwSize2 ? 1 : -1)); } break;
default: iRet = -1; }
return ResultFromShort((SHORT)iRet); }
HRESULT CControlFolder::CreateViewObject( HWND hwndOwner, REFIID riid, void **ppvOut) { HRESULT hres;
DebugMsg(DM_TRACE, TEXT("cf - sf - CreateViewObject() called."));
if (riid == IID_IShellView) { hres = ControlFolderView_CreateInstance(this, m_pidl, ppvOut); } else if (riid == IID_IContextMenu) { hres = ControlFolder_CreateInstance(NULL, riid, ppvOut); } else { *ppvOut = NULL; // null the out param
hres = E_NOINTERFACE; } return hres; }
HRESULT CControlFolder::GetAttributesOf(UINT cidl, LPCITEMIDLIST *apidl, ULONG *prgfInOut) { // Should we initialize this for each item in here? In other words,
// if cidl > 1, then we should initialize each entry in the prgInOut array
Assert(cidl == 1); *prgfInOut = SFGAO_CANCOPY | SFGAO_HASPROPSHEET | SFGAO_CANMOVE | SFGAO_CANDELETE; return NOERROR; }
HRESULT CControlFolder::GetUIObjectOf( HWND hwndOwner, UINT cidl, LPCITEMIDLIST *apidl, REFIID riid, UINT *prgfInOut, void **ppvOut) { HRESULT hres;
if ((riid == IID_IDataObject) || (riid == IID_IExtractIcon) || (riid == IID_IContextMenu)) { hres = CControlItem_CreateInstance(this, cidl, apidl, riid, ppvOut); } else { *ppvOut = NULL; // null the out param
hres = E_FAIL; } return hres; }
HRESULT CControlFolder::GetDisplayNameOf( LPCITEMIDLIST pidl, DWORD uFlags, LPSTRRET lpName) { DebugMsg(DM_TRACE, TEXT("cf - sf - GetDisplayNameOf() called."));
if (pidl) { lpName->uType = STRRET_CSTR;
// for the history, we'll use the title if we have one, otherwise we'll use
// the url filename.
if (uFlags & SHGDN_FORPARSING) lstrcpyn( lpName->cStr, GetStringInfo((LPCONTROLPIDL)pidl, SI_LOCATION), ARRAYSIZE(lpName->cStr)); else lstrcpyn( lpName->cStr, GetStringInfo((LPCONTROLPIDL)pidl, SI_CONTROL), ARRAYSIZE(lpName->cStr));
return NOERROR; } else { return E_INVALIDARG; } }
HRESULT CControlFolder::SetNameOf( HWND hwndOwner, LPCITEMIDLIST pidl, LPCOLESTR lpszName, DWORD uFlags, LPITEMIDLIST *ppidlOut) { DebugMsg(DM_TRACE, TEXT("cf - sf - SetNameOf() called.")); *ppidlOut = NULL; // null the out param
return E_FAIL; }
///////////////////////////////////////////////////////////////////////////////
// Helper functions
int CompareVersion(LPCTSTR lpszVersion1, LPCTSTR lpszVersion2) { LPCTSTR pszVerNum[2] = {lpszVersion1, lpszVersion2}; int nVerNum[2]; int nResult = 0;
while (nResult == 0 && *(pszVerNum[0]) != '\0' && *(pszVerNum[1]) != '\0') { nVerNum[0] = StrToInt(pszVerNum[0]++); nVerNum[1] = StrToInt(pszVerNum[1]++); nResult = ((nVerNum[0] < nVerNum[1]) ? (-1) : (nVerNum[0] > nVerNum[1] ? 1 : 0)); }
return nResult; }
|