Ejemplo n.º 1
0
/* #FN#
   Fills a branch of the TreeView control.
   
   Given the shell folder, enumerate the subitems of this folder, and
   add the appropriate items to the tree. This function enumerates the
   items in the folder identifed by lpsf. Note that since we are filling
   the left hand pane, we will only add items that are folders and/or
   have sub-folders. We *could* put all items in here if we wanted, but
   that's not the intent. */
void
/* #AS#
   Nothing */
CShellTree::
FillTreeView(
	LPSHELLFOLDER lpsf,   /* #IN# Pointer to shell folder that we want to enumerate items */
	LPITEMIDLIST  lpifq,  /* #IN# Fully qualified item id list to the item that we are enumerating items for; in other words, this is the PIDL to the item identified by the lpsf parameter */
	HTREEITEM     hParent /* #IN# Parent node */
)
{
	TV_ITEM         tvi;	/* TreeView Item */
	TV_INSERTSTRUCT tvins;	/* TreeView Insert Struct */

	HTREEITEM     hPrev         = NULL;	/* Previous Item Added */
	LPSHELLFOLDER lpsf2         = NULL;
	LPENUMIDLIST  lpe           = NULL;
	LPITEMIDLIST  lpi           = NULL;
	LPITEMIDLIST  lpifqThisItem = NULL;
	LPTVITEMDATA  lptvid        = NULL;
	LPMALLOC      lpMalloc      = NULL;

	ULONG   ulFetched = 0;
	HWND    hwnd      = ::GetParent( m_hWnd );
	char    szBuff[ MAX_PATH + 1 ];
	char    szPath[ MAX_PATH + 1 ];
	HRESULT hr;

	/* Allocate a shell memory object */
	hr = ::SHGetMalloc( &lpMalloc );
	if( FAILED(hr) )
		return;

	if( SUCCEEDED(hr) )
	{
		/* Get the IEnumIDList object for the given folder */
		hr = lpsf->EnumObjects( hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &lpe );

		if( S_OK == hr && lpe )
		{
			/* Enumerate throught the list of folder and non-folder objects */
			while( S_OK == lpe->Next( 1, &lpi, &ulFetched ) )
			{
				/* Create a fully qualified path to the current item. The SH* shell API's
				   take a fully qualified path pidl, (see GetIcon above where I call
				   SHGetFileInfo) whereas the interface methods take a relative path pidl */
				ULONG ulAttrs = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;

				if( !m_bFolderMode )
					ulAttrs |= SFGAO_FILESYSTEM | SFGAO_LINK;

				/* Determine what type of object we have */
				lpsf->GetAttributesOf( 1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs );

				if( m_bFolderMode && ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER) ||
				  (!m_bFolderMode && ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_FILESYSTEM) && !(ulAttrs & SFGAO_LINK)) )
				{
					tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
					/* We need this next if statement so that we don't add things like
					   the MSN to our tree. MSN is not a folder, but according to the
					   shell it has subfolders */
					/* OK, let's get some memory for our ITEMDATA struct */
					lptvid = (LPTVITEMDATA)lpMalloc->Alloc( sizeof(TVITEMDATA) );
					if( !lptvid )
						goto Done; /* Error - could not allocate memory */

					/* Now get the friendly name that we'll put in the treeview */
					if( !GetName( lpsf, lpi, SHGDN_NORMAL, szBuff ) )
						goto Done; /* Error - could not get friendly name */

					tvi.pszText    = szBuff;
					tvi.cchTextMax = MAX_PATH;

					/* Allocate/create the fully qualified PIDL, consisting
					   of the parents full PIDL and our relative PIDL */
					lpifqThisItem = ConcatPidls( lpifq, lpi );

					if( ulAttrs & SFGAO_FOLDER && (ulAttrs & SFGAO_HASSUBFOLDER ||
						/* There are not any subfolders but what about files? */
						(!m_bFolderMode && SHGetPathFromIDList( lpifqThisItem, szPath ) && !IsFolderEmpty( szPath ))) )
					{
						/* This item has sub-folders, so let's put the + in the TreeView.
						   The first time the user clicks on the item, we'll populate the
						   sub-folders */
						tvi.cChildren = 1;
						tvi.mask |= TVIF_CHILDREN;
					}
					/* Now, make a copy of the ITEMIDLIST (non-qualified) */
					lptvid->lpi = CopyITEMID( lpMalloc, lpi );

					tvi.iImage =
						GetItemIcon( lpifqThisItem,
									 SHGFI_PIDL |
									 SHGFI_SYSICONINDEX |
									 SHGFI_SMALLICON );

					tvi.iSelectedImage =
						GetItemIcon( lpifqThisItem,
									 SHGFI_PIDL |
									 SHGFI_SYSICONINDEX |
									 SHGFI_SMALLICON |
									 SHGFI_OPENICON );

					lptvid->lpsfParent = lpsf; /* Store the parent folders SF */
					lpsf->AddRef();            /* Increment our saved reference */

					/* Now create another PIDL from our Full parents PIDL and
					   the releative one that we'll save */
					lptvid->lpifq = ConcatPidls( lpifq, lpi );

					/* Populate the TreeView Insert Struct. The item is the one
					   filled above. Insert it after the last item inserted at
					   this level. And indicate this is a root entry */
					tvi.lParam         = (LPARAM)lptvid;
					tvins.item         = tvi;
					tvins.hInsertAfter = hPrev;
					tvins.hParent      = hParent;

					/* Add the item to the tree */
					hPrev = InsertItem( &tvins );

					/* Free this item with task allocator */
					lpMalloc->Free( lpifqThisItem );
					lpifqThisItem = 0;
				}
				lpMalloc->Free( lpi );  /* Free the pidl that the shell gave us */
				lpi = 0;
			}
		}
	}
	else
		return;

Done:
	if( lpe )
		lpe->Release();

	/* The following 2 if statements will only be TRUE if we got here
	   on an error condition from the "goto" statement. Otherwise, we
	   free this memory at the end of the while loop above */
	if( lpi && lpMalloc )
		lpMalloc->Free( lpi );
	if( lpifqThisItem && lpMalloc )
		lpMalloc->Free( lpifqThisItem );

	if( lpMalloc )
		lpMalloc->Release();

} /* #OF# CShellTree::FillTreeView */
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;
}
Ejemplo n.º 3
0
/****************************************************************************
*
*  FUNCTION: FillTreeView( LPSHELLFOLDER lpsf,
*                          LPITEMIDLIST  lpifq,
*                          HTREEITEM     hParent)
*
*  PURPOSE: Fills a branch of the TreeView control.  Given the
*           shell folder, enumerate the subitems of this folder,
*           and add the appropriate items to the tree.
*
*  PARAMETERS:
*    lpsf         - Pointer to shell folder that we want to enumerate items 
*    lpifq        - Fully qualified item id list to the item that we are enumerating
*                   items for.  In other words, this is the PIDL to the item
*                   identified by the lpsf parameter.
*    hParent      - Parent node
*
*  COMMENTS:
*    This function enumerates the items in the folder identifed by lpsf.
*    Note that since we are filling the left hand pane, we will only add
*    items that are folders and/or have sub-folders.  We *could* put all
*    items in here if we wanted, but that's not the intent.
*
****************************************************************************/
void CShellTreeCtrl::FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST  lpifq, HTREEITEM     hParent)
{
    TV_ITEM         tvi;                          // TreeView Item.
    TV_INSERTSTRUCT tvins;                        // TreeView Insert Struct.
    HTREEITEM       hPrev = NULL;                 // Previous Item Added.
    LPSHELLFOLDER   lpsf2=NULL;
    LPENUMIDLIST    lpe=NULL;
    LPITEMIDLIST    lpi=NULL, lpiTemp=NULL, lpifqThisItem=NULL;
    LPTVITEMDATA    lptvid=NULL;
    LPMALLOC        lpMalloc=NULL;
    ULONG           ulFetched;
    UINT            uCount=0;
    HRESULT         hr;
    char            szBuff[256];
	char			szFileName[2048];
    HWND            hwnd=::GetParent(m_hWnd);

    // Allocate a shell memory object. 
    hr=::SHGetMalloc(&lpMalloc);
    if (FAILED(hr))
       return;

    if (SUCCEEDED(hr))
    {
        // Get the IEnumIDList object for the given folder.
        hr=lpsf->EnumObjects(hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN , &lpe);

        if (SUCCEEDED(hr))
        {
            // Enumerate throught the list of folder and non-folder objects.
            while (S_OK==lpe->Next(1, &lpi, &ulFetched))
            {
                //Create a fully qualified path to the current item
                //The SH* shell api's take a fully qualified path pidl,
                //(see GetIcon above where I call SHGetFileInfo) whereas the
                //interface methods take a relative path pidl.
                ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER;

                // Determine what type of object we have.
                lpsf->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs);

                if (m_bDispFile || (ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER)))
                {
                   //We need this next if statement so that we don't add things like
                   //the MSN to our tree.  MSN is not a folder, but according to the
                   //shell it has subfolders.
                   if (m_bDispFile || (ulAttrs & SFGAO_FOLDER ))
                   {
                      tvi.mask= TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;

                      if (ulAttrs & (SFGAO_FOLDER|SFGAO_HASSUBFOLDER) )//
                      {
                         //This item has sub-folders, so let's put the + in the TreeView.
                         //The first time the user clicks on the item, we'll populate the
                         //sub-folders.
                         tvi.cChildren=1;
                         tvi.mask |= TVIF_CHILDREN;
                      }
                        
                      //OK, let's get some memory for our ITEMDATA struct
                      lptvid = (LPTVITEMDATA)lpMalloc->Alloc(sizeof(TVITEMDATA));
                      if (!lptvid)
                         goto Done;  // Error - could not allocate memory.
   
                      //Now get the friendly name that we'll put in the treeview.
                      if (!GetName(lpsf, lpi, SHGDN_NORMAL, szBuff))
                         goto Done; // Error - could not get friendly name.

					//  if (!GetName(lpsf, lpi, SHGDN_FORPARSING, szFileName))
					  if(SHGetPathFromIDList(lpi,szFileName))
					  {		
		 				  if(!(ulAttrs & SFGAO_FOLDER) && m_bDispFile)
							  if(!MatchExtensionFilter(szFileName))
								  continue;
					  }
					  else
		 				  if(!(ulAttrs & SFGAO_FOLDER) && m_bDispFile)
							  if(!MatchExtensionFilter(szBuff))
								  continue;

                      tvi.pszText    = szBuff;
                      tvi.cchTextMax = MAX_PATH;
    
                      lpifqThisItem=ConcatPidls(lpifq, lpi);
      
                      //Now, make a copy of the ITEMIDLIST
                      lptvid->lpi=CopyITEMID(lpMalloc, lpi);
   
                      GetNormalAndSelectedIcons(lpifqThisItem, &tvi);
   
                      lptvid->lpsfParent=lpsf;    //Store the parent folders SF
                      lpsf->AddRef();

                      lptvid->lpifq=ConcatPidls(lpifq, lpi);
   
                      tvi.lParam = (LPARAM)lptvid;
   
                      // Populate the TreeVeiw Insert Struct
                      // The item is the one filled above.
                      // Insert it after the last item inserted at this level.
                      // And indicate this is a root entry.
                      tvins.item         = tvi;
                      tvins.hInsertAfter = hPrev;
                      tvins.hParent      = hParent;
   
                      // Add the item to the tree
                      hPrev = InsertItem(&tvins);
                   }
                   // Free this items task allocator.
                   lpMalloc->Free(lpifqThisItem);  
                   lpifqThisItem=0;
                }

                lpMalloc->Free(lpi);  //Free the pidl that the shell gave us.
                lpi=0;
            }
        }

    }
    else
       return;

Done:
 
    if (lpe)  
        lpe->Release();

    //The following 2 if statements will only be TRUE if we got here on an
    //error condition from the "goto" statement.  Otherwise, we free this memory
    //at the end of the while loop above.
    if (lpi && lpMalloc)           
        lpMalloc->Free(lpi);
    if (lpifqThisItem && lpMalloc) 
        lpMalloc->Free(lpifqThisItem);  

    if (lpMalloc) 
        lpMalloc->Release();
}
Ejemplo n.º 4
0
void CCJShellTree::FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST  lpifq, HTREEITEM hParent)
{
    TV_ITEM         tvi;                          // TreeView Item.
    TV_INSERTSTRUCT tvins;                        // TreeView Insert Struct.
    HTREEITEM       hPrev = NULL;                 // Previous Item Added.
    LPENUMIDLIST    lpe=0;
    LPITEMIDLIST    lpi=0, lpifqThisItem=0;
    LPTVITEMDATA    lptvid=0;
    LPMALLOC        lpMalloc=0;
    ULONG           ulFetched;
    HRESULT         hr;
    TCHAR           szBuff[256];
    HWND            hwnd=GetParent()->GetSafeHwnd();

    hr=SHGetMalloc(&lpMalloc);
    if (FAILED(hr))
       return;

    // Hourglass on!

    SetCapture();
    CWaitCursor wait;   // display wait cursor

    if (SUCCEEDED(hr))
    {
		SetRedraw(FALSE);

        hr=lpsf->EnumObjects(hwnd, 
			SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &lpe);

        if (SUCCEEDED(hr))
        {
            while (S_OK==lpe->Next(1, &lpi, &ulFetched))
            {
                //Create a fully qualified path to the current item
                //The SH* shell api's take a fully qualified path pidl,
                //(see GetIcon above where I call SHGetFileInfo) whereas the
                //interface methods take a relative path pidl.

                ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER;

                lpsf->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs);

                if (ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER))
                {
                   //We need this next if statement so that we don't add things like
                   //the MSN to our tree.  MSN is not a folder, but according to the
                   //shell is has subfolders....

                   if (ulAttrs & SFGAO_FOLDER)
                   {
                      tvi.mask            = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE |
                                            TVIF_PARAM;

                      if (ulAttrs & SFGAO_HASSUBFOLDER)
                      {
                         //This item has sub-folders, so let's put the + in the TreeView.
                         //The first time the user clicks on the item, we'll populate the
                         //sub-folders then.

                         tvi.cChildren=1;
                         tvi.mask |= TVIF_CHILDREN;
                      }
                        
                      //OK, let's get some memory for our ITEMDATA struct

                      lptvid = (LPTVITEMDATA)lpMalloc->Alloc(sizeof(TVITEMDATA));
                      if (!lptvid)
                         goto Done;
   
                      //Now get the friendly name that we'll put in the treeview...

                      if( m_shell.GetName(lpsf, lpi, SHGDN_NORMAL, szBuff) == FALSE ) {
                         goto Done;
					  }

                      tvi.pszText    = szBuff;
                      tvi.cchTextMax = MAX_PATH;
    
                      lpifqThisItem=m_shell.ConcatPidls(lpifq, lpi);
      
                      //Now, make a copy of the ITEMIDLIST
      
                      lptvid->lpi=m_shell.CopyITEMID(lpMalloc, lpi);
   
                      m_shell.GetNormalAndSelectedIcons(lpifqThisItem, &tvi);
   
                      lptvid->lpsfParent=lpsf;    //Store the parent folders SF
                      lpsf->AddRef();

                      //So, you ask, what's the story here?  Why do we have 2
                      //functions that apparently do the same thing?  Well, 
                      //ParseDisplayName() (used in GetFullyQualPidl) does not 
                      //work well for non-file system objects such as the My 
                      //Computer and Net Hood.  So, since we know that these 
                      //guys will only show up when we are enumerating the root 
                      //of the namespace (as identified by an hParent of TVI_ROOT), 
                      //we special case this here.  You *could* use ConcatPidls() 
                      //in ALL cases, but the GetFullyQualPidl() is shown for 
                      //demonstration purposes, since it's the more intuative way.

//Commented out for now, since we need ConcatPidls for *any* non-file system object.
//This includes things like Control Panel, et al.

//                      if (hParent==TVI_ROOT)
                         lptvid->lpifq=m_shell.ConcatPidls(lpifq, lpi);
//                      else
//                         lptvid->lpifq=GetFullyQualPidl(lpsf, lpi);
   
                      tvi.lParam = (LPARAM)lptvid;
   
                      // Populate the TreeVeiw Insert Struct
                      // The item is the one filled above.
                      // Insert it after the last item inserted at this level.
                      // And indicate this is a root entry.
   				   
                      tvins.item         = tvi;
                      tvins.hInsertAfter = hPrev;
                      tvins.hParent      = hParent;
   
                      // Add the item to the tree
   
                      hPrev = InsertItem(&tvins);
                   }

                   lpMalloc->Free(lpifqThisItem);  
                   lpifqThisItem=0;
                }

                lpMalloc->Free(lpi);  //Finally, free the pidl that the shell gave us...
                lpi=0;
            }
        }

    }
    else {
		SetRedraw();
		return;
	}

Done:
 
    // Hourglass off!

    ReleaseCapture();

    if (lpe)  lpe->Release();

    //The following 2 if statements will only be TRUE if we got here on an
    //error condition from the "goto" statement.  Otherwise, we free this memory
    //at the end of the while loop above.
    if (lpi && lpMalloc)           lpMalloc->Free(lpi);
    if (lpifqThisItem && lpMalloc) lpMalloc->Free(lpifqThisItem);  

    if (lpMalloc) lpMalloc->Release();
	SetRedraw();
}
Ejemplo n.º 5
0
int DriveBox_Fill(HWND hwnd) {

    LPSHELLFOLDER lpsfDesktop;
    LPSHELLFOLDER lpsf; // Workspace == CSIDL_DRIVES

    LPITEMIDLIST pidl;
    LPITEMIDLIST pidlEntry;

    LPENUMIDLIST lpe;

    COMBOBOXEXITEM cbei;
    LPDC_ITEMDATA lpdcid;

    ULONG dwAttributes = 0;

    DWORD grfFlags = SHCONTF_FOLDERS;

    // Init ComboBox
    SendMessage(hwnd, WM_SETREDRAW, 0, 0);
    SendMessage(hwnd, CB_RESETCONTENT, 0, 0);

    ZeroMemory(&cbei, sizeof(COMBOBOXEXITEM));
    cbei.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_LPARAM;
    cbei.pszText = LPSTR_TEXTCALLBACK;
    cbei.cchTextMax = MAX_PATH;
    cbei.iImage = I_IMAGECALLBACK;
    cbei.iSelectedImage = I_IMAGECALLBACK;

    // Get pidl to [My Computer]
    if (NOERROR == SHGetSpecialFolderLocation(hwnd, CSIDL_DRIVES, &pidl)) {

        // Get Desktop Folder
        if (NOERROR == SHGetDesktopFolder(&lpsfDesktop)) {

            // Bind pidl to IShellFolder
            if (NOERROR == lpsfDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (void**)&lpsf)) {

                // Create an Enumeration object for lpsf
                if (NOERROR == lpsf->EnumObjects(hwnd, grfFlags, &lpe)) {

                    // Enumerate the contents of [My Computer]
                    while (NOERROR == lpe->Next(1, &pidlEntry, NULL)) {

                        // Add item to the List if it is part of the
                        // Filesystem
                        dwAttributes = SFGAO_FILESYSTEM;

                        lpsf->GetAttributesOf(1, (LPCITEMIDLIST*)&pidlEntry, &dwAttributes);

                        if (dwAttributes & SFGAO_FILESYSTEM) {

                            // Windows XP: check if pidlEntry is a drive
                            SHDESCRIPTIONID di;
                            HRESULT hr;
                            hr = SHGetDataFromIDList(lpsf, pidlEntry, SHGDFIL_DESCRIPTIONID, &di,
                                                     sizeof(SHDESCRIPTIONID));
                            if (hr != NOERROR || (di.dwDescriptionId >= SHDID_COMPUTER_DRIVE35 &&
                                                  di.dwDescriptionId <= SHDID_COMPUTER_OTHER)) {

                                lpdcid = (DC_ITEMDATA*)CoTaskMemAlloc(sizeof(DC_ITEMDATA));

                                // lpdcid->pidl = IL_Copy(pidlEntry);
                                lpdcid->pidl = pidlEntry;
                                lpdcid->lpsf = lpsf;

                                lpsf->AddRef();

                                // Insert sorted ...
                                {
                                    COMBOBOXEXITEM cbei2;
                                    LPDC_ITEMDATA lpdcid2;
                                    HRESULT hr;
                                    cbei2.mask = CBEIF_LPARAM;
                                    cbei2.iItem = 0;

                                    while ((SendMessage(hwnd, CBEM_GETITEM, 0, (LPARAM)&cbei2))) {
                                        lpdcid2 = (LPDC_ITEMDATA)cbei2.lParam;
                                        hr = (lpdcid->lpsf->CompareIDs(0, lpdcid->pidl,
                                                                       lpdcid2->pidl));

                                        if ((short)(SCODE_CODE(GetScode(hr))) < 0)
                                            break;
                                        else
                                            cbei2.iItem++;
                                    }

                                    cbei.iItem = cbei2.iItem;
                                    cbei.lParam = (LPARAM)lpdcid;
                                    SendMessage(hwnd, CBEM_INSERTITEM, 0, (LPARAM)&cbei);
                                }
                            }
                        }

                    } // IEnumIDList::Next()

                    lpe->Release();

                } // IShellFolder::EnumObjects()

                lpsf->Release();

            } // IShellFolder::BindToObject()

            CoTaskMemFree(pidl);

        } // SHGetSpecialFolderLocation()

        lpsfDesktop->Release();

    } // SHGetDesktopFolder()

    SendMessage(hwnd, WM_SETREDRAW, 1, 0);
    // Return number of items added to combo box
    return ((int)SendMessage(hwnd, CB_GETCOUNT, 0, 0));
}
Ejemplo n.º 6
0
//  Snapshots a directory and displays the items in the listview control
int DirList_Fill(HWND hwnd, const WCHAR* lpszDir, DWORD grfFlags, const WCHAR* lpszFileSpec,
                 BOOL bExcludeFilter, BOOL bNoFadeHidden, int iSortFlags, BOOL fSortRev) {

    WCHAR wszDir[MAX_PATH];

    LPSHELLFOLDER lpsfDesktop = NULL;
    LPSHELLFOLDER lpsf = NULL;

    LPITEMIDLIST pidl = NULL;
    LPITEMIDLIST pidlEntry = NULL;

    LPENUMIDLIST lpe = NULL;

    LV_ITEM lvi;
    LPLV_ITEMDATA lplvid;

    ULONG chParsed = 0;
    ULONG dwAttributes = 0;

    DL_FILTER dlf;
    SHFILEINFO shfi = { 0 };

    DLDATA* lpdl = (DLDATA*)GetProp(hwnd, pDirListProp);

    // Initialize default icons
    SHGetFileInfo(L"Icon", FILE_ATTRIBUTE_DIRECTORY, &shfi, sizeof(SHFILEINFO),
                  SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON | SHGFI_SYSICONINDEX);
    lpdl->iDefIconFolder = shfi.iIcon;

    SHGetFileInfo(L"Icon", FILE_ATTRIBUTE_NORMAL, &shfi, sizeof(SHFILEINFO),
                  SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON | SHGFI_SYSICONINDEX);
    lpdl->iDefIconFile = shfi.iIcon;

    // First of all terminate running icon thread
    DirList_TerminateIconThread(hwnd);

    // A Directory is strongly required
    if (!lpszDir || !*lpszDir)
        return (-1);

    lstrcpy(lpdl->szPath, lpszDir);

    // Init ListView
    SendMessage(hwnd, WM_SETREDRAW, 0, 0);
    ListView_DeleteAllItems(hwnd);

    // Init Filter
    DirList_CreateFilter(&dlf, lpszFileSpec, bExcludeFilter);

    // Init lvi
    lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
    lvi.iItem = 0;
    lvi.iSubItem = 0;
    lvi.pszText = LPSTR_TEXTCALLBACK;
    lvi.cchTextMax = MAX_PATH;
    lvi.iImage = I_IMAGECALLBACK;

    // Convert Directory to a UNICODE string
    /*MultiByteToWideChar(CP_ACP,
                        MB_PRECOMPOSED,
                        lpszDir,
                        -1,
                        wszDir,
                        MAX_PATH);*/
    lstrcpy(wszDir, lpszDir);

    // Get Desktop Folder
    if (NOERROR == SHGetDesktopFolder(&lpsfDesktop)) {

        // Convert wszDir into a pidl
        if (NOERROR ==
            lpsfDesktop->ParseDisplayName(hwnd, NULL, wszDir, &chParsed, &pidl, &dwAttributes)) {

            // Bind pidl to IShellFolder
            if (NOERROR == lpsfDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (void**)&lpsf)) {

                // Create an Enumeration object for lpsf
                if (NOERROR == lpsf->EnumObjects(hwnd, grfFlags, &lpe)) {

                    // Enumerate the contents of lpsf
                    while (NOERROR == lpe->Next(1, &pidlEntry, NULL)) {

                        // Add found item to the List
                        // Check if it's part of the Filesystem
                        dwAttributes = SFGAO_FILESYSTEM | SFGAO_FOLDER;

                        lpsf->GetAttributesOf(1, (LPCITEMIDLIST*)pidlEntry, &dwAttributes);

                        if (dwAttributes & SFGAO_FILESYSTEM) {

                            // Check if item matches specified filter
                            if (DirList_MatchFilter(lpsf, pidlEntry, &dlf)) {

                                lplvid = (LV_ITEMDATA*)CoTaskMemAlloc(sizeof(LV_ITEMDATA));

                                lplvid->pidl = pidlEntry;
                                lplvid->lpsf = lpsf;

                                lpsf->AddRef();

                                lvi.lParam = (LPARAM)lplvid;

                                // Setup default Icon - Folder or File
                                lvi.iImage = (dwAttributes & SFGAO_FOLDER) ? lpdl->iDefIconFolder
                                                                           : lpdl->iDefIconFile;

                                ListView_InsertItem(hwnd, &lvi);

                                lvi.iItem++;
                            }
                        }

                    } // IEnumIDList::Next()

                    lpe->Release();

                } // IShellFolder::EnumObjects()

            } // IShellFolder::BindToObject()

        } // IShellFolder::ParseDisplayName()

        lpsfDesktop->Release();

    } // SHGetDesktopFolder()

    if (lpdl->pidl)
        CoTaskMemFree(lpdl->pidl);

    if (lpdl->lpsf)
        lpdl->lpsf->Release();

    // Set lpdl
    lpdl->cbidl = IL_GetSize(pidl);
    lpdl->pidl = pidl;
    lpdl->lpsf = lpsf;
    lpdl->bNoFadeHidden = bNoFadeHidden;

    // Set column width to fit window
    ListView_SetColumnWidth(hwnd, 0, LVSCW_AUTOSIZE_USEHEADER);

    // Sort before display is updated
    DirList_Sort(hwnd, iSortFlags, fSortRev);

    // Redraw Listview
    SendMessage(hwnd, WM_SETREDRAW, 1, 0);

    // Return number of items in the control
    return (ListView_GetItemCount(hwnd));
}
Ejemplo n.º 7
0
void FillTreeView(HWND hwndTreeView,LPSHELLFOLDER lpsf,LPITEMIDLIST lpifq,HTREEITEM hParent)
{
    TV_ITEM         tvi;                          // TreeView Item.
    TV_INSERTSTRUCT tvins;                        // TreeView Insert Struct.
    HTREEITEM       hPrev = NULL;                 // Previous Item Added.
    LPSHELLFOLDER   lpsf2=0;
    LPENUMIDLIST    lpe=0;
    LPITEMIDLIST    lpi=0,lpifqThisItem;// lpiTemp=0, lpifqThisItem;
    LPTVITEMDATA    lptvid=0;
    LPMALLOC        lpMalloc=0;
    ULONG           ulFetched;
    HRESULT         hr;
    char            szBuff[256];
    HWND            hwnd=GetParent(hwndTreeView);

    hr=SHGetMalloc(&lpMalloc);
    if(FAILED(hr))
       return;

    SetCapture(GetParent(hwndTreeView));
    SetCursor(LoadCursor(NULL,IDC_WAIT));

    hr=lpsf->EnumObjects(hwnd,
								SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN,
                        &lpe) ;

    if(SUCCEEDED(hr))
    {
	    while (S_OK==lpe->Next(1,&lpi,&ulFetched))
       {
          ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER;

          lpsf->GetAttributesOf(1,(LPCITEMIDLIST*)&lpi, &ulAttrs) ;

          if( ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER))
          {
             if( ulAttrs & SFGAO_FOLDER)
             {
                tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;

                if( ulAttrs & SFGAO_HASSUBFOLDER)
                {
                   tvi.cChildren=1;
                   tvi.mask |= TVIF_CHILDREN;
                }

                lptvid = (LPTVITEMDATA)lpMalloc->Alloc(sizeof(TVITEMDATA));
                if( !lptvid)
                   goto Done;

                if(!GetName(lpsf, lpi, SHGDN_NORMAL, szBuff))
                   goto Done;
                tvi.pszText    = szBuff;
                tvi.cchTextMax = MAX_PATH;

                lpifqThisItem=ConcatPidls(lpifq, lpi) ;

                lptvid -> lpi=CopyITEMID(lpMalloc, lpi) ;

                GetNormalAndSelectedIcons(lpifqThisItem, &tvi) ;

                lptvid -> lpsfParent=lpsf;    //Store the parent folders SF
                lpsf->AddRef() ;

                if( hParent==TVI_ROOT)
                   lptvid -> lpifq=ConcatPidls(lpifq, lpi) ;
                else
                   lptvid -> lpifq=GetFullyQualPidl(lpsf, lpi) ;

                tvi.lParam = (LPARAM)lptvid;

                tvins./*DUMMYUNIONNAME.*/item = tvi;
                tvins.hInsertAfter = hPrev;
                tvins.hParent      = hParent;

                hPrev = TreeView_InsertItem(hwndTreeView, &tvins) ;

//////the next code expand all item but CD-ROM in Tree view/////////
//
//TreeView_Expand(hwndTreeView,hPrev,TVE_TOGGLE);
//
/////code end//////////////////////////////////////////////////////
				}

            lpMalloc->Free(lpifqThisItem) ;
            lpifqThisItem=0;
			}

         lpMalloc->Free(lpi) ;  //Finally, free the pidl that the shell gave us...
         lpi=0;
		}
	}

Done:

	ReleaseCapture() ;
   SetCursor( LoadCursor( NULL, IDC_ARROW)) ;

   if(lpe)
		lpe->Release() ;

   if(lpi && lpMalloc)
		lpMalloc->Free(lpi) ;
   if(lpifqThisItem && lpMalloc)
		lpMalloc->Free(lpifqThisItem) ;

   if(lpMalloc)
		lpMalloc->Release() ;
}
Ejemplo n.º 8
0
//***************************************************************************************
HRESULT CBCGPShellList::EnumObjects (LPSHELLFOLDER pParentFolder,
									LPITEMIDLIST pidlParent)
{
	ASSERT_VALID (this);
	ASSERT_VALID (g_pShellManager);

	LPENUMIDLIST pEnum;
	HRESULT hRes = pParentFolder->EnumObjects (NULL, m_nTypes, &pEnum);

	if (SUCCEEDED (hRes))
	{
		LPITEMIDLIST	pidlTemp;
		DWORD			dwFetched = 1;
		LPBCGCBITEMINFO pItem;
		
		//enumerate the item's PIDLs
		while (pEnum->Next(1, &pidlTemp, &dwFetched) == S_OK && dwFetched)
		{
			LVITEM lvItem;
			ZeroMemory(&lvItem, sizeof(lvItem));
			
			//fill in the TV_ITEM structure for this item
			lvItem.mask = LVIF_PARAM | LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
			
			//AddRef the parent folder so it's pointer stays valid
			pParentFolder->AddRef();
			
			//put the private information in the lParam
			pItem = (LPBCGCBITEMINFO)GlobalAlloc(GPTR, sizeof(BCGCBITEMINFO));
			
			pItem->pidlRel = pidlTemp;
			pItem->pidlFQ = g_pShellManager->ConcatenateItem (pidlParent, pidlTemp);
			
			pItem->pParentFolder = pParentFolder;

			if (!IsItemMatchedToFilter(pItem))
			{
				ReleaseItem(pItem);
				dwFetched = 0;
				continue;
			}

			lvItem.lParam = (LPARAM)pItem;
			
			lvItem.pszText = _T("");
			lvItem.iImage = OnGetItemIcon (GetItemCount (), pItem);
			
			//determine if the item is shared
			DWORD dwAttr = SFGAO_DISPLAYATTRMASK;
			pParentFolder->GetAttributesOf (1, (LPCITEMIDLIST*)&pidlTemp, &dwAttr);
			
			if (dwAttr & SFGAO_SHARE)
			{
				lvItem.mask |= LVIF_STATE;
				lvItem.stateMask |= LVIS_OVERLAYMASK;
				lvItem.state |= INDEXTOOVERLAYMASK(1); //1 is the index for the shared overlay image
			}
			
			if (dwAttr & SFGAO_GHOSTED)
			{
				lvItem.mask |= LVIF_STATE;
				lvItem.stateMask |= LVIS_CUT;
				lvItem.state |= LVIS_CUT;
			}
			
			int iItem = InsertItem (&lvItem);
			if (iItem >= 0)
			{
				//-------------
				// Set columns:
				//-------------
				const int nColumns = (GetStyle () & LVS_TYPEMASK) == LVS_REPORT ?
					m_wndHeader.GetItemCount () : 1;

				for (int iColumn = 0; iColumn < nColumns; iColumn++)
				{
					SetItemText (iItem, iColumn, 
								OnGetItemText (iItem, iColumn, pItem));
				}
			}

			dwFetched = 0;
		}
		
		pEnum->Release ();
	}

	return hRes;
}