// 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 #include "SmartInterfacePtr.h" #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class SMallocPtr : public TStaticInterfacePtr { public: SMallocPtr() { if (m_pIface == NULL) SHGetMalloc(&m_pIface); else m_pIface->AddRef(); } }; class SDesktopFolderPtr : public TStaticInterfacePtr { public: SDesktopFolderPtr() { if (m_pIface == NULL) SHGetDesktopFolder(&m_pIface); else m_pIface->AddRef(); } }; class SShellFolderPtr : public TInterfacePtr { 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 { public: SEnumIDListPtr(IShellFolder* pParentFolder, UINT nFlags, HWND hOwner = NULL) { pParentFolder->EnumObjects(hOwner, nFlags, &m_pIface); } }; class SContextMenuPtr : public TInterfacePtr { 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 { public: SContextMenu2Ptr(IContextMenu* pIface) { if (pIface != NULL) pIface->QueryInterface(IID_IContextMenu2, (LPVOID*)&m_pIface); } }; // templates template 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 void TSharedObject::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_)