Click here to Skip to main content
15,885,278 members
Articles / Desktop Programming / MFC
Article

ITEMIDLIST management library

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
3 May 2000 70.5K   965   27   3
The library that helps to manage Shell ITEMIDLISTS
  • Download source files - 4 Kb
  • This library simplifies management of Windows Shell ITEMIDLISTs (further PIDLs). For me, it always has been trouble to keep track of all allocated PIDLs and to free them in time. So, I wrote this library.

    As time goes, the library has became rather messy (it's because I put there all PIDL-related functions that may be reusable). But it still helps me a lot.

    The core of this library is CPidl class. All other functions exported here are mostly supplemental.

    Constructors

    CPidl::CPidl()
    Constructs empty CPidl instance
    CPidl::CPidl(LPITEMIDLIST other)
    Constructs CPidl instance and attaches (not copies) ITEMIDLIST allocated somewhere else. At destruction time attached ITEMIDLIST will be deallocated.
    CPidl::CPidl(const CPidl& other)
    Copy constructor. Copies one instance of CPidl into another.
    CPidl::CPidl(LPCTSTR pszPath)
    Constructs CPidl instance from file or folder path. In case of error, the PIDL will be empty. It uses IShellFolder::ParseDisplayName() for getting PIDL.
    CPidl::CPidl(int nSpecialFolder)
    Constructs CPidl instance from special folder ID. (See CSIDL_XXX constants in MSDN).

    Member functions

    LPITEMIDLIST CPidl::Detach()
    Detaches contained PIDL from wrapper
    LPITEMIDLIST CPidl::Copy()
    returns a copy of contained PIDL
    void CPidl::Free()
    frees contained PIDL. This member function is called automatically at destruction time.
    CPidl::operator bool()
    conversion operator for using in boolean expressions. Will return true if contained PIDL is not NULL
    CPidl::operator LPITEMIDLIST()
    Useful conversion operator that allows to use CPidlas a function argument in place of LPITEMIDLIST
    CPidl::operator LPITEMIDLIST*()
    CPidl::operator LPCITEMIDLIST*()
    Useful conversion operator that allows to use CPidl as a function argument in place of LPITEMIDLIST*. Usually the pointer to LPITEMIDLIST is used to receive when a PIDL from function. Make sure you call CPidl::Free() before using CPidl instance for receiving PIDLs!
    CPidl& CPidl::operator=(LPITEMIDLIST other)
    CPidl& CPidl::operator=(const CPidl& other)
    Assignment operators

    Global functions

    IShellFolderPtr& GetDesktopFolder()
    returns a reference to static instance of IShellFolder interface for root namespace folder.
    IMallocPtr& GetMalloc()
    returns a reference to static instance of IMalloc interface. This interface is essential for working with PIDLs.
    int GetItemIDSize(LPCITEMIDLIST pidl)
    returns PIDL size in bytes.
    int GetItemIDCount(LPCITEMIDLIST pidl)
    returns number of elements in PIDL. If you don't know what does it mean, reread "Working with Item ID Lists" article in MSDN.
    LPBYTE GetItemIDPos(LPCITEMIDLIST pidl, int nPos)
    gets pointer to nPos'th element in PIDL or NULL if nPos exceeds number of elements in PIDL.
    LPITEMIDLIST CopyItemID(LPCITEMIDLIST pidl, int cb=-1)
    makes a copy of PIDL. cb specifies number of bytes to copy. If it's equal -1, entire PIDL will be copied.
    LPITEMIDLIST MergeItemID(LPCITEMIDLIST pidl,...)
    Merges two or more PIDLs (usually relative ones) into absolute (or fully-qualified) PIDL. The programmer should know what he's doing when he calls this function :-). Typical usage is to make fully-qualified PIDL from folder PIDL and PIDL returned by IShellFolder::EnumObjects()
    int CompareItemID(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
    int CompareItemID(LPCITEMIDLIST pidl1,int nSpecialFolder)
    int CompareItemID(int nSpecialFolder,LPCITEMIDLIST pidl2)
    Compares two PIDLs. Returns 0 if equal and -1 otherwise.
    LPITEMIDLIST GetItemIDFromPath(LPCTSTR pszPath)
    returns PIDL for file or folder name. Or NULL if error
    HRESULT SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, VOID **ppv, LPCITEMIDLIST *ppidlLast)
    Closely resembles standard shell function SHBindToParent(). It was neccessary to write it becuase it's not available on Windows 95/NT. Refer to MSDN for arguments description.
    BOOL TrackItemIDContextMenu(LPCITEMIDLIST pidlShellItem, UINT nFlags, LPPOINT ptPoint, HWND hWnd)
    BOOL TrackItemIDContextMenu(LPCTSTR pszShellItemPath, UINT nFlags, LPPOINT ptPoint, HWND hWnd)
    This function builds, shows and tracks shell context menu for PIDL or or file/folder path. It returns TRUE if user clicked on some context menu item. In case of error or if user didn't choose anything from menu it returns FALSE.
    • LPCITEMIDLIST pidlShellItem, LPCTSTR pszShellItemPath: a PIDL or path name of the shell item to show context menu for.
    • UINT nFlags: a set of TPM_XXX flags. See function TrackPopupMenu() for description
    • LPPOINT ptPoint: a point in screen coordinates where menu should appear.
    • HWND hWnd: a handle to the window - owner of the menu. It cannot be NULL

    Examples

    //
    // Dislaying shell context menu for a document derived from CDocument.
    //
    void CmyDoc::OnFileShellmenu() 
    {   
    //	check that we have valid file name and the file does exist
    	if( GetPathName().IsEmpty() ||
    		(::GetFileAttributes(GetPathName()) == 0xFFFFFFFF &&
    		 ::GetLastError() == ERROR_FILE_NOT_FOUND) )
    		return;
    	
    //	save the file if it wasn't saved
    	if( !SaveModified() )
    		return;
    
    //	get the current mouse position
    	CPoint ptMenuOrg;
    	::GetCursorPos(&ptMenuOrg);
    
    //	and, eventually, fire off
    	TrackItemIDContextMenu(GetPathName(),
    		TPM_LEFTBUTTON|TPM_LEFTALIGN|TPM_TOPALIGN,
    		&ptMenuOrg, AfxGetMainWnd()->m_hWnd);
    }

    More examples (in form of fully functional utilites) is available at my freeware page

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here


    Written By
    Belarus Belarus
    This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

    Comments and Discussions

     
    General"Send To" doesn't work Pin
    Neville Franks30-May-02 20:04
    Neville Franks30-May-02 20:04 
    GeneralFile Path from window handle Pin
    erhemas6-Oct-01 0:12
    erhemas6-Oct-01 0:12 
    GeneralTrackItemIDContextMenu in cpp-file missing Pin
    mloibl2-Dec-00 11:00
    mloibl2-Dec-00 11:00 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.