📄 isf.cpp
字号:
/*****************************************************************************\
DESCRIPTION:
\*****************************************************************************/
HRESULT CBaseFolder::Initialize(LPCITEMIDLIST pidl)
{
ASSERT(!m_pidl); // Don't reroot us.
return _Initialize(pidl, NULL, ILGetSize(pidl) - sizeof(pidl->mkid.cb));
}
//===========================
// *** IPersistFolder2 Interface ***
//===========================
/*****************************************************************************\
DESCRIPTION:
\*****************************************************************************/
HRESULT CBaseFolder::GetCurFolder(LPITEMIDLIST *ppidl)
{
HRESULT hr = E_INVALIDARG;
if (EVAL(ppidl))
{
hr = E_FAIL;
if (m_pidlRoot)
{
*ppidl = ILClone(m_pidlRoot);
}
else if (EVAL(m_pidl))
{
*ppidl = GetPublicTargetPidlClone();
}
if (*ppidl)
hr = S_OK;
}
return hr;
}
//===========================
// *** IPersistFolder3 Interface ***
//===========================
HRESULT GetPidlFromPersistFolderTargetInfo(const PERSIST_FOLDER_TARGET_INFO *ppfti, LPITEMIDLIST * ppidl, BOOL fFree)
{
HRESULT hr = E_INVALIDARG;
if (ppidl)
{
*ppidl = NULL;
if (ppfti->pidlTargetFolder)
{
*ppidl = (fFree ? ppfti->pidlTargetFolder : ILClone(ppfti->pidlTargetFolder));
if (*ppidl)
hr = S_OK;
else
hr = E_OUTOFMEMORY;
}
else
{
if (ppfti->szTargetParsingName[0])
{
hr = IEParseDisplayNameWithBCW(CP_ACP, ppfti->szTargetParsingName, NULL, ppidl);
}
if (!*ppidl && (-1 != ppfti->csidl))
{
hr = SHGetSpecialFolderLocation(NULL, ppfti->csidl, ppidl);
}
}
}
return hr;
}
/*****************************************************************************\
DESCRIPTION:
\*****************************************************************************/
HRESULT CBaseFolder::InitializeEx(IBindCtx *pbc, LPCITEMIDLIST pidlRoot, const PERSIST_FOLDER_TARGET_INFO *ppfti)
{
HRESULT hr = E_INVALIDARG;
if (EVAL(pidlRoot))
{
if (ppfti)
{
// We are a Folder Shortcut.
LPITEMIDLIST pidlTarget;
hr = GetPidlFromPersistFolderTargetInfo(ppfti, &pidlTarget, FALSE); // Get the real root.
TraceMsg(TF_FOLDER_SHRTCUTS, "CBaseFolder::InitializeEx() this=%#08lx, pidlTarget=%#08lx, pidlRoot=%#08lx", this, pidlTarget, pidlRoot);
AssertMsg((NULL != pidlTarget), TEXT("CBaseFolder::InitializeEx() We are useless without a pidlTarget so watch me go limp."));
if (pidlTarget)
{
hr = _Initialize(pidlTarget, pidlRoot, m_nIDOffsetToPrivate);
ILFree(pidlTarget);
}
}
else
{
// We aren't a folder shortcut.
hr = Initialize(pidlRoot);
}
}
return hr;
}
HRESULT CBaseFolder::GetFolderTargetInfo(PERSIST_FOLDER_TARGET_INFO *ppfti)
{
HRESULT hr = E_INVALIDARG;
AssertMsg((NULL != ppfti), TEXT("CBaseFolder::GetFolderTargetInfo() Caller passed an invalid param."));
if (ppfti)
{
ZeroMemory(ppfti, sizeof(*ppfti));
ppfti->pidlTargetFolder = ILClone(m_pidlRoot);
ppfti->dwAttributes = -1;
ppfti->csidl = -1;
hr = S_OK;
}
return hr;
}
LPCITEMIDLIST CBaseFolder::GetPrivatePidlReference(void)
{
return _ILSkip(m_pidl, m_nIDOffsetToPrivate);
}
// This function always needs the InternetExplorer pidl.
LPITEMIDLIST CBaseFolder::GetPublicPidlRootIDClone(void)
{
LPITEMIDLIST pidlFull = ILClone(m_pidl);
LPITEMIDLIST pidlPrivStart = _ILSkip(pidlFull, m_nIDOffsetToPrivate);
// Strip all Private ItemIDs
while (!ILIsEmpty(pidlPrivStart))
ILRemoveLastID(pidlPrivStart);
return pidlFull;
}
LPITEMIDLIST CBaseFolder::CreateFullPrivatePidl(LPCITEMIDLIST pidlPrivateSubPidl)
{
return ILCombine(GetPrivatePidlReference(), pidlPrivateSubPidl);
}
LPITEMIDLIST CBaseFolder::CreateFullPublicPidlFromRelative(LPCITEMIDLIST pidlPrivateSubPidl)
{
return ILCombine(GetPublicRootPidlReference(), pidlPrivateSubPidl);
}
LPITEMIDLIST CBaseFolder::CreateFullPublicPidl(LPCITEMIDLIST pidlPrivatePidl)
{
LPITEMIDLIST pidlRoot = GetPublicPidlRootIDClone();
LPITEMIDLIST pidlResult = NULL;
if (pidlRoot)
{
pidlResult = ILCombine(pidlRoot, pidlPrivatePidl);
ILFree(pidlRoot);
}
return pidlResult;
}
HRESULT CBaseFolder::_Initialize(LPCITEMIDLIST pidlTarget, LPCITEMIDLIST pidlRoot, int nBytesToPrivate)
{
HRESULT hr = E_INVALIDARG;
if (pidlTarget)
{
ILFree(m_pidl);
ILFree(m_pidlRoot);
m_pidl = ILClone(pidlTarget);
m_pidlRoot = ILClone(pidlRoot); // This is the Folder Shortcut pidl. We don't use it outselves.
if (m_pidl)
{
m_nIDOffsetToPrivate = nBytesToPrivate;
hr = S_OK;
}
else
hr = E_OUTOFMEMORY;
}
return hr;
}
/****************************************************\
Constructor
\****************************************************/
CBaseFolder::CBaseFolder(LPCLSID pClassID) : m_cRef(1)
{
DllAddRef();
// This needs to be allocated in Zero Inited Memory.
// Assert that all Member Variables are inited to Zero.
ASSERT(!m_pidl);
ASSERT(!m_nIDOffsetToPrivate);
ASSERT(!m_pClassID);
m_pClassID = pClassID;
ASSERT(pClassID);
}
/****************************************************\
Destructor
\****************************************************/
CBaseFolder::~CBaseFolder()
{
Pidl_Set(&m_pidlRoot, NULL); // Folder Shortcut pidl
Pidl_Set(&m_pidl, NULL);
DllRelease();
}
//===========================
// *** IUnknown Interface ***
//===========================
ULONG CBaseFolder::AddRef()
{
m_cRef++;
return m_cRef;
}
ULONG CBaseFolder::Release()
{
ASSERT(m_cRef > 0);
m_cRef--;
if (m_cRef > 0)
return m_cRef;
delete this;
return 0;
}
HRESULT CBaseFolder::QueryInterface(REFIID riid, void **ppvObj)
{
static const QITAB qit[] = {
QITABENTMULTI(CBaseFolder, IShellFolder, IShellFolder2),
QITABENTMULTI(CBaseFolder, IPersist, IPersistFolder),
QITABENTMULTI(CBaseFolder, IPersist, IPersistFolder3),
QITABENTMULTI(CBaseFolder, IPersistFolder, IPersistFolder3),
QITABENTMULTI(CBaseFolder, IPersistFolder2, IPersistFolder3),
QITABENT(CBaseFolder, IShellFolder2),
QITABENT(CBaseFolder, IPersistFolder3),
QITABENT(CBaseFolder, IObjectWithSite),
{ 0 },
};
return QISearch(this, qit, riid, ppvObj);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -