Exemplo n.º 1
0
// only one full qualified PIDL has been passed
void CShellContextMenu::SetObjects(LPITEMIDLIST pidl)
{
	// free all allocated datas
	if (m_psfFolder && bDelete)
		m_psfFolder->Release ();
	m_psfFolder = NULL;
	FreePIDLArray (m_pidlArray);
	m_pidlArray = NULL;

		// full qualified PIDL is passed so we need
	// its parent IShellFolder interface and its relative PIDL to that
	LPITEMIDLIST pidlItem = NULL;
	SHBindToParent ((LPCITEMIDLIST) pidl, IID_IShellFolder, (void **) &m_psfFolder, (LPCITEMIDLIST *) &pidlItem);	

	m_pidlArray = (LPITEMIDLIST *) malloc (sizeof (LPITEMIDLIST));	// allocate ony for one elemnt
	m_pidlArray[0] = CopyPIDL (pidlItem);


	// now free pidlItem via IMalloc interface (but not m_psfFolder, that we need later
	LPMALLOC lpMalloc = NULL;
	SHGetMalloc (&lpMalloc);
	lpMalloc->Free (pidlItem);
	lpMalloc->Release();

	nItems = 1;
	bDelete = TRUE;	// indicates that m_psfFolder should be deleted by CShellContextMenu
}
BOOL COXShellNamespaceNavigator::
GetShellFolderRelativeIDL(const LPSHELLFOLDER lpParentFolder,
						  CString sFolderRelativePath, 
						  LPITEMIDLIST* ppidlRelative) const
{
	ASSERT(lpParentFolder!=NULL);
	ASSERT(ppidlRelative!=NULL);

	OLECHAR unicodeFolderPath[MAX_PATH];

#ifndef _UNICODE
	UTBStr::mbstowcs(unicodeFolderPath,MAX_PATH,sFolderRelativePath,MAX_PATH);
#else
	UTBStr::tcscpy(unicodeFolderPath, MAX_PATH, sFolderRelativePath);
#endif

	LPITEMIDLIST lpidl;
    ULONG chEaten;
    ULONG dwAttributes;
    HRESULT hResult=lpParentFolder->
		ParseDisplayName(m_pOwnerWnd!=NULL ? m_pOwnerWnd->GetSafeHwnd() : NULL,
		NULL,unicodeFolderPath,&chEaten,&lpidl,&dwAttributes);
	if(FAILED(hResult))
	{
		m_pMalloc->Free(lpidl);
        return FALSE;
	}

	*ppidlRelative=CopyPIDL(lpidl);
	m_pMalloc->Free(lpidl);

	return TRUE;
}
Exemplo n.º 3
0
// this is workaround function for the Shell API Function SHBindToParent
// SHBindToParent is not available under Win95/98
HRESULT CShellContextMenu::SHBindToParentEx (LPCITEMIDLIST pidl, REFIID riid, VOID **ppv, LPCITEMIDLIST *ppidlLast)
{
	HRESULT hr = 0;
	if (!pidl || !ppv)
		return E_POINTER;
	
	int nCount = GetPIDLCount (pidl);
	if (nCount == 0)	// desktop pidl of invalid pidl
		return E_POINTER;

	IShellFolder * psfDesktop = NULL;
	SHGetDesktopFolder (&psfDesktop);
	if (nCount == 1)	// desktop pidl
	{
		if ((hr = psfDesktop->QueryInterface(riid, ppv)) == S_OK)
		{
			if (ppidlLast) 
				*ppidlLast = CopyPIDL (pidl);
		}
		psfDesktop->Release ();
		return hr;
	}

	LPBYTE pRel = GetPIDLPos (pidl, nCount - 1);
	LPITEMIDLIST pidlParent = NULL;
	pidlParent = CopyPIDL (pidl, pRel - (LPBYTE) pidl);
	IShellFolder * psfFolder = NULL;
	
	if ((hr = psfDesktop->BindToObject (pidlParent, NULL, __uuidof (psfFolder), (void **) &psfFolder)) != S_OK)
	{
		free (pidlParent);
		psfDesktop->Release ();
		return hr;
	}
	if ((hr = psfFolder->QueryInterface (riid, ppv)) == S_OK)
	{
		if (ppidlLast)
			*ppidlLast = CopyPIDL ((LPCITEMIDLIST) pRel);
	}
	free (pidlParent);
	psfFolder->Release ();
	psfDesktop->Release ();
	return hr;
}
Exemplo n.º 4
0
void CShellContextMenu::SetObjects(const QStringList &strList)
{
	// free all allocated datas
	if (m_psfFolder && bDelete)
		m_psfFolder->Release ();
	m_psfFolder = NULL;
	FreePIDLArray (m_pidlArray);
	m_pidlArray = NULL;
	
	// get IShellFolder interface of Desktop (root of shell namespace)
	IShellFolder * psfDesktop = NULL;
	SHGetDesktopFolder (&psfDesktop);	// needed to obtain full qualified pidl

	// ParseDisplayName creates a PIDL from a file system path relative to the IShellFolder interface
	// but since we use the Desktop as our interface and the Desktop is the namespace root
	// that means that it's a fully qualified PIDL, which is what we need
	LPITEMIDLIST pidl = NULL;
	
	psfDesktop->ParseDisplayName (NULL, 0, (LPOLESTR)strList[0].utf16(), NULL, &pidl, NULL);

	// now we need the parent IShellFolder interface of pidl, and the relative PIDL to that interface
	LPITEMIDLIST pidlItem = NULL;	// relative pidl
	SHBindToParentEx (pidl, IID_IShellFolder, (void **) &m_psfFolder, NULL);
	free (pidlItem);
	// get interface to IMalloc (need to free the PIDLs allocated by the shell functions)
	LPMALLOC lpMalloc = NULL;
	SHGetMalloc (&lpMalloc);
	lpMalloc->Free (pidl);

	// now we have the IShellFolder interface to the parent folder specified in the first element in strArray
	// since we assume that all objects are in the same folder (as it's stated in the MSDN)
	// we now have the IShellFolder interface to every objects parent folder
	
	IShellFolder * psfFolder = NULL;
	nItems = strList.size ();
	for (int i = 0; i < nItems; i++)
	{
                pidl=0;
		psfDesktop->ParseDisplayName (NULL, 0, (LPOLESTR)strList[i].utf16(), NULL, &pidl, NULL);
                if (pidl)
                {
                     m_pidlArray = (LPITEMIDLIST *) realloc (m_pidlArray, (i + 1) * sizeof (LPITEMIDLIST));
                     // get relative pidl via SHBindToParent
                     SHBindToParentEx (pidl, IID_IShellFolder, (void **) &psfFolder, (LPCITEMIDLIST *) &pidlItem);
                     m_pidlArray[i] = CopyPIDL (pidlItem);	// copy relative pidl to pidlArray
                     free (pidlItem);
                     lpMalloc->Free (pidl);		// free pidl allocated by ParseDisplayName
                     psfFolder->Release ();
                }
	}
	lpMalloc->Release ();
	psfDesktop->Release ();

	bDelete = TRUE;	// indicates that m_psfFolder should be deleted by CShellContextMenu
}
LPITEMIDLIST COXShellNamespaceNavigator::ConcatenatePIDLs(LPCITEMIDLIST pidl1, 
														  LPCITEMIDLIST pidl2) const
{
	LPITEMIDLIST pidlNew;
	UINT cb1, cb2;
	cb1=cb2=0;

	//are both of these NULL?
	if(!pidl1 && !pidl2)
		return NULL;

	//if pidl1 is NULL, just return a copy of pidl2
	if(!pidl1)
	{
		pidlNew=CopyPIDL(pidl2);
		return pidlNew;
	}

	//if pidl2 is NULL, just return a copy of pidl1
	if(!pidl2)
	{
		pidlNew=CopyPIDL(pidl1);
		return pidlNew;
	}


	cb1=GetIDLSize(pidl1)-sizeof(pidl1->mkid.cb);
	cb2=GetIDLSize(pidl2);

	//create the new PIDL
	pidlNew=(LPITEMIDLIST)m_pMalloc->Alloc(cb1+cb2);

	if(pidlNew)
	{
		//copy the first PIDL
		CopyMemory(pidlNew,pidl1,cb1);
		//copy the second PIDL
		CopyMemory(((LPBYTE)pidlNew)+cb1,pidl2,cb2);
	}

	return pidlNew;
}
LPSHELLFOLDER COXShellNamespaceNavigator::
GetParentShellFolder(LPCITEMIDLIST pidlFull, LPITEMIDLIST* lppRelativeIDL) const
{
	ASSERT(lppRelativeIDL!=NULL);

	if(pidlFull==NULL)
	{
		// Retrieve the Desktop's IShellFolder interface. 
		LPSHELLFOLDER lpDesktopFolder;
		if(FAILED(SHGetDesktopFolder(&lpDesktopFolder)))
			return NULL;

		ASSERT(lpDesktopFolder!=NULL);
		if(lpDesktopFolder!=NULL)
			m_mapIShellFolderToRelease.SetAt((DWORD_PTR)lpDesktopFolder,NULL);
		return lpDesktopFolder;
	}

	UINT cbTotal=0;
	LPITEMIDLIST pidlTemp=(LPITEMIDLIST)pidlFull;

	// add the size of the NULL terminating mkid.cb  - !!!!2 bytes!!!!
	cbTotal+=sizeof(pidlTemp->mkid.cb);
	while(pidlTemp && pidlTemp->mkid.cb)
	{
		LPITEMIDLIST pidlLast=pidlTemp;
		UINT cb=pidlTemp->mkid.cb;
        cbTotal+=cb;
		pidlTemp=GetNextIDLItem(pidlTemp);
		if(pidlTemp==NULL)
		{
	        cbTotal-=cb;
			*lppRelativeIDL=CopyPIDL(pidlLast);
		}
	}  

	LPITEMIDLIST pidlTarget=(LPITEMIDLIST)m_pMalloc->Alloc(cbTotal);
	if(!pidlTarget)
		return (NULL);
	::memset(pidlTarget,0,cbTotal);
	
	// Copy the source to the target
	CopyMemory(pidlTarget,(LPITEMIDLIST)pidlFull,cbTotal-sizeof(pidlTemp->mkid.cb));

	LPSHELLFOLDER pShellFolder=GetShellFolder(pidlTarget);

	m_pMalloc->Free(pidlTarget);

	return pShellFolder;
}
Exemplo n.º 7
0
HRESULT CContextMenuHelper::SHGetContextMenu(std::vector<LPCTSTR> files) {
    HRESULT hr;
    IMalloc *pm = NULL;
    IShellFolder *pDesktop = NULL;
    IShellFolder *psf = NULL;
    LPITEMIDLIST pidl = NULL;
    WCHAR fwname[MAX_PATH + 1];

    if (SUCCEEDED(hr = SHGetMalloc(&pm))) {
        if (SUCCEEDED(hr = SHGetDesktopFolder(&pDesktop))) {
            std::vector<LPITEMIDLIST> pidls;
            IShellFolder* psfFolder = NULL;
            for (UINT i = 0; SUCCEEDED(hr) && i < files.size(); i++) {
                LPCTSTR lpszFilePath = files[i];

                ULONG cch;
                ULONG attrs;

                // Convert to Unicode
                memset(fwname, L'\0', (MAX_PATH + 1) * sizeof(WCHAR));
                MultiByteToWideChar(CP_THREAD_ACP, 0, lpszFilePath, -1, fwname, MAX_PATH);
                if (SUCCEEDED(hr = pDesktop->ParseDisplayName(m_hWnd, NULL, fwname, &cch, &pidl, &attrs))) {
                    LPITEMIDLIST pidlItem = NULL;
                    if (SUCCEEDED(hr = SHBindToParentEx((LPCITEMIDLIST)pidl, IID_IShellFolder, (void **)&psf, (LPCITEMIDLIST *) &pidlItem, pDesktop, pm))) {
                        pidls.push_back(CopyPIDL(pidlItem, pm));
                        pm->Free(pidlItem);
                        if (psfFolder == NULL) {
                            // Remember first folder and we wiil show menu for this one
                            // All other folder will be ignored
                            psfFolder = psf;
                        } else {
                            psf->Release();
                        }
                    }
                    pm->Free(pidl);
                }
            }
            if (SUCCEEDED(hr) && psfFolder != NULL) {
                hr = psfFolder->GetUIObjectOf(m_hWnd, pidls.size(), const_cast<LPCITEMIDLIST*>(pidls.begin()), IID_IContextMenu, NULL, (void**)&m_lpcm);
                psfFolder->Release();
            }
            FreeItemIDList(pidls, pm);
            pDesktop->Release();
        }
        pm->Release();
    }

    return hr;
}
Exemplo n.º 8
0
// IShellFolder interface with a relative pidl has been passed
void CShellContextMenu::SetObjects(IShellFolder *psfFolder, LPITEMIDLIST pidlItem)
{
	// free all allocated datas
	if (m_psfFolder && bDelete)
		m_psfFolder->Release ();
	m_psfFolder = NULL;
	FreePIDLArray (m_pidlArray);
	m_pidlArray = NULL;

	m_psfFolder = psfFolder;

	m_pidlArray = (LPITEMIDLIST *) malloc (sizeof (LPITEMIDLIST));
	m_pidlArray[0] = CopyPIDL (pidlItem);
	
	nItems = 1;
	bDelete = FALSE;	// indicates wheter m_psfFolder should be deleted by CShellContextMenu
}
BOOL COXShellNamespaceNavigator::
GetShellFolderFullIDL(CString sFolderFullPath,
					  LPITEMIDLIST* ppidlFull) const
{
	ASSERT(ppidlFull!=NULL);

	// If lpcsFolderFullPath is NULL then just return the Desktop's IDL which is NULL
	if(sFolderFullPath.IsEmpty())
	{
		*ppidlFull=NULL;
		return TRUE;
	}

	// First of all get the Desktop's IShellFolder interface. 
	LPSHELLFOLDER lpDesktopFolder;
    if(FAILED(SHGetDesktopFolder(&lpDesktopFolder)))
        return FALSE;


	OLECHAR unicodeFolderPath[MAX_PATH];

#ifndef _UNICODE
	UTBStr::mbstowcs(unicodeFolderPath,MAX_PATH,sFolderFullPath,MAX_PATH);
#else
	UTBStr::tcscpy(unicodeFolderPath, MAX_PATH, sFolderFullPath);
#endif

	LPITEMIDLIST lpidl;
    ULONG chEaten;
    ULONG dwAttributes;
    HRESULT hResult=lpDesktopFolder->
		ParseDisplayName(m_pOwnerWnd!=NULL ? m_pOwnerWnd->GetSafeHwnd() : NULL,
		NULL,unicodeFolderPath,&chEaten,&lpidl,&dwAttributes);
	if(FAILED(hResult))
	{
		lpDesktopFolder->Release();
		m_pMalloc->Free(lpidl);
        return FALSE;
	}

	*ppidlFull=CopyPIDL(lpidl);
	lpDesktopFolder->Release();
	m_pMalloc->Free(lpidl);

	return TRUE;
}
Exemplo n.º 10
0
void CShellContextMenu::SetObjects(IShellFolder * psfFolder, LPITEMIDLIST *pidlArray, int nItemCount)
{
	// free all allocated datas
	if (m_psfFolder && bDelete)
		m_psfFolder->Release ();
	m_psfFolder = NULL;
	FreePIDLArray (m_pidlArray);
	m_pidlArray = NULL;

	m_psfFolder = psfFolder;

	m_pidlArray = (LPITEMIDLIST *) malloc (nItemCount * sizeof (LPITEMIDLIST));

	for (int i = 0; i < nItemCount; i++)
		m_pidlArray[i] = CopyPIDL (pidlArray[i]);

	nItems = nItemCount;
	bDelete = FALSE;	// indicates wheter m_psfFolder should be deleted by CShellContextMenu
}
Exemplo n.º 11
0
// this is workaround function for the Shell API Function SHBindToParent
// SHBindToParent is not available under Win95/98
HRESULT CContextMenuHelper::SHBindToParentEx(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast, IShellFolder *psfDesktop, IMalloc *pm) {
    HRESULT hr = 0;
    if (pidl == NULL || ppv == NULL) {
        return E_POINTER;
    }

    IShellFolder *psfFolder = NULL;
    if (SUCCEEDED(hr == psfDesktop->QueryInterface(riid, (LPVOID*)&psfFolder))) {
        IShellFolder *psfParent = NULL;

        // For each pidl component, bind to folder
        LPITEMIDLIST pidlNext, pidlLast;
        pidlNext = NEXTPIDL(pidl);
        pidlLast = (LPITEMIDLIST)pidl;
        
        while (pidlNext->mkid.cb != 0) {
            
            UINT uSave = pidlNext->mkid.cb;     //stop the chain temporarily
            pidlNext->mkid.cb = 0;              //so we can bind to the next folder 1 deeper
            if (!SUCCEEDED(hr = psfFolder->BindToObject(pidlLast, NULL, riid, (LPVOID*)&psfParent))) {
                return hr;
            }
            pidlNext->mkid.cb = uSave;          //restore the chain

            psfFolder->Release();               //and set up to work with the next-level folder
            psfFolder = psfParent;
            pidlLast = pidlNext;

            pidlNext = NEXTPIDL(pidlNext);      //advance to next pidl
        }

        if (ppidlLast != NULL) {
            *ppidlLast = CopyPIDL((LPCITEMIDLIST)pidlLast, pm);
        }
        *ppv = psfFolder;
    }
    return hr;
}
Exemplo n.º 12
0
void CShellContextMenu::SetObjects(CString &strArray)
{
	// free all allocated datas
	if (m_psfFolder && bDelete)
		m_psfFolder->Release ();
	m_psfFolder = NULL;
	FreePIDLArray (m_pidlArray);
	m_pidlArray = NULL;
	
	// get IShellFolder interface of Desktop (root of shell namespace)
	IShellFolder * psfDesktop = NULL;
	SHGetDesktopFolder (&psfDesktop);	// needed to obtain full qualified pidl

	// ParseDisplayName creates a PIDL from a file system path relative to the IShellFolder interface
	// but since we use the Desktop as our interface and the Desktop is the namespace root
	// that means that it's a fully qualified PIDL, which is what we need
	LPITEMIDLIST pidl = NULL;
	
#ifndef _UNICODE
	OLECHAR * olePath = (OLECHAR *) calloc (strArray.GetLength () + 1, sizeof (OLECHAR));
	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR)strArray, -1, olePath, strArray.GetLength () + 1);	
	psfDesktop->ParseDisplayName (NULL, 0, olePath, NULL, &pidl, NULL);
	free (olePath);
#else
	psfDesktop->ParseDisplayName (NULL, 0, strArray.GetBuffer (0), NULL, &pidl, NULL);
#endif

	// now we need the parent IShellFolder interface of pidl, and the relative PIDL to that interface
	LPITEMIDLIST pidlItem = NULL;	// relative pidl
	SHBindToParentEx (pidl, IID_IShellFolder, (void **) &m_psfFolder, NULL);
	free (pidlItem);
	// get interface to IMalloc (need to free the PIDLs allocated by the shell functions)
	LPMALLOC lpMalloc = NULL;
	SHGetMalloc (&lpMalloc);
	lpMalloc->Free (pidl);

	// now we have the IShellFolder interface to the parent folder specified in the first element in strArray
	// since we assume that all objects are in the same folder (as it's stated in the MSDN)
	// we now have the IShellFolder interface to every objects parent folder
	
	IShellFolder * psfFolder = NULL;
	nItems = 1;
	for (int i = 0; i < nItems; i++)
	{
#ifndef _UNICODE
		olePath = (OLECHAR *) calloc (strArray.GetLength () + 1, sizeof (OLECHAR));
		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (strArray), -1, olePath, strArray.GetLength () + 1);	
		psfDesktop->ParseDisplayName (NULL, 0, olePath, NULL, &pidl, NULL);
		free (olePath);
#else
		psfDesktop->ParseDisplayName (NULL, 0, strArray.GetBuffer (0), NULL, &pidl, NULL);
#endif
		m_pidlArray = (LPITEMIDLIST *) realloc (m_pidlArray, (i + 1) * sizeof (LPITEMIDLIST));
		// get relative pidl via SHBindToParent
		SHBindToParentEx (pidl, IID_IShellFolder, (void **) &psfFolder, (LPCITEMIDLIST *) &pidlItem);
		m_pidlArray[i] = CopyPIDL (pidlItem);	// copy relative pidl to pidlArray
		free (pidlItem);
		lpMalloc->Free (pidl);		// free pidl allocated by ParseDisplayName
		psfFolder->Release ();
	}
	lpMalloc->Release ();
	psfDesktop->Release ();

	bDelete = TRUE;	// indicates that m_psfFolder should be deleted by CShellContextMenu
}
LPNAMESPACEOBJECT COXShellNamespaceNavigator::
GetNameSpaceObject(const LPSHELLFOLDER lpsfParent,
				   const LPITEMIDLIST lpRelativeIDL, 
				   const LPITEMIDLIST lpFullIDL) const
{
	ASSERT(lpsfParent!=NULL);
	ASSERT(lpRelativeIDL!=NULL);

	// Information about currently enumerated object can be retrieved using
	// IShellFolder::GetAttributesOf method
	//
/*
HRESULT GetAttributesOf(
    UINT cidl,
    LPCITEMIDLIST *apidl,
    ULONG *rgfInOut
   );	

Retrieves the attributes of one or more file objects or subfolders. 

Returns NOERROR if successful, or an OLE-defined error value otherwise. 

cidl			-	Number of file objects from which to retrieve attributes. 
apidl			-	Address of an array of pointers to ITEMIDLIST structures, each 
					of which uniquely identifies a file object relative to the parent 
					folder. Each ITEMIDLIST structure must contain exactly one 
					SHITEMID structure followed by a terminating zero. 
rgfInOut		-	Address of a single ULONG value that, on entry, contains the 
					attributes that the caller is requesting. On exit, this value 
					contains the requested attributes that are common to all of the 
					specified objects. Note that this is the address of a single 
					ULONG value, not an array of ULONG values. The lists below 
					describe the possible flags for this parameter. 

For list of flags refer to the documentation. I list here only ones we are
particular interested in:

SFGAO_HASSUBFOLDER		-	The specified folders have subfolders (and are, therefore, 
							expandable in the left pane of Windows Explorer).  
SFGAO_FILESYSTEM		-	The specified folders or file objects are part of the 
							file system (that is, they are files, directories, or 
							root directories).  
SFGAO_FILESYSANCESTOR	-	The specified folders contain one or more file system 
							folders.  
SFGAO_FOLDER			-	The specified items are folders.  
SFGAO_REMOVABLE			-	The specified file objects or folders are on removable 
							media.  
SFGAO_VALIDATE			-	Validate cached information. The shell will validate that 
							the objects specified in a pidl still exist and will not 
							used cached information when retrieving the attributes. 
							If one or more of the items specified in a pidl no longer 
							exist, this method will return an error code. If cidl is 
							zero, the shell will discard all cached information for 
							the shell folder. This is similar to doing a refresh of 
							the folder.  
*/
	DWORD dwFilter=0xffffffff;
	lpsfParent->GetAttributesOf(1,(LPCITEMIDLIST*)&lpRelativeIDL,&dwFilter);

	// First of all, allocate memory for NAMESPACEOBJECT structure
	// using our m_pMalloc object
	LPNAMESPACEOBJECT lpNameSpaceObject=(LPNAMESPACEOBJECT)m_pMalloc->
		Alloc(sizeof(NAMESPACEOBJECT));
	// IMalloc::Alloc returns NULL if insufficient memory
	if(lpNameSpaceObject==NULL)
		return NULL;

	// store parent folder's IShellFolder
	lpNameSpaceObject->lpsfParent=lpsfParent;
	// whenever you save a pointer to COM object don't forget to 
	// add reference
	lpsfParent->AddRef();

	// make copy of enumerated shell object relative PIDL to save 
	// it in NAMESPACEOBJECT structure
	lpNameSpaceObject->lpRelativeIDL=CopyPIDL(lpRelativeIDL);
	// Create full qualified PIDL by concatenating parent's full
	// qualified PIDL lpParentFullIDL with current relative PIDL lpidl
	lpNameSpaceObject->lpFullIDL=CopyPIDL(lpFullIDL);
					
	// We save text, images (including selected) and filter flags 
	// for the object
	lpNameSpaceObject->dwFlags=dwFilter;

	// The item text is the display name of the object. 
	CString sDisplayName=GetDisplayName(lpsfParent,lpRelativeIDL);
	if(sDisplayName.IsEmpty())
		return NULL;

	lstrcpy(lpNameSpaceObject->szDisplayName,(LPCTSTR)sDisplayName);

	// The last thing we have to get are item's icons for normal
	// and selected state. Use COXShellNamespaceNavigator::GetShellImageList
	// function in order to retrieve image list of all icons used to 
	// display shell objects. Now we need to request item index of 
	// particular shell object. To accomplish this task we use 
	// SHGetFileInfo function (remember that we have to use fully qualified 
	// PIDL with that function)
	//

	// SHFILEINFO structure to be used with SH* functions
	SHFILEINFO sfi;

	// Request icon index for normal state
	SHGetFileInfo((LPCTSTR)lpNameSpaceObject->lpFullIDL,0,&sfi,
		sizeof(SHFILEINFO),SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
	lpNameSpaceObject->nImageSmall=sfi.iIcon;

	// Request icon index for selected state
	SHGetFileInfo((LPCTSTR)lpNameSpaceObject->lpFullIDL,0,&sfi,
		sizeof(SHFILEINFO),SHGFI_PIDL|SHGFI_SYSICONINDEX|
		SHGFI_SMALLICON|SHGFI_OPENICON);
	lpNameSpaceObject->nImageSelectedSmall=sfi.iIcon;

	// Request icon index for normal state
	SHGetFileInfo((LPCTSTR)lpNameSpaceObject->lpFullIDL,0,&sfi,
		sizeof(SHFILEINFO),SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_LARGEICON);
	lpNameSpaceObject->nImage=sfi.iIcon;

	// Request icon index for selected state
	SHGetFileInfo((LPCTSTR)lpNameSpaceObject->lpFullIDL,0,&sfi,
		sizeof(SHFILEINFO),SHGFI_PIDL|SHGFI_SYSICONINDEX|
		SHGFI_LARGEICON|SHGFI_OPENICON);
	lpNameSpaceObject->nImageSelected=sfi.iIcon;

	return lpNameSpaceObject;
}