246 lines
12 KiB
C++
246 lines
12 KiB
C++
#ifndef _mergfldr_h_
|
|
#define _mergfldr_h_
|
|
|
|
#include "sfstorage.h"
|
|
#include "clsobj.h"
|
|
|
|
class CMergedFolder;
|
|
class CMergedFldrDropTarget;
|
|
class CMergedFldrContextMenu;
|
|
class CMergedFldrNamespace;
|
|
class CMergedFldrItem;
|
|
class CMergedFldrEnum;
|
|
class CMergedCategorizer;
|
|
class CMergedFolderViewCB;
|
|
|
|
class CMergedFolder : public CSFStorage,
|
|
public IAugmentedShellFolder3,
|
|
public IShellService,
|
|
public ITranslateShellChangeNotify,
|
|
public IPersistFolder2,
|
|
public IPersistPropertyBag,
|
|
public IShellIconOverlay,
|
|
public ICompositeFolder,
|
|
public IItemNameLimits
|
|
{
|
|
public:
|
|
// IUnknown
|
|
STDMETHOD (QueryInterface)(REFIID, void **);
|
|
STDMETHOD_(ULONG, AddRef)();
|
|
STDMETHOD_(ULONG, Release)();
|
|
|
|
// IShellFolder
|
|
STDMETHOD(ParseDisplayName)(HWND hwnd, LPBC pbc, LPOLESTR pszName, ULONG * pchEaten, LPITEMIDLIST * ppidl, ULONG *pdwAttributes);
|
|
STDMETHOD(EnumObjects)(HWND hwnd, DWORD grfFlags, IEnumIDList **ppenumIDList);
|
|
STDMETHOD(BindToObject)(LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, void **ppvOut);
|
|
STDMETHOD(BindToStorage)(LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, void **ppvObj);
|
|
STDMETHOD(CompareIDs)(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
|
|
STDMETHOD(CreateViewObject)(HWND hwndOwner, REFIID riid, void **ppvOut);
|
|
STDMETHOD(GetAttributesOf)(UINT cidl, LPCITEMIDLIST * apidl, ULONG *rgfInOut);
|
|
STDMETHOD(GetUIObjectOf)(HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl, REFIID riid, UINT * prgfInOut, void **ppvOut);
|
|
STDMETHOD(GetDisplayNameOf)(LPCITEMIDLIST pidl, DWORD uFlags, LPSTRRET lpName);
|
|
STDMETHOD(SetNameOf)(HWND hwnd, LPCITEMIDLIST pidl, LPCOLESTR pszName, DWORD uFlags, LPITEMIDLIST * ppidlOut);
|
|
|
|
// IShellFolder2
|
|
// stub implementation to indicate we support CompareIDs() for identity
|
|
STDMETHOD(GetDefaultSearchGUID)(LPGUID)
|
|
{ return E_NOTIMPL; }
|
|
STDMETHOD(EnumSearches)(LPENUMEXTRASEARCH *pe)
|
|
{ *pe = NULL; return E_NOTIMPL; }
|
|
STDMETHOD(GetDefaultColumn)(DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
|
|
{ return E_NOTIMPL; };
|
|
|
|
STDMETHOD(GetDefaultColumnState)(UINT iColumn, DWORD *pbState);
|
|
STDMETHOD(GetDetailsEx)(LPCITEMIDLIST pidl, const SHCOLUMNID *pscid, VARIANT *pv);
|
|
STDMETHOD(GetDetailsOf)(LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS *pDetails);
|
|
STDMETHOD(MapColumnToSCID)(UINT iCol, SHCOLUMNID *pscid);
|
|
|
|
// IAugmentedShellFolder
|
|
STDMETHOD(AddNameSpace)(const GUID * pguidObject, IShellFolder * psf, LPCITEMIDLIST pidl, DWORD dwFlags);
|
|
STDMETHOD(GetNameSpaceID)(LPCITEMIDLIST pidl, GUID * pguidOut);
|
|
STDMETHOD(QueryNameSpace)(DWORD dwID, GUID * pguidOut, IShellFolder ** ppsf);
|
|
STDMETHOD(EnumNameSpace)(DWORD cNameSpaces, DWORD * pdwID);
|
|
|
|
// IAugmentedShellFolder2
|
|
STDMETHOD(UnWrapIDList)(LPCITEMIDLIST pidlWrap, LONG cPidls, IShellFolder** apsf, LPITEMIDLIST* apidlFolder, LPITEMIDLIST* apidlItems, LONG* pcFetched);
|
|
|
|
// IAugmentedShellFolder3
|
|
STDMETHOD(QueryNameSpace2)(DWORD dwID, QUERYNAMESPACEINFO *pqnsi);
|
|
|
|
// IShellService
|
|
STDMETHOD(SetOwner)(IUnknown * punkOwner);
|
|
|
|
// ITranslateShellChangeNotify
|
|
STDMETHOD(TranslateIDs)(LONG *plEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, LPITEMIDLIST *ppidlOut1, LPITEMIDLIST *ppidlOut2,
|
|
LONG *plEvent2, LPITEMIDLIST *ppidlOut1Event2, LPITEMIDLIST *ppidlOut2Event2);
|
|
STDMETHOD(IsChildID)(LPCITEMIDLIST pidlKid, BOOL fImmediate);
|
|
STDMETHOD(IsEqualID)(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
|
|
STDMETHOD(Register)(HWND hwnd, UINT uMsg, long lEvents);
|
|
STDMETHOD(Unregister)(void);
|
|
|
|
// IPersist
|
|
STDMETHOD(GetClassID)(CLSID *pclsid)
|
|
{ *pclsid = _clsid; return S_OK; };
|
|
|
|
// IPersistFolder
|
|
STDMETHOD(Initialize)(LPCITEMIDLIST pidl);
|
|
|
|
// IPersistFolder2
|
|
STDMETHOD(GetCurFolder)(LPITEMIDLIST *ppidl);
|
|
|
|
// IPersistPropertyBag
|
|
STDMETHOD(InitNew)()
|
|
{ return E_NOTIMPL; };
|
|
STDMETHOD(Load)(IPropertyBag* ppb, IErrorLog *pErrLog);
|
|
STDMETHOD(Save)(IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties)
|
|
{ return E_NOTIMPL; };
|
|
|
|
// IShellIconOverlay
|
|
STDMETHOD(GetOverlayIndex)(LPCITEMIDLIST pidl, int *pIndex);
|
|
STDMETHOD(GetOverlayIconIndex)(LPCITEMIDLIST pidl, int *pIndex);
|
|
|
|
// ICompositeFolder
|
|
STDMETHOD(InitComposite)(WORD wSignature, REFCLSID refclsid, CFINITF cfiFlags, ULONG celt, const COMPFOLDERINIT *rgCFs);
|
|
STDMETHOD(BindToParent)(LPCITEMIDLIST pidl, REFIID riid, void **ppv, LPITEMIDLIST *ppidlLast);
|
|
|
|
// IItemNameLimits
|
|
STDMETHOD(GetValidCharacters)(LPWSTR *ppwszValidChars, LPWSTR *ppwszInvalidChars)
|
|
{ return E_NOTIMPL; }
|
|
STDMETHOD(GetMaxLength)(LPCWSTR pszName, int *piMaxNameLen)
|
|
{ return E_NOTIMPL; }
|
|
|
|
protected:
|
|
CMergedFolder(CMergedFolder*pmfParent, REFCLSID clsid);
|
|
virtual ~CMergedFolder();
|
|
friend HRESULT CMergedFolder_CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv);
|
|
friend HRESULT CCompositeFolder_CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv);
|
|
virtual HRESULT _CreateWithCLSID(CLSID clsid, CMergedFolder **ppmf);
|
|
virtual BOOL _ShouldSuspend(REFGUID rguid);
|
|
|
|
private:
|
|
|
|
// CSFStorage
|
|
STDMETHOD(_DeleteItemByIDList)(LPCITEMIDLIST pidl);
|
|
STDMETHOD(_StgCreate)(LPCITEMIDLIST pidl, DWORD grfMode, REFIID riid, void **ppv);
|
|
|
|
CMergedFldrNamespace* _Namespace(int iNamespace);
|
|
HRESULT _Namespace(int i, CMergedFldrNamespace **ppns);
|
|
HRESULT _NamespaceForItem(LPCITEMIDLIST pidlWrap, ULONG dwAttribMask, ULONG dwAttrib, IShellFolder** ppsf, LPITEMIDLIST *ppidl, CMergedFldrNamespace **ppns, BOOL fExact = FALSE);
|
|
HRESULT _OldTranslateIDs(LONG *plEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, LPITEMIDLIST *ppidlOut1, LPITEMIDLIST *ppidlOut2,
|
|
LONG *plEvent2, LPITEMIDLIST *ppidlOut1Event2, LPITEMIDLIST *ppidlOut2Event2);
|
|
HRESULT _NewTranslateIDs(LONG *plEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2, LPITEMIDLIST *ppidlOut1, LPITEMIDLIST *ppidlOut2,
|
|
LONG *plEvent2, LPITEMIDLIST *ppidlOut1Event2, LPITEMIDLIST *ppidlOut2Event2);
|
|
HRESULT _GetOverlayInfo(LPCITEMIDLIST pidl, int * pIndex, DWORD dwFlags);
|
|
|
|
BOOL _NamespaceMatches(ULONG dwAttribMask, ULONG dwAttrib, LPCGUID pguid, CMergedFldrNamespace *pns);
|
|
HRESULT _FindNamespace(ULONG dwAttribMask, ULONG dwAttrib, LPCGUID pguid, CMergedFldrNamespace **ppv, BOOL fFallback = FALSE);
|
|
BOOL _ShouldMergeNamespaces(int iNS1, int iNS2);
|
|
BOOL _ShouldMergeNamespaces(CMergedFldrNamespace *pns1, CMergedFldrNamespace *pns2);
|
|
CMergedFolder*_Parent() { return _pmfParent; }
|
|
HRESULT _GetPidl(int* piPos, DWORD grfEnumFlags, LPITEMIDLIST *ppidl);
|
|
HRESULT _GetFolder2(LPCITEMIDLIST pidlWrap, LPITEMIDLIST *ppidlItem, IShellFolder2 **ppsf);
|
|
BOOL _ContainsCommonItem(LPCITEMIDLIST pidl);
|
|
HRESULT _New(LPCITEMIDLIST pidlWrap, CMergedFolder **ppmf);
|
|
|
|
HRESULT _IsWrap(LPCITEMIDLIST pidlTest);
|
|
HRESULT _CreateWrap(LPCITEMIDLIST pidlSrc, UINT nSrcID, LPITEMIDLIST *ppidlWrap);
|
|
HRESULT _WrapAddIDList(LPCITEMIDLIST pidlSrc, UINT nSrcID, IN OUT LPITEMIDLIST *ppidlWrap);
|
|
ULONG _GetSourceCount(IN LPCITEMIDLIST pidl);
|
|
BOOL _ContainsSrcID(LPCITEMIDLIST pidlWrap, UINT uSrcID);
|
|
HRESULT _WrapRemoveIDList(LPITEMIDLIST pidlWrap, UINT nSrcID, LPITEMIDLIST *ppidl);
|
|
HRESULT _WrapRemoveIDListAbs(LPITEMIDLIST pidlWrapAbs, UINT nSrcID, LPITEMIDLIST *ppidlAbs);
|
|
HRESULT _GetSubPidl(LPCITEMIDLIST pidlWrap, int i, UINT* pnSrcID, LPITEMIDLIST *ppidl, CMergedFldrNamespace **ppns);
|
|
HRESULT _ForceParseDisplayName(LPCITEMIDLIST pidlAbsNamespace, LPTSTR pszDisplayName, BOOL fForce, BOOL *pfOthersInwrap, LPITEMIDLIST *ppidl);
|
|
HRESULT _AbsPidlToAbsWrap(CMergedFldrNamespace *pns, LPCITEMIDLIST pidl, BOOL fForce, BOOL *pfOthersInwrap, LPITEMIDLIST *ppidl);
|
|
HRESULT _AddComposite(const COMPFOLDERINIT *pcfi);
|
|
void _SetSimple(LPITEMIDLIST *ppidl);
|
|
BOOL _IsSimple(LPCITEMIDLIST pidl);
|
|
|
|
HRESULT _FixStrRetOffset(LPCITEMIDLIST pidl, STRRET *psr);
|
|
BOOL _IsFolder(LPCITEMIDLIST pidl);
|
|
HRESULT _CreateOtherNameSpace(IShellFolder **ppsf);
|
|
HRESULT _CompareSingleLevelIDs(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
|
|
|
|
static int CALLBACK _SearchByName(void *p1, void *p2, LPARAM lParam);
|
|
static void *_Merge(UINT uMsg, void * pv1, void * pv2, LPARAM lParam);
|
|
static int _CompareArbitraryPidls(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
|
|
static int _Compare(void *pv1, void *pv2, LPARAM lParam);
|
|
|
|
HRESULT _SearchForPidl(int iNamespace, CMergedFldrNamespace *pns, LPCITEMIDLIST pidl, BOOL fFolder, int* piIndex, CMergedFldrItem** ppmfi);
|
|
HRESULT _GetTargetUIObjectOf(IShellFolder *psf, HWND hwnd, UINT cidl, LPCITEMIDLIST *apidl, REFIID riid, UINT *prgf, void **ppv);
|
|
HRESULT _GetContextMenu(HWND hwnd, UINT cidl, LPCITEMIDLIST *apidl, REFIID riid, void **ppv);
|
|
|
|
int _NamespaceCount() const;
|
|
void _FreeNamespaces();
|
|
|
|
int _AcquireObjects();
|
|
void _FreeObjects();
|
|
int _ObjectCount() const;
|
|
CMergedFldrItem *_GetObject(int i);
|
|
|
|
BOOL _IsFolderEvent(LONG lEvent);
|
|
LPITEMIDLIST _ILCombineBase(LPCITEMIDLIST pidlContainingBase, LPCITEMIDLIST pidlRel);
|
|
|
|
static int _DestroyObjectsProc(void *pv, void *pvData);
|
|
static int _SetOwnerProc(void *, void *);
|
|
static int _SetNotifyProc(void *, void *);
|
|
static int _DestroyNamespacesProc(void *pv, void *pvData);
|
|
|
|
BOOL _IsChildIDInternal(LPCITEMIDLIST pidl, BOOL fImmediate, int* iShellFolder);
|
|
|
|
void _GetKeyForProperty(LPWSTR pszName, LPWSTR pszValue, LPWSTR pszBuffer, INT cchBuffer);
|
|
HRESULT _AddNameSpaceFromPropertyBag(IPropertyBag *ppb, LPWSTR pszName);
|
|
HRESULT _SimpleAddNamespace(CMergedFldrNamespace *pns);
|
|
BOOL _IsOurColumn(UINT iColumn);
|
|
HRESULT _GetWhichFolderColumn(LPCITEMIDLIST pidl, LPTSTR pszBuffer, INT cchBuffer);
|
|
HRESULT _GetDestinationStorage(DWORD grfMode, IStorage **ppstg);
|
|
void _AddAllOtherNamespaces(LPITEMIDLIST *ppidl);
|
|
|
|
public:
|
|
LPITEMIDLIST _pidl; // CMergedFolder is a base class for several IShellFolders, and their IShellFolderViewCBs need access to this
|
|
|
|
private:
|
|
CLSID _clsid; // our identity
|
|
LONG _cRef; // reference count.
|
|
HDPA _hdpaNamespaces; // source _Namespace collection
|
|
HDPA _hdpaObjects; // array of (CMergedFldrItem *)
|
|
CMergedFolder *_pmfParent; // parent folder (if any)
|
|
UINT _iColumnOffset; // offset to my column set (-1 if unknown)
|
|
DWORD _dwDropEffect; // default drop effect for this folder
|
|
BOOL _fInShellView; // true if we're in the view. used in TranslateIDs.
|
|
BOOL _fDontMerge; // true means don't merge the items in the view (but still navigate like we're merged).
|
|
BOOL _fPartialMerge; // true if only some namespaces should be merged
|
|
BOOL _fCDBurn; // true means we're the cdburn case.
|
|
IStorage *_pstg; // hold onto the storage for the first namespace (default for IStorage operations).
|
|
BOOL _fAcquiring; // correct for architecture problem where state is kept in the folder about the enumeration
|
|
|
|
friend CMergedFldrEnum;
|
|
friend CMergedFldrDropTarget;
|
|
friend CMergedFldrContextMenu;
|
|
friend CMergedCategorizer;
|
|
friend CMergedFolderViewCB;
|
|
};
|
|
|
|
|
|
class CMergedFolderViewCB : public CBaseShellFolderViewCB
|
|
{
|
|
public:
|
|
CMergedFolderViewCB(CMergedFolder *pmf);
|
|
|
|
STDMETHODIMP RealMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
|
|
protected:
|
|
virtual ~CMergedFolderViewCB();
|
|
|
|
CMergedFolder *_pmf;
|
|
|
|
private:
|
|
HRESULT _OnGetWebViewTemplate(DWORD pv, UINT uViewMode, SFVM_WEBVIEW_TEMPLATE_DATA* pvi);
|
|
HRESULT _OnFSNotify(DWORD pv, LPCITEMIDLIST *ppidl, LPARAM lp);
|
|
HRESULT _RefreshObjectsWithSameName(IShellFolderView *psfv, LPITEMIDLIST pidl);
|
|
};
|
|
|
|
|
|
|
|
#endif // _mergfldr_h_
|