Пример #1
0
// Recursively sorts a node and its children using an application
// specific sorting function
void CMyTreeCtrl::SortNodeAndChildren(HTREEITEM hItem, PFNTVCOMPARE lpfnCompare)
{
	// Create the sorting structure
	TVSORTCB sort;
	sort.hParent=hItem;
	sort.lParam=0;
	sort.lpfnCompare=lpfnCompare;

	// Sort the node
	SortChildrenCB(&sort);

	// Determine if this item has children
	if (ItemHasChildren(hItem))
	{
		// Get the first child item
		HTREEITEM hChild=GetChildItem(hItem);

		// Sort the child
		SortNodeAndChildren(hChild, lpfnCompare);

		// Sort the rest of the children
		HTREEITEM hSibling=GetNextSiblingItem(hChild);
		while (hSibling)
		{
			SortNodeAndChildren(hSibling, lpfnCompare);
			hSibling=GetNextSiblingItem(hSibling);
		}
	}
}
Пример #2
0
void CCJShellTree::OnFill(bool bRefresh/*=false*/)
{
    LPSHELLFOLDER lpsf=NULL;
    HRESULT hr;
    TV_SORTCB      tvscb;

	m_bRefresh = bRefresh;

    // Get a pointer to the desktop folder.
    hr=SHGetDesktopFolder(&lpsf);
	
    if (SUCCEEDED(hr))
    {
		// Initialize the tree view to be empty.
		DeleteAllItems();
		
		// Fill in the tree view from the root.
		FillTreeView(lpsf,
			NULL,
			TVI_ROOT);
		// Release the folder pointer.
		lpsf->Release();
    }
    tvscb.hParent     = TVI_ROOT;
    tvscb.lParam      = 0;
    tvscb.lpfnCompare = TreeViewCompareProc;
	
    // Sort the items in the tree view
	SortChildrenCB(&tvscb/*, FALSE*/);
	
	Expand(GetRootItem(), TVE_EXPAND);
}
Пример #3
0
// Recursively sort the entire tree
void CMultiSelTreeCtrl::SortTree(HTREEITEM topNode/*=NULL*/, HTREEITEM parentNode/*=NULL*/)
{
	HTREEITEM item;

	// Sort things at the this level
	if (parentNode && (m_SortByExtension || m_SortByResolveStat 
					|| m_SortByAction    || m_SortByFilename))
	{
		TVSORTCB tvsortcb;
		tvsortcb.hParent = topNode;
		tvsortcb.lParam = (m_SortByResolveStat ? 2 : 0) + (m_SortByExtension ? 1 : 0) 
						+ (m_SortByFilename ? 8 : 0)    + (m_SortByAction ? 4 : 0);
		tvsortcb.lpfnCompare = SortTreeCB;
		SortChildrenCB(&tvsortcb);
	}
	else 
		SortChildren(topNode);

	// Get the first item at this level
	if(topNode == NULL)
		item=GetNextItem(TVI_ROOT, TVGN_ROOT);
	else
		item=GetChildItem(topNode);   // Get first child

	// Recurse all items that have children
	while(item != NULL)
	{
		if(ItemHasChildren(item))
			SortTree(item, topNode);
		item=GetNextSiblingItem(item);
	}
}
Пример #4
0
/****************************************************************************
*
*    FUNCTION: PopulateTree()
*
*    PURPOSE:  Processes the File.Fill/RefreshTree command
*
****************************************************************************/
void CShellTreeCtrl::PopulateTree() 
{

    LPSHELLFOLDER lpsf=NULL;
    LPITEMIDLIST  lpi=NULL;
    HRESULT hr;
    TV_SORTCB      tvscb;
   
    // Get a pointer to the desktop folder.
    hr=SHGetDesktopFolder(&lpsf);

    if (SUCCEEDED(hr))
    {
       // Initialize the tree view to be empty.
       DeleteAllItems();

       // Fill in the tree view from the root.
       FillTreeView(lpsf, NULL, TVI_ROOT);
       //TunnelFillTree(lpsf, NULL, TVI_ROOT);
       // Release the folder pointer.
       lpsf->Release();
    }
    tvscb.hParent     = TVI_ROOT;
    tvscb.lParam      = 0;
    tvscb.lpfnCompare = TreeViewCompareProc;

    // Sort the items in the tree view
	SortChildrenCB(&tvscb/*, FALSE*/);
    
	HTREEITEM hItem;
	hItem = GetRootItem();
	Expand(hItem,TVE_EXPAND);
	Select(GetRootItem(),TVGN_CARET);
}
Пример #5
0
/****************************************************************************
*
*	FUNCTION:	OnFolderSelected(NMHDR* pNMHDR, LRESULT* pResult, CString &szFolderPath) 
*
*	PURPOSE:	Call this function if for example you want to put the path of the folder
*				selected inside a combobox or an edit window. You would pass the
*				parameters from OnSelChanged() to this function along with a CString object
*				that will hold the folder path. If the path is not
*				in the filesystem(eg MyComputer) it returns false.
*
*	MESSAGEMAP:	TVN_SELCHANGED
*
****************************************************************************/
BOOL CShellTreeCtrl::OnFolderSelected(NMHDR* pNMHDR, LRESULT* pResult, CString &szFolderPath) 
{
	// TODO: Add your control notification handler code here
	LPTVITEMDATA	lptvid;  //Long pointer to TreeView item data
	LPSHELLFOLDER	lpsf2=NULL;
	static char		szBuff[MAX_PATH];
	HRESULT			hr;
	BOOL			bRet=false;
	TV_SORTCB		tvscb;
	HTREEITEM		hItem=NULL;

	if((hItem = GetSelectedItem()))
	{
		lptvid=(LPTVITEMDATA)GetItemData(hItem);

		if (lptvid && lptvid->lpsfParent && lptvid->lpi)
		{
			hr=lptvid->lpsfParent->BindToObject(lptvid->lpi,
					 0,IID_IShellFolder,(LPVOID *)&lpsf2);

			if (SUCCEEDED(hr))
				{
					ULONG ulAttrs = SFGAO_FILESYSTEM;

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

					if (ulAttrs & (SFGAO_FILESYSTEM))
					{
						if(SHGetPathFromIDList(lptvid->lpifq,szBuff)){
							szFolderPath = szBuff;
							bRet = true;
						}
					}
					//non standard from here(NEW CODE)
					NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR;
					if ((pnmtv->itemNew.cChildren == 1) && !(pnmtv->itemNew.state & TVIS_EXPANDEDONCE)){
						FillTreeView(lpsf2,lptvid->lpifq,pnmtv->itemNew.hItem);

						tvscb.hParent     = pnmtv->itemNew.hItem;
						tvscb.lParam      = 0;
						tvscb.lpfnCompare = TreeViewCompareProc;
						SortChildrenCB(&tvscb);
						
						pnmtv->itemNew.state |= TVIS_EXPANDEDONCE;
						pnmtv->itemNew.stateMask |= TVIS_EXPANDEDONCE;
						pnmtv->itemNew.mask |= TVIF_STATE;
						SetItem(&pnmtv->itemNew);
					}
				}

		}
		if(lpsf2)
			lpsf2->Release();
		
	}	
	*pResult = 0;
	return bRet;
}
Пример #6
0
void CTreeCtrlEx::Sort(HTREEITEM parent)
{
   TVSORTCB tvs;
   tvs.hParent=parent;
   tvs.lpfnCompare=MyCompareProc;
   tvs.lParam=(LPARAM)this;
   SortChildrenCB(&tvs);
}
Пример #7
0
BOOL CTreeListCtrl::SortItems( int nCol, BOOL bAscending, HTREEITEM low)
{
   TV_SORTCB tSort;

   tSort.hParent = low;
   tSort.lpfnCompare = CompareFunc;

   SSortType *pSortType = new SSortType;
   pSortType->nCol = nCol;
   pSortType->bAscending = bAscending;
   tSort.lParam = (LPARAM)pSortType;

   BOOL m_bReturn = SortChildrenCB(&tSort);

   delete pSortType;

   return m_bReturn;
}
Пример #8
0
BOOL CMyTreeView::GetChildItems(HTREEITEM hParentItem)
{
    TVITEM tvItem = {0};
    tvItem.mask = TVIF_PARAM;
    tvItem.hItem = hParentItem;

    if (!GetItem(tvItem))
        return FALSE;

    //change the cursor
    HCURSOR hCursor = ::SetCursor(LoadCursor(NULL, IDC_WAIT));
    //turn redawing off in the TreeView. This will speed things up as we add items
    SendMessage(WM_SETREDRAW, FALSE, 0);
    TreeItemData* pItem = (TreeItemData*)tvItem.lParam;
    CShellFolder cParentFolder;
    HRESULT        hr;

    //if the parent folder is NULL, then we are at the root of the namespace, so the parent of this item is the desktop folder
    if (!pItem->GetParentFolder().GetIShellFolder())
        hr = cParentFolder.SHGetDesktopFolder();
    //otherwise we need to get the IShellFolder for this item
    else
        hr = pItem->GetParentFolder().BindToObject(pItem->GetRelCpidl(), NULL, IID_IShellFolder, cParentFolder);

    if (FAILED(hr))
        return FALSE;

    EnumObjects(hParentItem, cParentFolder, pItem->GetFullCpidl());
    //sort the new items
    TV_SORTCB tvSort;
    tvSort.hParent = hParentItem;
    tvSort.lpfnCompare = CompareProc;
    tvSort.lParam = 0;
    SortChildrenCB(tvSort, 0);
    //turn redawing back on in the TreeView
    SendMessage(WM_SETREDRAW, TRUE, 0);
    UpdateWindow();
    ::SetCursor(hCursor);
    return TRUE;
}
Пример #9
0
/****************************************************************************
*
*	FUNCTION:	OnFolderExpanding(NMHDR* pNMHDR, LRESULT* pResult) 
*
*	PURPOSE:	Reponds to an TVN_ITEMEXPANDING message in order to fill up
*				subdirectories. Pass the parameters from OnItemExpanding() to 
*				this function. You need to do that or your folders won't
*				expand.
*
*	OTHER:		It can also be used to update a corresponding listview. Seem MFCENUM
*
*	MESSAGEMAP:	TVN_ITEMEXPANDING
*
****************************************************************************/
void CShellTreeCtrl::OnFolderExpanding(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LPTVITEMDATA   lptvid;  //Long pointer to TreeView item data
	HRESULT        hr;
	LPSHELLFOLDER  lpsf2=NULL;
	static char    szBuff[MAX_PATH];
	TV_SORTCB      tvscb;

	NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
    if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
	{
         return;
	}

    lptvid=(LPTVITEMDATA)pnmtv->itemNew.lParam;
    if (lptvid)
       {
            hr=lptvid->lpsfParent->BindToObject(lptvid->lpi,
                0, IID_IShellFolder,(LPVOID *)&lpsf2);

            if (SUCCEEDED(hr))
            {
                FillTreeView(lpsf2,
                       lptvid->lpifq,
                       pnmtv->itemNew.hItem);
            }

            tvscb.hParent     = pnmtv->itemNew.hItem;
            tvscb.lParam      = 0;
            tvscb.lpfnCompare = TreeViewCompareProc;

            SortChildrenCB(&tvscb /*, FALSE*/);
    }	
	

	*pResult = 0;
}
Пример #10
0
/* #FN#
   Reponds to TVN_ITEMEXPANDING message in order to fill up subdirectories.
   Pass the parameters from OnItemExpanding() to this function. You need to
   do that or your folders won't expand */
void
/* #AS#
   Nothing */
CShellTree::
OnFolderExpanding(
	NMHDR   *pNMHDR, /* #IN# */
	LRESULT *pResult /* #OUT# */
)
{
	LPTVITEMDATA  lptvid; /* Long pointer to TreeView item data */
	LPSHELLFOLDER lpsf2 = NULL;
	TV_SORTCB     tvscb;
	static char   szBuff[ MAX_PATH + 1 ];
	HRESULT       hr;

	NM_TREEVIEW *pnmtv = (NM_TREEVIEW *)pNMHDR;

	if( pnmtv->itemNew.state & TVIS_EXPANDEDONCE )
		return;

	lptvid = (LPTVITEMDATA)pnmtv->itemNew.lParam;
	if( lptvid )
	{
		hr = lptvid->lpsfParent->BindToObject( lptvid->lpi, 0, IID_IShellFolder, (LPVOID *)&lpsf2 );
		
		if( SUCCEEDED(hr) )
			FillTreeView( lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem );

		tvscb.hParent     = pnmtv->itemNew.hItem;
		tvscb.lParam      = 0;
		tvscb.lpfnCompare = TreeViewCompareProc;
		
		SortChildrenCB( &tvscb /*, FALSE*/ );
	}
	*pResult = 0;

} /* #OF# CShellTree::OnFolderExpanding */
Пример #11
0
/* #FN#
   Populates the tree view control with file list */
void
/* #AS#
   Nothing */
CShellTree::
PopulateTree()
{
	LPSHELLFOLDER lpsf = NULL;
	LPITEMIDLIST  lpi  = NULL;
	HRESULT hr;

	/* Get a pointer to the desktop folder */
	hr = SHGetDesktopFolder( &lpsf );

	if( SUCCEEDED(hr) )
	{
		/* Initialize the tree view to be empty */
		DeleteAllItems();

		/* Fill in the tree view from the root */
		FillTreeView( lpsf, NULL, TVI_ROOT );
		/* Release the folder pointer */
		lpsf->Release();
	}
	TV_SORTCB tvscb;
	tvscb.hParent     = TVI_ROOT;
	tvscb.lParam      = 0;
	tvscb.lpfnCompare = TreeViewCompareProc;

	/* Sort the items in the tree view */
	SortChildrenCB( &tvscb /*, FALSE*/ );

	HTREEITEM hItem = GetRootItem();
	Expand( hItem, TVE_EXPAND );
	Select( GetRootItem(), TVGN_CARET );

} /* #OF# CShellTree::PopulateTree */
Пример #12
0
void CCJShellTree::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	*pResult = 0;

	LPTVITEMDATA   lptvid;  //Long pointer to TreeView item data
	HRESULT        hr;
	LPSHELLFOLDER  lpsf2=NULL;
	static char    szBuff[MAX_PATH];
	TV_SORTCB      tvscb;

	if ((pNMTreeView->itemNew.state & TVIS_EXPANDEDONCE))
		return;
	
	SetRedraw(FALSE);
	lptvid=(LPTVITEMDATA)pNMTreeView->itemNew.lParam;
	if (lptvid)
	{
		hr=lptvid->lpsfParent->BindToObject(lptvid->lpi,
			0, IID_IShellFolder,(LPVOID *)&lpsf2);
		
		if (SUCCEEDED(hr))
		{
			FillTreeView(lpsf2,
				lptvid->lpifq,
				pNMTreeView->itemNew.hItem);
		}
		
		tvscb.hParent     = pNMTreeView->itemNew.hItem;
		tvscb.lParam      = 0;
		tvscb.lpfnCompare = TreeViewCompareProc;
		
		SortChildrenCB(&tvscb/*, FALSE*/);
	}
	SetRedraw();
}
Пример #13
0
void FolderTree::DisplayPath(const tstring &sPath, HTREEITEM hParent, bool bUseSetRedraw /* = true */)
{
	//CWaitCursor c;

	//Speed up the job by turning off redraw
	if (bUseSetRedraw)
		SetRedraw(false);

	//Remove all the items currently under hParent
	HTREEITEM hChild = GetChildItem(hParent);
	while (hChild)
	{
		DeleteItem(hChild);
		hChild = GetChildItem(hParent);
	}

	//Should we display the root folder
	if (m_bShowRootedFolder && (hParent == TVI_ROOT))
	{
		FolderTreeItemInfo* pItem = new FolderTreeItemInfo;
		pItem->m_sFQPath = m_sRootFolder;
		pItem->m_sRelativePath = m_sRootFolder;
		m_hRootedFolder = InsertFileItem(TVI_ROOT, pItem, false, GetIconIndex(m_sRootFolder), GetSelIconIndex(m_sRootFolder), true);
		Expand(m_hRootedFolder, TVE_EXPAND);
		return;
	}

	//find all the directories underneath sPath
	int nDirectories = 0;
	
	tstring sFile;
	if (sPath[sPath.size()-1] != _T('\\'))
		sFile = sPath + _T("\\");
	else
		sFile = sPath;

	WIN32_FIND_DATA fData;
	HANDLE hFind;
	hFind = FindFirstFile((sFile + _T("*")).c_str(), &fData);

	if(hFind != INVALID_HANDLE_VALUE)

	{
		do
		{
			tstring filename = fData.cFileName;
			if((fData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && 
				(filename != _T(".")) && (filename != _T("..")))
			{
				++nDirectories;
				tstring path = sFile + filename;

				TCHAR szPath[_MAX_PATH];
				TCHAR szFname[_MAX_FNAME];
				TCHAR szExt[_MAX_EXT];
				_tsplitpath(path.c_str(), NULL, NULL, szFname, szExt);
				_tmakepath(szPath, NULL, NULL, szFname, szExt);

				FolderTreeItemInfo* pItem = new FolderTreeItemInfo;
				pItem->m_sFQPath = path;
				pItem->m_sRelativePath = szPath;
				InsertFileItem(hParent, pItem, m_bShowSharedUsingDifferentIcon && IsShared(path), GetIconIndex(path), GetSelIconIndex(path), true);
			}
		} while (FindNextFile(hFind, &fData));
	}

	FindClose(hFind);

	//Now sort the items we just added
	TVSORTCB tvsortcb;
	tvsortcb.hParent = hParent;
	tvsortcb.lpfnCompare = CompareByFilenameNoCase;
	tvsortcb.lParam = 0;
	SortChildrenCB(&tvsortcb);

	//We want to add them before sorting
	checkRemovedDirs(sFile, hParent);

	//If no items were added then remove the "+" indicator from hParent
	if(nDirectories == 0)
		SetHasPlusButton(hParent, FALSE);

	//Turn back on the redraw flag
	if(bUseSetRedraw)
		SetRedraw(true);
}
Пример #14
0
void CCJShellTree::PopulateTree(LPCTSTR lpszPath)
{
	LPSHELLFOLDER lpsf=NULL,lpsf2=NULL;
    LPITEMIDLIST  lpi=NULL;
    HRESULT hr;
    TV_SORTCB      tvscb;
	LPTSTR			lpFolder = (LPTSTR)lpszPath;
	LPTSTR			lpNextFolder;
	TCHAR			strPath[_MAX_PATH];
	
	LPMALLOC pMalloc;
	if (::SHGetMalloc(&pMalloc) == NOERROR)
	{
		
		// Get a pointer to the desktop folder.
		hr=SHGetDesktopFolder(&lpsf);
		
		if (SUCCEEDED(hr))
		{
			USES_CONVERSION;
			
			// Initialize the tree view to be empty.
			DeleteAllItems();
			
			do{
				
				// Get the Next Component
				lpNextFolder = PathFindNextComponent( lpFolder );
				if( lpNextFolder && *lpNextFolder ){
					memcpy( strPath, lpFolder, ( lpNextFolder - lpFolder ) );
					strPath[lpNextFolder - lpFolder] = _T('\0');
				}
				else{
					_tcscpy( strPath, lpFolder );
					lpNextFolder = NULL;
				}
				
				// Get ShellFolder Pidl
				ULONG eaten;
				hr = lpsf->ParseDisplayName( NULL, NULL, T2OLE(strPath), &eaten, &lpi, NULL );
				if( FAILED( hr ) ){
					break;
				}
				hr=lpsf->BindToObject(lpi, 0, IID_IShellFolder,(LPVOID *)&lpsf2);
				if( FAILED( hr ) ){
					break;
				}
				
				pMalloc->Free( lpi );
				
				// Release the Parent Folder pointer.
				lpsf->Release();
				
				// Chenge Folder Info
				lpsf = lpsf2;
				lpFolder = lpNextFolder;
			}
			while( lpNextFolder );
			
			FillTreeView(lpsf,NULL,TVI_ROOT);
			
		}
	}
    tvscb.hParent     = TVI_ROOT;
    tvscb.lParam      = 0;
    tvscb.lpfnCompare = TreeViewCompareProc;
	
    // Sort the items in the tree view
	SortChildrenCB(&tvscb/*, FALSE*/);
    
	HTREEITEM hItem;
	hItem = GetRootItem();
	Expand(hItem,TVE_EXPAND);
	Select(GetRootItem(),TVGN_CARET);
}