⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shelltreectrl.cpp

📁 用VC写的浏览器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	// TODO: Add your control notification handler code here
	::GetCursorPos((LPPOINT)&pt);
	ScreenToClient(&pt);
	tvhti.pt=pt;
    HitTest(&tvhti);
    SelectItem(tvhti.hItem);
	if (tvhti.flags & (TVHT_ONITEMLABEL|TVHT_ONITEMICON))
	{
		ClientToScreen(&pt);
		tvi.mask=TVIF_PARAM;
		tvi.hItem=tvhti.hItem;
		
        if (!GetItem(&tvi)){
			return;
		}
		
		lptvid=(LPTVITEMDATA)tvi.lParam;
		
		DoTheMenuThing(::GetParent(m_hWnd),
		lptvid->lpsfParent, lptvid->lpi, &pt);
	}	
	
	*pResult = 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;
}

/****************************************************************************
*
*	FUNCTION:	OnDeleteShellItem(NMHDR* pNMHDR, LRESULT* pResult)
*
*	PURPOSE:	Releases the memory allocated by the shell folders
*
*	MESSAGEMAP:	TVN_DELETEITEM
*
*	MISC:		failure to call this function will result in a memory leak
*
****************************************************************************/
void CShellTreeCtrl::OnDeleteShellItem(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPTVITEMDATA lptvid=NULL;
	HRESULT hr;
	LPMALLOC lpMalloc;

	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

	//Let's free the memory for the TreeView item data...
	hr=SHGetMalloc(&lpMalloc);
	if (FAILED(hr))
		return;
		
	lptvid=(LPTVITEMDATA)pNMTreeView->itemOld.lParam;
	lptvid->lpsfParent->Release();
	lpMalloc->Free(lptvid->lpi);  
	lpMalloc->Free(lptvid->lpifq);  
	lpMalloc->Free(lptvid);  
	lpMalloc->Release();
}

/****************************************************************************
*
*	FUNCTION:	EnableImages()
*
*	PURPOSE:	Obtains a handle to the system image list and attaches it
*				to the tree control. DO NOT DELETE the imagelist
*
*	MESSAGEMAP:	NONE
*
****************************************************************************/
void CShellTreeCtrl::EnableImages()
{
	// Get the handle to the system image list, for our icons
    HIMAGELIST  hImageList;
    SHFILEINFO    sfi;

    hImageList = (HIMAGELIST)SHGetFileInfo((LPCSTR)"C:\\", 
                                           0,
                                           &sfi, 
                                           sizeof(SHFILEINFO), 
                                           SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
    // Attach ImageList to TreeView
    if (hImageList)
        ::SendMessage(m_hWnd, TVM_SETIMAGELIST, (WPARAM) TVSIL_NORMAL,
            (LPARAM)hImageList);
}

/****************************************************************************
*
*	FUNCTION:	SearchTree(	HTREEITEM treeNode,
*							CString szSearchName )
*
*	PURPOSE:	Too crude to explain, just use it
*
*	WARNING:	Only works if you use the default PopulateTree()
*				Not guaranteed to work on any future or existing
*				version of windows. Use with caution. Pretty much
*				ok if you're using on local drives
*
****************************************************************************/
bool CShellTreeCtrl::SearchTree(HTREEITEM treeNode,
							CString szSearchName,
							FindAttribs attr)
{
	LPTVITEMDATA	lptvid;  //Long pointer to TreeView item data
	LPSHELLFOLDER	lpsf2=NULL;
	char	drive[_MAX_DRIVE];
	char	dir[_MAX_DIR];
	char	fname[_MAX_FNAME];
	char	ext[_MAX_EXT];
	bool	bRet=false;
	HRESULT	hr;
	CString	szCompare;

	szSearchName.MakeUpper();
	while(treeNode && bRet==false)
	{
		lptvid=(LPTVITEMDATA)GetItemData(treeNode);
		if (lptvid && lptvid->lpsfParent && lptvid->lpi)
		{
			hr=lptvid->lpsfParent->BindToObject(lptvid->lpi,
					 0,IID_IShellFolder,(LPVOID *)&lpsf2);
			if (SUCCEEDED(hr))
			{
				ULONG ulAttrs = SFGAO_FILESYSTEM;
				lptvid->lpsfParent->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lptvid->lpi, &ulAttrs);
				if (ulAttrs & (SFGAO_FILESYSTEM))
				{
					if(SHGetPathFromIDList(lptvid->lpifq,szCompare.GetBuffer(MAX_PATH)))
					{
						switch(attr)
						{
						case type_drive:
							_splitpath(szCompare,drive,dir,fname,ext);
							szCompare=drive;
							break;
						case type_folder:
							szCompare = GetItemText(treeNode);
							break;
						}
						szCompare.MakeUpper();
						if(szCompare == szSearchName)
						{
							EnsureVisible(treeNode);
							SelectItem(treeNode);
							Expand(treeNode, TVE_EXPAND);
							bRet=true;
						}
					}
				}
				lpsf2->Release();
			}
		}
		treeNode = GetNextSiblingItem(treeNode);
	}
	return bRet;
}

/****************************************************************************
*
*	FUNCTION:	TunnelTree(CString szFindPath)
*
*	PURPOSE:	Too crude to explain, just use it
*
*	WARNING:	Only works if you use the default PopulateTree()
*				Not guaranteed to work on any future or existing
*				version of windows. Use with caution. Pretty much
*				ok if you're using on local drives
*
****************************************************************************/
void CShellTreeCtrl::TunnelTree(CString szFindPath)
{
	HTREEITEM subNode = GetRootItem();
	CString szPathHop;
	char drive[_MAX_DRIVE];
	char dir[_MAX_DIR];
	char fname[_MAX_FNAME];
	char ext[_MAX_EXT];
	char delimiter[]="\\";
	LPSHELLFOLDER  lpsf2=NULL;
	static char    szBuff[MAX_PATH];

	if ( !_FileIsExist(szFindPath) )
	{
		MessageBox(szFindPath,"Folder not found",MB_ICONERROR);
		return;
	}
		
	if(szFindPath.ReverseFind('\\') != szFindPath.GetLength()-1)
	{
		szFindPath += "\\";
	}

	_splitpath(szFindPath,drive,dir,fname,ext);

	//search the drive first
	bool found = false;
	szPathHop=drive;
	subNode=GetChildItem(subNode);
	if(subNode)
	{
		found = SearchTree(subNode,szPathHop, CShellTreeCtrl::type_drive);
		if(!found)
		{
			subNode = GetRootItem();
			subNode = GetNextSiblingItem(subNode);
			Expand(subNode, TVE_EXPAND);
			subNode = GetChildItem(subNode);
			if(subNode)
				found = SearchTree(subNode,szPathHop, CShellTreeCtrl::type_drive);
		}
		if(found)
		{
			//break down subfolders and search
			char *p=strtok(dir,delimiter);
			while(p)
			{
				subNode = GetSelectedItem();
				//expand it
				Expand(subNode, TVE_EXPAND);
				subNode = GetChildItem(subNode);
				if(SearchTree(subNode,p,CShellTreeCtrl::type_folder))
					p=strtok(NULL,delimiter);
				else
					p=NULL;
			}
		}
	}
}

BOOL CShellTreeCtrl::MatchExtensionFilter(LPSTR lpFileName)
{
	if(lpFileName == NULL)
		return FALSE;

	if(m_strFilter == "" || m_strFilter.Find("*.*")>=0)
		return TRUE;

	CString str(lpFileName);
	str.MakeLower();
	int i = str.ReverseFind('.');
	if(i<0)
		return FALSE;
	str = str.Mid(i);
	str += ";";
	if(m_strFilter.Find(str)>=0)
		return TRUE;
	else
		return FALSE;
}

void CShellTreeCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPTVITEMDATA	lptvid;
	char		szBuff[MAX_PATH];
	HTREEITEM		hItem=NULL;

	CPoint pt;
	UINT uFlags;

	GetCursorPos(&pt);
	ScreenToClient(&pt);
	hItem = HitTest(pt, &uFlags);
	if(hItem == NULL || !(TVHT_ONITEM & uFlags))
		return;

	lptvid=(LPTVITEMDATA)GetItemData(hItem);
	if(SHGetPathFromIDList(lptvid->lpifq,szBuff))
	{
		OFSTRUCT ofs;
		if(OpenFile(szBuff, &ofs, OF_EXIST) != HFILE_ERROR)
		{
			//is exe?
			CString s = szBuff;
			if(s.Right(4)==".exe" || s.Right(4)==".EXE")
				ShellExecute(NULL, "open", szBuff , "", NULL, SW_SHOW );
			else
			{
				CGreenBrowserView* pvw = GetCurrentView(1, g_bFileInNewWindow);
				if(pvw!=NULL)
				{
					pvw->ToNavigate(szBuff,0,NULL);
				}
			}
		}
		else
			Expand(hItem, TVE_TOGGLE);
	}
}

BOOL CShellTreeCtrl::GetCurFilePath(CString & str)
{
	LPTVITEMDATA	lptvid;
	char		szBuff[MAX_PATH];
	HTREEITEM		hItem=NULL;

	hItem = GetSelectedItem();
	lptvid=(LPTVITEMDATA)GetItemData(hItem);
	if(SHGetPathFromIDList(lptvid->lpifq,szBuff))
	{
		str = szBuff;
		return TRUE;
	}
	else
		return FALSE;
}

//#pragma optimize( "s", off )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -