218 lines
4.6 KiB
C++
218 lines
4.6 KiB
C++
// SmartInterfacePtr.h: interface for the TInterfacePtr class.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2000-2001 by Paolo Messina
|
|
// (http://www.geocities.com/ppescher - ppescher@yahoo.com)
|
|
//
|
|
// The contents of this file are subject to the Artistic License (the "License").
|
|
// You may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at:
|
|
// http://www.opensource.org/licenses/artistic-license.html
|
|
//
|
|
// If you find this code useful, credits would be nice!
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#if !defined(AFX_SHELLWRAPPERS_H__B0E1BBE7_A5D8_4A80_9A36_ED5553FE74F6__INCLUDED_)
|
|
#define AFX_SHELLWRAPPERS_H__B0E1BBE7_A5D8_4A80_9A36_ED5553FE74F6__INCLUDED_
|
|
|
|
#include <shlobj.h>
|
|
#include "SmartInterfacePtr.h"
|
|
|
|
#if _MSC_VER > 1000
|
|
#pragma once
|
|
#endif // _MSC_VER > 1000
|
|
|
|
class SMallocPtr : public TStaticInterfacePtr<IMalloc>
|
|
{
|
|
public:
|
|
SMallocPtr()
|
|
{
|
|
if (m_pIface == NULL)
|
|
SHGetMalloc(&m_pIface);
|
|
else
|
|
m_pIface->AddRef();
|
|
}
|
|
};
|
|
|
|
class SDesktopFolderPtr : public TStaticInterfacePtr<IShellFolder>
|
|
{
|
|
public:
|
|
SDesktopFolderPtr()
|
|
{
|
|
if (m_pIface == NULL)
|
|
SHGetDesktopFolder(&m_pIface);
|
|
else
|
|
m_pIface->AddRef();
|
|
}
|
|
};
|
|
|
|
class SShellFolderPtr : public TInterfacePtr<IShellFolder>
|
|
{
|
|
public:
|
|
SShellFolderPtr() {}
|
|
|
|
SShellFolderPtr(IShellFolder* pFolder) { Copy(pFolder); }
|
|
SShellFolderPtr(IShellFolder* pParentFolder, LPCITEMIDLIST pidlRel)
|
|
{
|
|
if (pidlRel != NULL && pidlRel->mkid.cb == 0)
|
|
{
|
|
// it's a root element, copy the parent folder
|
|
Copy(pParentFolder);
|
|
}
|
|
else
|
|
{
|
|
pParentFolder->BindToObject(pidlRel,
|
|
NULL, IID_IShellFolder, (LPVOID*)&m_pIface);
|
|
}
|
|
}
|
|
|
|
SShellFolderPtr(LPCITEMIDLIST pidlAbs)
|
|
{
|
|
SDesktopFolderPtr pDesktopFolder;
|
|
if (pidlAbs != NULL && pidlAbs->mkid.cb == 0)
|
|
{
|
|
// it's a root element, copy the parent folder
|
|
Copy(pDesktopFolder);
|
|
}
|
|
else
|
|
{
|
|
pDesktopFolder->BindToObject(pidlAbs,
|
|
NULL, IID_IShellFolder, (LPVOID*)&m_pIface);
|
|
}
|
|
}
|
|
};
|
|
|
|
class SEnumIDListPtr : public TInterfacePtr<IEnumIDList>
|
|
{
|
|
public:
|
|
SEnumIDListPtr(IShellFolder* pParentFolder, UINT nFlags, HWND hOwner = NULL)
|
|
{
|
|
pParentFolder->EnumObjects(hOwner, nFlags, &m_pIface);
|
|
}
|
|
};
|
|
|
|
class SContextMenuPtr : public TInterfacePtr<IContextMenu>
|
|
{
|
|
public:
|
|
SContextMenuPtr() {}
|
|
|
|
SContextMenuPtr(IShellFolder* pParentFolder, LPCITEMIDLIST pidlRel, HWND hOwner = NULL)
|
|
{
|
|
pParentFolder->GetUIObjectOf(hOwner, 1, &pidlRel,
|
|
IID_IContextMenu, NULL, (LPVOID*)&m_pIface);
|
|
}
|
|
};
|
|
|
|
class SContextMenu2Ptr : public TInterfacePtr<IContextMenu2>
|
|
{
|
|
public:
|
|
SContextMenu2Ptr(IContextMenu* pIface)
|
|
{
|
|
if (pIface != NULL)
|
|
pIface->QueryInterface(IID_IContextMenu2, (LPVOID*)&m_pIface);
|
|
}
|
|
};
|
|
|
|
// templates
|
|
|
|
template <class TYPE>
|
|
class TSharedObject
|
|
{
|
|
public:
|
|
~TSharedObject()
|
|
{ Destroy(); }
|
|
|
|
protected:
|
|
TYPE* m_pObj;
|
|
|
|
TSharedObject()
|
|
{ m_pObj = NULL; }
|
|
|
|
TSharedObject(const TSharedObject& shobj)
|
|
{ Copy(shobj); }
|
|
|
|
void Copy(const TSharedObject& shobj);
|
|
|
|
public:
|
|
operator const TYPE * () const
|
|
{ return m_pObj; }
|
|
|
|
const TSharedObject& operator = (const TSharedObject& shobj)
|
|
{
|
|
Destroy();
|
|
Copy(shobj);
|
|
|
|
return *this;
|
|
}
|
|
|
|
BOOL IsValid() const
|
|
{ return m_pObj != NULL; }
|
|
|
|
void Attach(TYPE* pObj)
|
|
{
|
|
ASSERT(m_pObj == NULL); // can't attach two times!
|
|
m_pObj = pObj;
|
|
}
|
|
|
|
TYPE* Detach()
|
|
{
|
|
TYPE* ret = m_pObj;
|
|
m_pObj = NULL;
|
|
return ret;
|
|
}
|
|
|
|
// obtain a void object by pointer
|
|
TYPE** GetPointer()
|
|
{
|
|
Destroy();
|
|
return &m_pObj;
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void DumpRaw(CDumpContext& dc) const
|
|
{
|
|
dc << "addr = " << (void*)m_pObj << "\n";
|
|
if (m_pObj == NULL)
|
|
return;
|
|
|
|
SMallocPtr pMalloc;
|
|
ULONG size = pMalloc->GetSize((void*)m_pObj);
|
|
cd << "[hex dump]\n";
|
|
dc.HexDump(".", (BYTE*)m_pObj, (int)size, 16);
|
|
dc << "\n";
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
protected:
|
|
|
|
void Destroy()
|
|
{
|
|
SMallocPtr pMalloc;
|
|
pMalloc->Free(Detach());
|
|
}
|
|
};
|
|
|
|
template <class TYPE>
|
|
void TSharedObject<TYPE>::Copy(const TSharedObject& shobj)
|
|
{
|
|
m_pObj = NULL;
|
|
if (shobj.m_pObj == NULL)
|
|
return;
|
|
|
|
// obj to copy must have been allocated this way
|
|
SMallocPtr pMalloc;
|
|
ULONG size = (ULONG)pMalloc->GetSize((void*)shobj.m_pObj);
|
|
ASSERT(size > 0);
|
|
|
|
if (shobj.m_pObj != NULL)
|
|
{
|
|
m_pObj = (TYPE*)pMalloc->Alloc(size);
|
|
CopyMemory(m_pObj, shobj.m_pObj, size);
|
|
}
|
|
}
|
|
|
|
|
|
#endif //!defined(AFX_SHELLWRAPPERS_H__B0E1BBE7_A5D8_4A80_9A36_ED5553FE74F6__INCLUDED_)
|