📄 shelltreectrl.cpp
字号:
// 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 + -