|
|
#include "private.h"
#include "offl_cpp.h"
#include <htmlhelp.h>
#include <shdocvw.h>
#include <mluisupp.h>
// {F5175861-2688-11d0-9C5E-00AA00A45957}
const GUID CLSID_OfflineFolder = { 0xf5175861, 0x2688, 0x11d0, { 0x9c, 0x5e, 0x0, 0xaa, 0x0, 0xa4, 0x59, 0x57 } };
// {F5175860-2688-11d0-9C5E-00AA00A45957}
const GUID IID_IOfflineObject = { 0xf5175860, 0x2688, 0x11d0, { 0x9c, 0x5e, 0x0, 0xaa, 0x0, 0xa4, 0x59, 0x57 } };
// Column definition for the Cache Folder DefView
ColInfoType s_AllItems_cols[] = { {ICOLC_SHORTNAME, IDS_NAME_COL, 20, LVCFMT_LEFT}, {ICOLC_LAST, IDS_LAST_COL, 14, LVCFMT_LEFT}, {ICOLC_STATUS, IDS_STATUS_COL, 14, LVCFMT_LEFT}, {ICOLC_URL, IDS_URL_COL, 20, LVCFMT_LEFT}, {ICOLC_ACTUALSIZE, IDS_SIZE_COL, 10, LVCFMT_LEFT}};
ColInfoType * colInfo = s_AllItems_cols;
LPMYPIDL _CreateFolderPidl(IMalloc *pmalloc, DWORD dwSize);
HRESULT OfflineFolderView_InitMenuPopup(HWND hwnd, UINT idCmdFirst, int nIndex, HMENU hMenu) { UINT platform = WhichPlatform();
if (platform != PLATFORM_INTEGRATED) { MENUITEMINFO mInfo = {0}; mInfo.cbSize = sizeof(MENUITEMINFO); mInfo.fMask = MIIM_STATE; if (IsGlobalOffline()) { mInfo.fState = MFS_CHECKED; } else { mInfo.fState = MFS_UNCHECKED; } SetMenuItemInfo(hMenu, RSVIDM_WORKOFFLINE + idCmdFirst, FALSE, &mInfo); }
return NOERROR; }
HRESULT OfflineFolderView_MergeMenu(LPQCMINFO pqcm) { HMENU hmenu = NULL; UINT platform = WhichPlatform(); if (platform == PLATFORM_INTEGRATED) { hmenu = LoadMenu(MLGetHinst(), MAKEINTRESOURCE(MENU_OFFLINE_TOP)); } else { hmenu = LoadMenu(MLGetHinst(), MAKEINTRESOURCE(MENU_OFFLINE_BRONLY)); }
if (hmenu) { MergeMenuHierarchy(pqcm->hmenu, hmenu, pqcm->idCmdFirst, pqcm->idCmdLast, TRUE); DestroyMenu(hmenu); }
return S_OK; }
extern HRESULT CancelAllDownloads();
HRESULT OfflineFolderView_Command(HWND hwnd, UINT uID) { switch (uID) { case RSVIDM_SORTBYNAME: ShellFolderView_ReArrange(hwnd, ICOLC_SHORTNAME); break; case RSVIDM_UPDATEALL: SendUpdateRequests(hwnd, NULL, 0); break; case RSVIDM_WORKOFFLINE: SetGlobalOffline(!IsGlobalOffline()); break; case RSVIDM_HELP: SHHtmlHelpOnDemandWrap(hwnd, TEXT("iexplore.chm > iedefault"), 0, (DWORD_PTR) TEXT("subs_upd.htm"), ML_CROSSCODEPAGE); break;
case RSVIDM_UPDATE: { LPMYPIDL * pidlsSel = NULL; UINT count = 0;
count = (UINT) ShellFolderView_GetSelectedObjects (hwnd, (LPITEMIDLIST*) &pidlsSel);
if ((!pidlsSel) || !count) break;
CLSID * cookies = (CLSID *)MemAlloc(LPTR, count * sizeof(CLSID)); UINT validCount = 0;
if (cookies) { for (UINT i = 0; i < count; i ++) { if (IS_VALID_MYPIDL(pidlsSel[i])) cookies[validCount++] = pidlsSel[i]->ooe.m_Cookie; }
if (validCount) SendUpdateRequests(hwnd, cookies, validCount); MemFree(cookies); cookies = NULL; } break; } default: return E_FAIL; } return NOERROR; }
// We should make this a generic function for all types of items, even
// for the third party items they should support these properties.
HRESULT Generic_GetDetails(PDETAILSINFO pdi, UINT iColumn) { LPMYPIDL pooi = (LPMYPIDL)pdi->pidl; POOEntry pooe = NULL; TCHAR timeSTR[128];
pdi->str.uType = STRRET_CSTR; pdi->str.cStr[0] = '\0';
pooe = &(pooi->ooe); switch (iColumn) { case ICOLC_SHORTNAME: SHTCharToAnsi(NAME(pooe), pdi->str.cStr, sizeof(pdi->str.cStr)); break; case ICOLC_URL: SHTCharToAnsi(URL(pooe), pdi->str.cStr, sizeof(pdi->str.cStr)); break; case ICOLC_LAST: DATE2DateTimeString(pooe->m_LastUpdated, timeSTR, ARRAYSIZE(timeSTR)); SHTCharToAnsi(timeSTR, pdi->str.cStr, sizeof(pdi->str.cStr)); break; case ICOLC_STATUS: SHTCharToAnsi(STATUS(pooe), pdi->str.cStr, sizeof(pdi->str.cStr)); break; case ICOLC_ACTUALSIZE: StrFormatByteSizeA(pooe->m_ActualSize * 1024, pdi->str.cStr, sizeof(pdi->str.cStr)); break; }
return S_OK; }
HRESULT OfflineFolderView_OnGetDetailsOf(HWND hwnd, UINT iColumn, PDETAILSINFO pdi) { LPMYPIDL pooi = (LPMYPIDL)pdi->pidl;
if (iColumn > ICOLC_ACTUALSIZE) return E_NOTIMPL;
if (!pooi) { pdi->str.uType = STRRET_CSTR; pdi->str.cStr[0] = '\0'; MLLoadStringA(colInfo[iColumn].ids, pdi->str.cStr, sizeof(pdi->str.cStr)); pdi->fmt = colInfo[iColumn].iFmt; pdi->cxChar = colInfo[iColumn].cchCol; return S_OK; }
UINT colId = colInfo[iColumn].iCol; return Generic_GetDetails(pdi, colId); }
HRESULT OfflineFolderView_OnColumnClick(HWND hwnd, UINT iColumn) { ShellFolderView_ReArrange(hwnd, colInfo[iColumn].iCol); return NOERROR; }
const TBBUTTON c_tbOffline[] = { { 0, RSVIDM_UPDATE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 }, { 1, RSVIDM_UPDATEALL, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0L, -1 }, { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP , {0,0}, 0L, -1 }, };
HRESULT OfflineFolderView_OnGetButtons(HWND hwnd, UINT idCmdFirst, LPTBBUTTON ptButton) { UINT i; LONG_PTR iBtnOffset; IShellBrowser * psb = FileCabinet_GetIShellBrowser(hwnd); TBADDBITMAP ab;
// add the toolbar button bitmap, get it's offset
ab.hInst =g_hInst; ab.nID = IDB_TB_SMALL; // std bitmaps
psb->SendControlMsg(FCW_TOOLBAR, TB_ADDBITMAP, 2, (LPARAM)&ab, &iBtnOffset);
for (i = 0; i < ARRAYSIZE(c_tbOffline); i++) { ptButton[i] = c_tbOffline[i];
if (!(c_tbOffline[i].fsStyle & TBSTYLE_SEP)) { ptButton[i].idCommand += idCmdFirst; ptButton[i].iBitmap += (int)iBtnOffset; } }
return S_OK; }
HRESULT OfflineFolderView_OnGetButtonInfo(TBINFO * ptbInfo) { ptbInfo->uFlags = TBIF_PREPEND; ptbInfo->cbuttons = ARRAYSIZE(c_tbOffline); return S_OK; }
HRESULT OfflineFolderView_DidDragDrop(HWND hwnd,IDataObject *pdo,DWORD dwEffect) { if ((dwEffect & (DROPEFFECT_MOVE |DROPEFFECT_COPY)) == DROPEFFECT_MOVE) { COfflineObjectItem *pOOItem; if (SUCCEEDED(pdo->QueryInterface(IID_IOfflineObject, (void **)&pOOItem))) { BOOL fDel = ConfirmDelete(hwnd, pOOItem->_cItems, pOOItem->_ppooi); if (!fDel) { pOOItem->Release(); return S_FALSE; }
for (UINT i = 0; i < pOOItem->_cItems; i++) { if (SUCCEEDED(DoDeleteSubscription(&(pOOItem->_ppooi[i]->ooe)))) { _GenerateEvent(SHCNE_DELETE, (LPITEMIDLIST)pOOItem->_ppooi[i], NULL); } }
pOOItem->Release(); return S_OK; } } return E_FAIL; }
HRESULT CALLBACK OfflineFolderView_ViewCallback( IShellView *psvOuter, IShellFolder *psf, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HRESULT hres = NOERROR;
switch (uMsg) { case DVM_GETHELPTEXT: case DVM_GETTOOLTIPTEXT: { UINT id = LOWORD(wParam); UINT cchBuf = HIWORD(wParam); if (g_fIsWinNT) { WCHAR * pszBuf = (WCHAR *)lParam; MLLoadStringW(id + IDS_SB_FIRST, pszBuf, cchBuf); } else { CHAR * pszBuf = (CHAR *)lParam; MLLoadStringA(id + IDS_SB_FIRST, pszBuf, cchBuf); } } break;
case DVM_DIDDRAGDROP: hres = OfflineFolderView_DidDragDrop(hwnd,(IDataObject *)lParam,(DWORD)wParam); break; case DVM_INITMENUPOPUP: hres = OfflineFolderView_InitMenuPopup(hwnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam); break;
case DVM_INVOKECOMMAND: OfflineFolderView_Command(hwnd, (UINT)wParam); break;
case DVM_COLUMNCLICK: hres = OfflineFolderView_OnColumnClick(hwnd, (UINT)wParam); break;
case DVM_GETDETAILSOF: hres = OfflineFolderView_OnGetDetailsOf(hwnd, (UINT)wParam, (PDETAILSINFO)lParam); break;
case DVM_MERGEMENU: hres = OfflineFolderView_MergeMenu((LPQCMINFO)lParam); break;
case DVM_DEFVIEWMODE: *(FOLDERVIEWMODE *)lParam = FVM_DETAILS; break;
case DVM_GETBUTTONINFO: hres = OfflineFolderView_OnGetButtonInfo((TBINFO *)lParam); break;
case DVM_GETBUTTONS: hres = OfflineFolderView_OnGetButtons(hwnd, LOWORD(wParam), (TBBUTTON *)lParam); break;
default: hres = E_FAIL; }
return hres; }
HRESULT OfflineFolderView_CreateInstance(COfflineFolder *pOOFolder, LPCITEMIDLIST pidl, void **ppvOut) { CSFV csfv;
csfv.cbSize = sizeof(csfv); csfv.pshf = (IShellFolder *)pOOFolder; csfv.psvOuter = NULL; csfv.pidl = pidl; csfv.lEvents = SHCNE_DELETE | SHCNE_CREATE | SHCNE_RENAMEITEM | SHCNE_UPDATEITEM | SHCNE_UPDATEDIR; csfv.pfnCallback = OfflineFolderView_ViewCallback; csfv.fvm = (FOLDERVIEWMODE)0; // Have defview restore the folder view mode
return SHCreateShellFolderViewEx(&csfv, (IShellView**)ppvOut); // &this->psv);
}
//////////////////////////////////////////////////////////////////////////////
//
// COfflineFolderEnum Object
//
//////////////////////////////////////////////////////////////////////////////
COfflineFolderEnum::COfflineFolderEnum(DWORD grfFlags) { TraceMsg(TF_SUBSFOLDER, "hcfe - COfflineFolderEnum() called"); m_cRef = 1; DllAddRef();
m_grfFlags = grfFlags; }
IMalloc *COfflineFolderEnum::s_pMalloc = NULL;
void COfflineFolderEnum::EnsureMalloc() { if (NULL == s_pMalloc) { SHGetMalloc(&s_pMalloc); }
ASSERT(NULL != s_pMalloc); }
COfflineFolderEnum::~COfflineFolderEnum() { ASSERT(m_cRef == 0); // we should always have a zero ref count here
SAFERELEASE(m_pFolder); SAFEDELETE(m_pCookies);
TraceMsg(TF_SUBSFOLDER, "hcfe - ~COfflineFolderEnum() called."); DllRelease(); }
HRESULT COfflineFolderEnum::Initialize(COfflineFolder *pFolder) { HRESULT hr = S_OK;
ASSERT(pFolder); if (NULL != pFolder) { m_pFolder = pFolder; m_pFolder->AddRef();
hr = CoInitialize(NULL);
if (SUCCEEDED(hr)) { ISubscriptionMgr2 *pSubsMgr2; hr = CoCreateInstance(CLSID_SubscriptionMgr, NULL, CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr2, (void **)&pSubsMgr2); if (SUCCEEDED(hr)) { IEnumSubscription *pes;
hr = pSubsMgr2->EnumSubscriptions(0, &pes); if (SUCCEEDED(hr)) { pes->GetCount(&m_nCount);
if (m_nCount > 0) { m_pCookies = new SUBSCRIPTIONCOOKIE[m_nCount];
if (NULL != m_pCookies) { hr = pes->Next(m_nCount, m_pCookies, &m_nCount); } else { hr = E_OUTOFMEMORY; } } pes->Release(); } pSubsMgr2->Release(); }
CoUninitialize(); } } else { hr = E_INVALIDARG; } return hr; }
HRESULT COfflineFolderEnum_CreateInstance(DWORD grfFlags, COfflineFolder *pFolder, LPENUMIDLIST *ppeidl) { HRESULT hr;
*ppeidl = NULL;
COfflineFolderEnum *pOOFE = new COfflineFolderEnum(grfFlags); if (NULL != pOOFE) { hr = pOOFE->Initialize(pFolder);
if (SUCCEEDED(hr)) { *ppeidl = pOOFE; } else { pOOFE->Release(); } } else { hr = E_OUTOFMEMORY; } return hr; }
//////////////////////////////////
//
// IUnknown Methods...
//
HRESULT COfflineFolderEnum::QueryInterface(REFIID iid,void **ppv) { // TraceMsg(TF_SUBSFOLDER, "COfflineFolderEnum - QI called.");
if ((iid == IID_IEnumIDList) || (iid == IID_IUnknown)) { *ppv = (IEnumIDList *)this; AddRef(); return S_OK; } *ppv = NULL; return E_NOINTERFACE; }
ULONG COfflineFolderEnum::AddRef(void) { return ++m_cRef; }
ULONG COfflineFolderEnum::Release(void) { if (0L != --m_cRef) return m_cRef;
delete this; return 0; }
LPMYPIDL COfflineFolderEnum::NewPidl(DWORD dwSize) { LPMYPIDL pidl;
// TraceMsg(TF_MEMORY, "NewPidl called");
EnsureMalloc();
pidl = _CreateFolderPidl(s_pMalloc, dwSize);
// TraceMsg(TF_MEMORY, "\tNewPidl returned with 0x%x", pidl);
return pidl; }
void COfflineFolderEnum::FreePidl(LPMYPIDL pidl) { ASSERT(NULL != pidl);
// TraceMsg(TF_MEMORY, "FreePidl on (0x%x) called", pidl);
EnsureMalloc();
s_pMalloc->Free(pidl); }
// IEnumIDList Methods
HRESULT COfflineFolderEnum::Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG *pceltFetched) { HRESULT hr = S_OK; ULONG nCopied; DWORD dwBuffSize; OOEBuf ooeBuf;
if ((0 == celt) || ((celt > 1) && (NULL == pceltFetched)) || (NULL == rgelt)) { return E_INVALIDARG; }
memset(&ooeBuf, 0, sizeof(ooeBuf));
for (nCopied = 0; (S_OK == hr) && (m_nCurrent < m_nCount) && (nCopied < celt); m_nCurrent++, nCopied++) { rgelt[nCopied] = NULL; hr = LoadOOEntryInfo(&ooeBuf, &m_pCookies[m_nCurrent], &dwBuffSize);
if (SUCCEEDED(hr)) { if (IsNativeAgent(ooeBuf.clsidDest)) { CLSID cookie; HRESULT hrTmp = ReadCookieFromInetDB(ooeBuf.m_URL, &cookie); if (S_OK != hrTmp) { hrTmp = WriteCookieToInetDB(ooeBuf.m_URL,&(ooeBuf.m_Cookie), FALSE); ASSERT(SUCCEEDED(hrTmp)); } }
LPMYPIDL pooi = NewPidl(dwBuffSize); if (pooi) { CopyToMyPooe(&ooeBuf, &(pooi->ooe)); // Always succeeds!
rgelt[nCopied] = (LPITEMIDLIST)pooi; } else { hr = E_OUTOFMEMORY; } } }
if (SUCCEEDED(hr)) { hr = (celt == nCopied) ? S_OK : S_FALSE; } else { for (ULONG i = 0; i < nCopied; i++) { FreePidl((LPMYPIDL)rgelt[i]); } }
if (NULL != pceltFetched) { *pceltFetched = SUCCEEDED(hr) ? nCopied : 0; } return hr; }
HRESULT COfflineFolderEnum::Skip(ULONG celt) { HRESULT hr; m_nCurrent += celt;
if (m_nCurrent > (m_nCount - 1)) { m_nCurrent = m_nCount; // Passed the last one
hr = S_FALSE; } else { hr = S_OK; } return hr; }
HRESULT COfflineFolderEnum::Reset() { m_nCurrent = 0;
return S_OK; }
HRESULT COfflineFolderEnum::Clone(IEnumIDList **ppenum) { return E_NOTIMPL; }
//////////////////////////////////////////////////////////////////////////////
//
// COfflineFolder Object
//
//////////////////////////////////////////////////////////////////////////////
COfflineFolder::COfflineFolder(void) { TraceMsg(TF_SUBSFOLDER, "Folder - COfflineFolder() called."); _cRef = 1; viewMode = 0; colInfo = s_AllItems_cols; DllAddRef(); }
COfflineFolder::~COfflineFolder() { Assert(_cRef == 0); // should always have zero
TraceMsg(TF_SUBSFOLDER, "Folder - ~COfflineFolder() called.");
if (_pidl) ILFree(_pidl); DllRelease(); }
//////////////////////////////////
//
// IUnknown Methods...
//
HRESULT COfflineFolder::QueryInterface(REFIID iid, void **ppvObj) { *ppvObj = NULL; // null the out param
if (iid == IID_IUnknown) { *ppvObj = (void *)this; } else if (iid == IID_IShellFolder) { *ppvObj = (void *)(IShellFolder *)this; } else if ((iid == IID_IPersistFolder) || (iid == IID_IPersist) || (iid == IID_IPersistFolder2)) { *ppvObj = (void *)(IPersistFolder *)this; } else if (iid == IID_IContextMenu) { *ppvObj = (void *)(IContextMenu *)this; } else if (iid == IID_IShellView) { return OfflineFolderView_CreateInstance(this, _pidl, ppvObj); } else if (iid == IID_IOfflineObject) { *ppvObj = (void *)this; } else if (iid == IID_IDropTarget) { // APPCOMPAT: Implementation of IDropTarget didn't follow the COM rules.
// We create following object by aggregattion but QI on it for IUnknown
// won't get us ptr THIS.
COfflineDropTarget * podt = new COfflineDropTarget(GetDesktopWindow()); if (podt) { HRESULT hr = podt->QueryInterface(iid, ppvObj); podt->Release(); } else { return E_OUTOFMEMORY; } }
if (*ppvObj) { ((IUnknown *)*ppvObj)->AddRef(); return S_OK; }
return E_NOINTERFACE; }
ULONG COfflineFolder::AddRef() { return ++_cRef; }
ULONG COfflineFolder::Release() { if (0L != --_cRef) return _cRef;
delete this; return 0; }
//////////////////////////////////
//
// IShellFolder methods...
//
HRESULT COfflineFolder::ParseDisplayName(HWND hwndOwner, LPBC pbcReserved, LPOLESTR lpszDisplayName, ULONG *pchEaten, LPITEMIDLIST *ppidl, ULONG *pdwAttributes) { // TraceMsg(TF_SUBSFOLDER, "Folder:ISF - ParseDisplayName.");
*ppidl = NULL; return E_FAIL; }
HRESULT COfflineFolder::EnumObjects(HWND hwndOwner, DWORD grfFlags, LPENUMIDLIST *ppenumIDList) { // TraceMsg(TF_SUBSFOLDER, "Folder:ISF - EnumObjects.");
return COfflineFolderEnum_CreateInstance(grfFlags, this, ppenumIDList); }
HRESULT COfflineFolder::BindToObject(LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, void **ppvOut) { // TraceMsg(TF_SUBSFOLDER, "Folder:ISF - BindToObject.");
*ppvOut = NULL; return E_FAIL; }
HRESULT COfflineFolder::BindToStorage(LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, void **ppvObj) { // TraceMsg(TF_SUBSFOLDER, "Folder:ISF - BindToStorage.");
*ppvObj = NULL; return E_NOTIMPL; }
HRESULT COfflineFolder::CompareIDs(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { int iRet;
// TraceMsg(TF_SUBSFOLDER, "Folder:ISF - CompareIDs(%d).", lParam);
if (!IS_VALID_MYPIDL(pidl1) || !IS_VALID_MYPIDL(pidl2)) return E_FAIL;
switch (lParam) { case ICOLC_SHORTNAME: iRet = _CompareShortName((LPMYPIDL)pidl1, (LPMYPIDL)pidl2); break; case ICOLC_URL: iRet = _CompareURL((LPMYPIDL)pidl1, (LPMYPIDL)pidl2); break; case ICOLC_STATUS: iRet = _CompareStatus((LPMYPIDL)pidl1, (LPMYPIDL)pidl2); break; case ICOLC_LAST: iRet = _CompareLastUpdate((LPMYPIDL)pidl1, (LPMYPIDL)pidl2); break; case ICOLC_ACTUALSIZE: iRet = (((LPMYPIDL)pidl1)->ooe.m_ActualSize - ((LPMYPIDL)pidl2)->ooe.m_ActualSize); break; default: iRet = -1; break; } return ResultFromShort((SHORT)iRet); }
HRESULT COfflineFolder::CreateViewObject(HWND hwndOwner, REFIID riid, void **ppvOut) { HRESULT hres;
// TraceMsg(TF_SUBSFOLDER, "Folder:ISF - CreateViewObject() called.");
if (riid == IID_IShellView) { hres = OfflineFolderView_CreateInstance(this, _pidl, ppvOut); } else if (riid == IID_IContextMenu) { COfflineFolder * pof = new COfflineFolder();
if (pof) { hres = pof->Initialize(this->_pidl); if (SUCCEEDED(hres)) hres = pof->QueryInterface(riid, ppvOut); pof->Release(); } else { return E_OUTOFMEMORY; } } else if (riid == IID_IDropTarget) { COfflineDropTarget * podt = new COfflineDropTarget(hwndOwner);
if (podt) { hres = podt->QueryInterface(riid, ppvOut); podt->Release(); } else { return E_OUTOFMEMORY; } } else if (riid == IID_IShellDetails) { COfflineDetails *pod = new COfflineDetails(hwndOwner); if (NULL != pod) { hres = pod->QueryInterface(IID_IShellDetails, ppvOut); pod->Release(); } else { hres = E_OUTOFMEMORY; } } else { DBGIID("COfflineFolder::CreateViewObject() failed", riid); *ppvOut = NULL; // null the out param
hres = E_NOINTERFACE; } return hres; }
HRESULT COfflineFolder::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 ); UINT attr = SFGAO_CANCOPY | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET; *prgfInOut = attr; return NOERROR; }
HRESULT COfflineFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl, REFIID riid, UINT * prgfInOut, void **ppvOut) { HRESULT hres;
// TraceMsg(TF_SUBSFOLDER, "Folder:ISF - GetUIObjectOf.");
if ((riid == IID_IContextMenu) || (riid == IID_IDataObject) || (riid == IID_IExtractIcon) || (riid == IID_IQueryInfo)) { hres = COfflineObjectItem_CreateInstance(this, cidl, apidl, riid, ppvOut); } else if (riid == IID_IDropTarget) { hres = CreateViewObject(hwndOwner, IID_IDropTarget, ppvOut); } else { *ppvOut = NULL; hres = E_FAIL; DBGIID("Unsupported interface in COfflineFolder::GetUIObjectOf()", riid); } return hres; }
HRESULT COfflineFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD uFlags, LPSTRRET lpName) { // TraceMsg(TF_SUBSFOLDER, "Folde:ISF - GetDisplayNameOf.");
if (!IS_VALID_MYPIDL(pidl)) { lpName->uType = 0; return E_FAIL; }
lpName->uType = STRRET_CSTR; lpName->cStr[0] = '\0';
PCTSTR pszNameLocal; LPTSTR szNameUnaligned = NAME(&(((LPMYPIDL)pidl)->ooe));
TSTR_ALIGNED_STACK_COPY( &pszNameLocal, szNameUnaligned );
SHTCharToAnsi( pszNameLocal, lpName->cStr, ARRAYSIZE(lpName->cStr) );
TraceMsg(TF_ALWAYS, "COfflineFolder::GetDisplayNameOf() - pszNameLocal='%s'", pszNameLocal );
TraceMsg(TF_ALWAYS, "COfflineFolder::GetDisplayNameOf() - lpName->cStr='%S'", lpName->cStr );
return NOERROR; }
HRESULT COfflineFolder::SetNameOf(HWND hwndOwner, LPCITEMIDLIST pidl, LPCOLESTR lpszName, DWORD uFlags, LPITEMIDLIST * ppidlOut) { OOEBuf ooeBuf; POOEntry pooe = NULL; // TraceMsg(TF_SUBSFOLDER, "Folde:ISF - SetNameOf.");
if (ppidlOut) { *ppidlOut = NULL; // null the out param
}
if (!IS_VALID_MYPIDL(pidl)) return E_FAIL;
HRESULT hr; WCHAR szTempName[MAX_PATH];
ASSERT(lpszName);
StrCpyNW(szTempName, lpszName, ARRAYSIZE(szTempName));
PathRemoveBlanks(szTempName);
if (szTempName[0]) { memset(&ooeBuf, 0, sizeof(ooeBuf));
pooe = &(((LPMYPIDL)pidl)->ooe); CopyToOOEBuf(pooe, &ooeBuf); MyOleStrToStrN(ooeBuf.m_Name, MAX_NAME, szTempName);
ooeBuf.dwFlags = PROP_WEBCRAWL_NAME; hr = SaveBufferChange(&ooeBuf, FALSE); if (ppidlOut) { DWORD dwSize = BufferSize(&ooeBuf); *ppidlOut = (LPITEMIDLIST)COfflineFolderEnum::NewPidl(dwSize); if (*ppidlOut) { pooe = &(((LPMYPIDL)(*ppidlOut))->ooe); CopyToMyPooe(&ooeBuf, pooe); } } } else { WCMessageBox(hwndOwner, IDS_NONULLNAME, IDS_RENAME, MB_OK | MB_ICONSTOP); hr = E_FAIL; } return hr; }
//////////////////////////////////
//
// IPersistFolder Methods...
//
HRESULT COfflineFolder::GetClassID(LPCLSID lpClassID) { // TraceMsg(TF_SUBSFOLDER, "hcf - pf - GetClassID.");
*lpClassID = CLSID_OfflineFolder; return S_OK; }
HRESULT COfflineFolder::Initialize(LPCITEMIDLIST pidlInit) { if (_pidl) ILFree(_pidl);
_pidl = ILClone(pidlInit);
if (!_pidl) return E_OUTOFMEMORY;
return NOERROR; }
HRESULT COfflineFolder::GetCurFolder(LPITEMIDLIST *ppidl) { if (_pidl) { *ppidl = ILClone(_pidl); return *ppidl ? NOERROR : E_OUTOFMEMORY; }
*ppidl = NULL; return S_FALSE; // success but empty
}
//////////////////////////////////
//
// IContextMenu Methods...
//
HRESULT COfflineFolder::QueryContextMenu ( HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) { USHORT cItems = 0;
// TraceMsg(TF_SUBSFOLDER, "Folder:IContextMenu- QueryContextMenu.");
if (uFlags == CMF_NORMAL) { HMENU hmenuHist = LoadMenu(MLGetHinst(), MAKEINTRESOURCE(CONTEXT_MENU_OFFLINE)); if (hmenuHist) { cItems = (USHORT) MergeMenuHierarchy(hmenu, hmenuHist, idCmdFirst, idCmdLast, TRUE);
DestroyMenu(hmenuHist); } } return ResultFromShort(cItems); // number of menu items
}
STDMETHODIMP COfflineFolder::InvokeCommand(LPCMINVOKECOMMANDINFO pici) { // TraceMsg(TF_SUBSFOLDER, "Folder:IContextMenu - InvokeCommand.");
int idCmd = _GetCmdID(pici->lpVerb); if (idCmd != RSVIDM_PASTE) return OfflineFolderView_Command(pici->hwnd, idCmd); IDataObject * dataSrc = NULL; IDropTarget * pDropTrgt = NULL; HRESULT hr;
hr = OleGetClipboard(&(dataSrc));
if (SUCCEEDED(hr)) hr = this->QueryInterface(IID_IDropTarget, (void **) &pDropTrgt);
if (SUCCEEDED(hr)) { DWORD dwPrefEffect = DROPEFFECT_COPY; POINTL pt = {0, 0};
hr = pDropTrgt->DragEnter(dataSrc, 0/*keystate*/, pt, &dwPrefEffect); if (SUCCEEDED(hr)) { hr = pDropTrgt->Drop(dataSrc, 0, pt, &dwPrefEffect); } }
if (dataSrc) SAFERELEASE(dataSrc); if (pDropTrgt) SAFERELEASE(pDropTrgt);
return hr; }
STDMETHODIMP COfflineFolder::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax) { HRESULT hres = E_FAIL;
// TraceMsg(TF_SUBSFOLDER, "Folder:IContextMenu - GetCommandString.");
if (uFlags == GCS_HELPTEXTA) { MLLoadStringA((UINT)idCmd + IDS_SB_FIRST, pszName, cchMax); hres = NOERROR; } return hres; }
COfflineDetails::COfflineDetails(HWND hwndOwner) { ASSERT(NULL != hwndOwner); m_hwndOwner = hwndOwner; m_cRef = 1; }
STDMETHODIMP COfflineDetails::QueryInterface(REFIID riid, void **ppv) { if ((IID_IUnknown == riid) || (IID_IShellDetails == riid)) { *ppv = (IShellDetails *)this; } else { *ppv = NULL; return E_NOINTERFACE; } AddRef(); return S_OK; }
STDMETHODIMP_(ULONG) COfflineDetails::AddRef() { return ++m_cRef; }
STDMETHODIMP_(ULONG) COfflineDetails::Release() { if (--m_cRef == 0) { delete this; return 0; }
return m_cRef; }
STDMETHODIMP COfflineDetails::GetDetailsOf(LPCITEMIDLIST pidl, UINT iColumn, LPSHELLDETAILS pDetails) { HRESULT hr;
if (iColumn > ICOLC_ACTUALSIZE) return E_NOTIMPL;
if (NULL == pDetails) { return E_INVALIDARG; } if (NULL != pidl) { DETAILSINFO di = { pidl }; hr = Generic_GetDetails(&di, colInfo[iColumn].iCol); pDetails->fmt = di.fmt; pDetails->cxChar = di.cxChar; memcpy(&pDetails->str, &di.str, sizeof(di.str)); } else { pDetails->str.uType = STRRET_CSTR; pDetails->str.cStr[0] = '\0'; MLLoadStringA(colInfo[iColumn].ids, pDetails->str.cStr, sizeof(pDetails->str.cStr)); pDetails->fmt = colInfo[iColumn].iFmt; pDetails->cxChar = colInfo[iColumn].cchCol; hr = S_OK; }
return hr; }
STDMETHODIMP COfflineDetails::ColumnClick(UINT iColumn) { ShellFolderView_ReArrange(m_hwndOwner, colInfo[iColumn].iCol); return S_OK; }
LPMYPIDL _CreateFolderPidl(IMalloc *pmalloc, DWORD dwSize) { LPMYPIDL pooi = (LPMYPIDL)pmalloc->Alloc(sizeof(MYPIDL) + dwSize + sizeof(USHORT)); if (pooi) { memset(pooi, 0, sizeof(MYPIDL) + dwSize + sizeof(USHORT)); pooi->cb = (USHORT)(dwSize + sizeof(MYPIDL)); pooi->usSign = (USHORT)MYPIDL_MAGIC; // TraceMsg(TF_MEMORY, "CreatePidl %d", sizeof(MYPIDL) + dwSize);
} return pooi; }
|