?? umshelltree.cpp
字號:
{
// TODO: Add your control notification handler code here
POINT pt;
LPTVITEMDATA lptvid; //Long pointer to TreeView item data
LPSHELLFOLDER lpsf2=NULL;
static char szBuff[MAX_PATH];
TV_HITTESTINFO tvhti;
TV_ITEM tvi;
// 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 CUmShellTree::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 CUmShellTree::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 CUmShellTree::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: GetSelectedFolderPath(CString &szFolderPath)
*
* PURPOSE: Retrieves the path of the currently selected string.
* Pass a CString object that will hold the folder path.
* If the path is not in the filesystem(eg MyComputer)
* or none is selected it returns false.
*
* MESSAGEMAP: NONE
*
****************************************************************************/
BOOL CUmShellTree::GetSelectedFolderPath(CString &szFolderPath)
{
LPTVITEMDATA lptvid; //Long pointer to TreeView item data
LPSHELLFOLDER lpsf2=NULL;
static char szBuff[MAX_PATH];
HTREEITEM hItem=NULL;
HRESULT hr;
BOOL bRet=false;
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;
}
}
}
}
if(lpsf2)
lpsf2->Release();
}
return bRet;
}
/****************************************************************************
*
* FUNCTION: GetParentShellFolder(HTREEITEM folderNode)
*
* PURPOSE: Retrieves the pointer to the ISHELLFOLDER interface
* of the tree node passed as the paramter.
*
* MESSAGEMAP: NONE
*
****************************************************************************/
LPSHELLFOLDER CUmShellTree::GetParentShellFolder(HTREEITEM folderNode)
{
LPTVITEMDATA lptvid; //Long pointer to TreeView item data
lptvid=(LPTVITEMDATA)GetItemData(folderNode);
if(lptvid)
return lptvid->lpsfParent;
else
return NULL;
}
/****************************************************************************
*
* FUNCTION: GetRelativeIDLIST(HTREEITEM folderNode)
*
* PURPOSE: Retrieves the Pointer to an ITEMIDLIST structure that
* identifies the subfolder relative to its parent folder.
* see GetParentShellFolder();
*
* MESSAGEMAP: NONE
*
****************************************************************************/
LPITEMIDLIST CUmShellTree::GetRelativeIDLIST(HTREEITEM folderNode)
{
LPTVITEMDATA lptvid; //Long pointer to TreeView item data
lptvid=(LPTVITEMDATA)GetItemData(folderNode);
if(lptvid)
return lptvid->lpifq;
else
return NULL;
}
/****************************************************************************
*
* FUNCTION: GetFullyQualifiedIDLIST(HTREEITEM folderNode)
*
* PURPOSE: Retrieves the Retrieves the Pointer to an ITEMIDLIST
* structure that identifies the subfolder relative to the
* desktop. This is a fully qualified Item Identifier
*
* MESSAGEMAP: NONE
*
****************************************************************************/
LPITEMIDLIST CUmShellTree::GetFullyQualifiedID(HTREEITEM folderNode)
{
LPTVITEMDATA lptvid; //Long pointer to TreeView item data
lptvid=(LPTVITEMDATA)GetItemData(folderNode);
if(lptvid)
return lptvid->lpifq;
else
return NULL;
}
/****************************************************************************
*
* 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 CUmShellTree::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);
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 CUmShellTree::TunnelTree(CString szFindPath)
{
HTREEITEM subNode = GetRootItem();
HTREEITEM subNode2;
CString szPathHop;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
char delimiter[]="\\";
CUmFileName checkPath(szFindPath);
if(!checkPath.Exist())
{
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
szPathHop=drive;
//subNode=GetChildItem(subNode);
while(subNode)
{
subNode2=GetChildItem(subNode);
if(SearchTree(subNode2,szPathHop, CUmShellTree::type_drive))
{
//break down subfolders and search
char *p=strtok(dir,delimiter);
while(p)
{
subNode2 = GetSelectedItem();
subNode2 = GetChildItem(subNode2);
if(SearchTree(subNode2,p,CUmShellTree::type_folder))
p=strtok(NULL,delimiter);
else
p=NULL;
}
}
subNode = GetNextSiblingItem(subNode);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -