?? shelltree.cpp
字號:
****************************************************************************/
void CShellTree::
GetNormalAndSelectedIcons (LPITEMIDLIST lpifq,
LPTV_ITEM lptvitem)
{
//Note that we don't check the return value here because if GetIcon()
//fails, then we're in big trouble...
lptvitem->iImage = GetItemIcon (lpifq, SHGFI_PIDL |
SHGFI_SYSICONINDEX |
SHGFI_SMALLICON);
lptvitem->iSelectedImage = GetItemIcon (lpifq, SHGFI_PIDL |
SHGFI_SYSICONINDEX |
SHGFI_SMALLICON |
SHGFI_OPENICON);
return;
}
/****************************************************************************
*
* FUNCTION: TreeViewCompareProc(LPARAM, LPARAM, LPARAM)
*
* PURPOSE: Callback routine for sorting the tree
*
****************************************************************************/
#pragma warning ( disable : 4100 )
int CALLBACK CShellTree::
TreeViewCompareProc (LPARAM lparam1,
LPARAM lparam2, LPARAM lparamSort)
{
LPTVITEMDATA lptvid1 = (LPTVITEMDATA) lparam1;
LPTVITEMDATA lptvid2 = (LPTVITEMDATA) lparam2;
HRESULT hr;
hr = lptvid1->lpsfParent->CompareIDs (0, lptvid1->lpi, lptvid2->lpi);
if (FAILED (hr))
return 0;
return (short) SCODE_CODE (GetScode (hr));
}
#pragma warning ( default : 4100 )
void CShellTree::
DeleteChildren (HTREEITEM item)
{
HTREEITEM child;
child = GetChildItem (item);
while (child)
{
if (GetChildItem (child))
DeleteChildren (child);
DeleteItem (child);
child = GetChildItem (item);
}
}
/////////////////////////////////////////////////////////////////////////////
// CShellTree message handlers
/****************************************************************************
*
* 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 CShellTree::
OnFolderExpanding (NMHDR * pNMHDR, LRESULT * pResult)
{
LPTVITEMDATA lptvid; //Long pointer to TreeView item data
HRESULT hr;
LPSHELLFOLDER lpsf2 = NULL;
static TCHAR szBuff[MAX_PATH];
TV_SORTCB tvscb;
NM_TREEVIEW *pnmtv = (NM_TREEVIEW *) pNMHDR;
if (m_flags & SHLT_REFRESHONEXPAND)
{
if ((pnmtv->itemNew.state & TVIS_EXPANDED) && GetChildItem (pnmtv->itemNew.hItem))
{
Expand (pnmtv->itemNew.hItem, TVE_COLLAPSE);
DeleteChildren (pnmtv->itemNew.hItem);
return;
}
}
else
{
//:originally alone
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;
}
/****************************************************************************
*
* FUNCTION: GetContextMenu(NMHDR* pNMHDR, LRESULT* pResult)
*
* PURPOSE: Diplays a popup menu for the folder selected. Pass the
* parameters from Rclick() to this function.
*
* MESSAGEMAP: NM_RCLICK;
*
****************************************************************************/
#pragma warning ( disable : 4100 )
void CShellTree::
GetContextMenu (NMHDR * pNMHDR, LRESULT * pResult)
{
// TODO: Add your control notification handler code here
POINT pt;
LPTVITEMDATA lptvid; //Long pointer to TreeView item data
LPSHELLFOLDER lpsf2 = NULL;
static TCHAR 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;
}
#pragma warning ( default : 4100 )
/****************************************************************************
*
* 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 CShellTree::
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 TCHAR szBuff[MAX_PATH];
HRESULT hr;
BOOL bRet = false;
TV_SORTCB tvscb;
HTREEITEM hItem = NULL;
if ((hItem = GetSelectedItem ()) != NULL)
{
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
*
****************************************************************************/
#pragma warning ( disable : 4100 )
void CShellTree::
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 ();
}
#pragma warning ( default : 4100 )
/****************************************************************************
*
* 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 CShellTree::
EnableImages ()
{
// Get the handle to the system image list, for our icons
HIMAGELIST hImageList;
SHFILEINFO sfi;
hImageList = (HIMAGELIST) SHGetFileInfo ((LPCTSTR) _T ("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: GetPointedFolderPath( const CPoint & point, CString &szFolderPath )
*
* PURPOSE: Retrieves the path of the currently pointed 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 CShellTree::
GetPointedFolderPath (const CPoint & point, CString & szFolderPath)
{
LPTVITEMDATA lptvid; //Long pointer to TreeView item data
LPSHELLFOLDER lpsf2 = NULL;
static TCHAR szBuff[MAX_PATH];
HTREEITEM hItem = NULL;
HRESULT hr;
BOOL bRet = false;
TV_HITTESTINFO tvhti;
tvhti.pt = point;
HitTest (&tvhti);
if (tvhti.flags & (TVHT_ONITEMLABEL | TVHT_ONITEMICON))
{
hItem = tvhti.hItem;
}
if (hItem)
{
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;
}
}
}
else
{
if (lpsf2)
lpsf2->Release ();
HTREEITEM hItem2 = GetParentItem (hItem);
if (hItem2)
{
lptvid = (LPTVITEMDATA) GetItemData (hItem2);
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))
{
CString item = GetItemText (hItem);
szFolderPath = szBuff[_tcslen (szBuff) - 1] == _T ('\\') ? szBuff + item : CString (szBuff) + _T ("\\") + item;
bRet = true;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -