📄 filetreectrl.cpp
字号:
}
void CTreeFileCtrl::OnUpdateOpen(CCmdUI* pCmdUI)
{
HTREEITEM hSelItem = GetSelectedItem();
if (hSelItem)
{
if (m_bAllowOpen)
{
CTreeFileCtrlItemInfo* pItem = (CTreeFileCtrlItemInfo*) GetItemData(hSelItem);
ASSERT(pItem);
if (pItem->m_bNetworkNode)
{
if (pItem->m_pNetResource)
pCmdUI->Enable(pItem->m_pNetResource->dwDisplayType == RESOURCEDISPLAYTYPE_SERVER ||
pItem->m_pNetResource->dwDisplayType == RESOURCEDISPLAYTYPE_SHARE);
else
pCmdUI->Enable(FALSE);
}
else
pCmdUI->Enable(TRUE);
}
else
pCmdUI->Enable(FALSE);
}
else
pCmdUI->Enable(FALSE);
}
void CTreeFileCtrl::OnDelete()
{
Delete(GetSelectedItem());
}
void CTreeFileCtrl::OnUpdateDelete(CCmdUI* pCmdUI)
{
HTREEITEM hSelItem = GetSelectedItem();
if (hSelItem)
{
CTreeFileCtrlItemInfo* pItem = (CTreeFileCtrlItemInfo*) GetItemData(hSelItem);
ASSERT(pItem);
pCmdUI->Enable(m_bAllowDelete && !IsDrive(hSelItem) && !pItem->m_bNetworkNode);
}
else
pCmdUI->Enable(FALSE);
}
void CTreeFileCtrl::OnContextMenu(CWnd*, CPoint point)
{
CMenu menu;
VERIFY(menu.LoadMenu(IDR_TREEFILECTRL_POPUP));
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
}
HTREEITEM CTreeFileCtrl::InsertFileItem(HTREEITEM hParent, CTreeFileCtrlItemInfo* pItem, BOOL bShared, int nIcon, int nSelIcon, BOOL bCheckForChildren)
{
CString sLabel;
//Correct the label if need be
if (IsDrive(pItem->m_sFQPath) && m_bShowDriveLabels)
sLabel = GetDriveLabel(pItem->m_sFQPath);
else
sLabel = GetCorrectedLabel(pItem);
//Add the actual item
TV_INSERTSTRUCT tvis;
ZeroMemory(&tvis, sizeof(TV_INSERTSTRUCT));
tvis.hParent = hParent;
tvis.hInsertAfter = TVI_LAST;
tvis.item.mask = TVIF_CHILDREN | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT | TVIF_PARAM;
tvis.item.lParam = (LPARAM) pItem;
tvis.item.pszText = sLabel.GetBuffer(sLabel.GetLength());
tvis.item.iImage = nIcon;
tvis.item.iSelectedImage = nSelIcon;
if (bCheckForChildren)
tvis.item.cChildren = HasGotSubEntries(pItem->m_sFQPath);
else
tvis.item.cChildren = TRUE;
if (bShared)
{
tvis.item.mask |= TVIF_STATE;
tvis.item.stateMask |= TVIS_OVERLAYMASK;
tvis.item.state |= INDEXTOOVERLAYMASK(1); //1 is the index for the shared overlay image
}
HTREEITEM hItem = InsertItem(&tvis);
sLabel.ReleaseBuffer();
return hItem;
}
BOOL CTreeFileCtrl::GetChecked(HTREEITEM hItem) const
{
ASSERT(::IsWindow(m_hWnd));
TVITEM item;
item.mask = TVIF_HANDLE | TVIF_STATE;
item.hItem = hItem;
item.stateMask = TVIS_STATEIMAGEMASK;
VERIFY(::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item));
// Return zero if it's not checked, or nonzero otherwise.
return ((BOOL)(item.state >> 12) -1);
}
BOOL CTreeFileCtrl::SetChecked(HTREEITEM hItem, BOOL fCheck)
{
ASSERT(::IsWindow(m_hWnd));
TVITEM item;
item.mask = TVIF_HANDLE | TVIF_STATE;
item.hItem = hItem;
item.stateMask = TVIS_STATEIMAGEMASK;
/*
Since state images are one-based, 1 in this macro turns the check off, and
2 turns it on.
*/
item.state = INDEXTOSTATEIMAGEMASK((fCheck ? 2 : 1));
return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item);
}
void CTreeFileCtrl::Refresh()
{
if (GetSafeHwnd())
OnRefresh();
}
BOOL CTreeFileCtrl::IsExpanded(HTREEITEM hItem)
{
TVITEM tvItem;
tvItem.hItem = hItem;
tvItem.mask = TVIF_HANDLE | TVIF_STATE;
return GetItem(&tvItem) && (tvItem.state & TVIS_EXPANDED);
}
CString CTreeFileCtrl::GetCorrectedLabel(CTreeFileCtrlItemInfo* pItem)
{
CString sLabel(pItem->m_sRelativePath);
switch (m_FileExtensions)
{
case UseTheShellSetting:
{
TCHAR pszLabel[_MAX_PATH];
if (IsFile(pItem->m_sFQPath) && GetFileTitle(pItem->m_sRelativePath, pszLabel, _MAX_PATH) == 0)
{
pItem->m_bExtensionHidden = (sLabel.CompareNoCase(pszLabel) != 0);
sLabel = pszLabel;
}
break;
}
case HideExtension:
{
//Remove the extension if the item is a file
if (IsFile(pItem->m_sFQPath))
{
TCHAR szPath[_MAX_PATH];
TCHAR szDrive[_MAX_DRIVE];
TCHAR szDir[_MAX_DIR];
TCHAR szFname[_MAX_FNAME];
_tsplitpath(pItem->m_sRelativePath, szDrive, szDir, szFname, NULL);
_tmakepath(szPath, szDrive, szDir, szFname, NULL);
sLabel = szPath;
pItem->m_bExtensionHidden = TRUE;
}
break;
}
default:
{
pItem->m_bExtensionHidden = FALSE;
break;
}
}
return sLabel;
}
void CTreeFileCtrl::OnRefresh()
{
//Just in case this will take some time
CWaitCursor wait;
SetRedraw(FALSE);
//Get the item which is currently selected
HTREEITEM hSelItem = GetSelectedItem();
CString sItem;
BOOL bExpanded = FALSE;
if (hSelItem)
{
sItem = ItemToPath(hSelItem);
bExpanded = IsExpanded(hSelItem);
}
theSharedEnumerator.Refresh();
KillNotificationThreads();
//Remove all nodes that currently exist
Clear();
//Display the folder items in the tree
if (m_sRootFolder.IsEmpty())
{
//Should we insert a "My Computer" node
if (m_bShowMyComputer)
{
CTreeFileCtrlItemInfo* pItem = new CTreeFileCtrlItemInfo;
pItem->m_bNetworkNode = FALSE;
int nIcon = 0;
int nSelIcon = 0;
//Get the localized name and correct icons for "My Computer"
LPITEMIDLIST lpMCPidl;
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &lpMCPidl)))
{
SHFILEINFO sfi;
if (SHGetFileInfo((LPCTSTR)lpMCPidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_DISPLAYNAME))
{
pItem->m_sRelativePath = sfi.szDisplayName;
pItem->m_sFQPath = pItem->m_sRelativePath;
}
nIcon = GetIconIndex(lpMCPidl);
nSelIcon = GetSelIconIndex(lpMCPidl);
//Free up the pidl now that we are finished with it
ASSERT(m_pMalloc);
m_pMalloc->Free(lpMCPidl);
m_pMalloc->Release();
}
//Add it to the tree control
m_hMyComputerRoot = InsertFileItem(TVI_ROOT, pItem, FALSE, nIcon, nSelIcon, FALSE);
}
//Display all the drives
if (!m_bShowMyComputer)
DisplayDrives(TVI_ROOT, FALSE);
//Also add network neighborhood if requested to do so
if (m_bDisplayNetwork)
{
CTreeFileCtrlItemInfo* pItem = new CTreeFileCtrlItemInfo;
pItem->m_bNetworkNode = TRUE;
int nIcon = 0;
int nSelIcon = 0;
//Get the localized name and correct icons for "Network Neighborhood"
LPITEMIDLIST lpNNPidl;
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_NETWORK, &lpNNPidl)))
{
SHFILEINFO sfi;
if (SHGetFileInfo((LPCTSTR)lpNNPidl, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_DISPLAYNAME))
{
pItem->m_sRelativePath = sfi.szDisplayName;
pItem->m_sFQPath = pItem->m_sRelativePath;
}
nIcon = GetIconIndex(lpNNPidl);
nSelIcon = GetSelIconIndex(lpNNPidl);
//Free up the pidl now that we are finished with it
ASSERT(m_pMalloc);
m_pMalloc->Free(lpNNPidl);
m_pMalloc->Release();
}
//Add it to the tree control
m_hNetworkRoot = InsertFileItem(TVI_ROOT, pItem, FALSE, nIcon, nSelIcon, FALSE);
}
}
else
{
DisplayPath(m_sRootFolder, TVI_ROOT, FALSE);
if (CanHandleChangeNotifications(m_sRootFolder))
CreateMonitoringThread(m_sRootFolder);
}
//Reselect the initially selected item
if (hSelItem)
SetSelectedPath(sItem, bExpanded);
//Turn back on the redraw flag
SetRedraw(TRUE);
}
BOOL CTreeFileCtrl::OnBeginLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pDispInfo = (TV_DISPINFO*)pNMHDR;
if (pDispInfo->item.hItem)
{
CTreeFileCtrlItemInfo* pItem = (CTreeFileCtrlItemInfo*) GetItemData(pDispInfo->item.hItem);
ASSERT(pItem);
if (m_bAllowRename && !IsDrive(pDispInfo->item.hItem) && !pItem->m_bNetworkNode)
*pResult = FALSE;
else
*pResult = TRUE;
}
else
*pResult = TRUE;
return TRUE; //Allow the message to be reflected again
}
BOOL CTreeFileCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
NMTVCUSTOMDRAW* pCustomDraw = (NMTVCUSTOMDRAW*) pNMHDR;
switch (pCustomDraw->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
{
*pResult = CDRF_NOTIFYITEMDRAW; //Tell the control that we are interested in item notifications
break;
}
case CDDS_ITEMPREPAINT:
{
//Check to see if this item is compressed and if it it is, change its
//color just like explorer does
if (m_bShowCompressedUsingDifferentColor &&
((pCustomDraw->nmcd.uItemState & CDIS_SELECTED) == 0) &&
IsCompressed((HTREEITEM) pCustomDraw->nmcd.dwItemSpec))
pCustomDraw->clrText = m_rgbCompressed;
//also check for encrypted files
else if (m_bShowEncryptedUsingDifferentColor &&
((pCustomDraw->nmcd.uItemState & CDIS_SELECTED) == 0) &&
IsEncrypted((HTREEITEM) pCustomDraw->nmcd.dwItemSpec))
pCustomDraw->clrText = m_rgbEncrypted;
//Let it know that we want post paint notifications
*pResult = CDRF_NOTIFYPOSTPAINT;
break;
}
case CDDS_ITEMPOSTPAINT:
{
HTREEITEM hItem = (HTREEITEM) pCustomDraw->nmcd.dwItemSpec;
CTreeFileCtrlItemInfo* pItem = (CTreeFileCtrlItemInfo*) GetItemData(hItem);
ASSERT(pItem);
if (pItem->m_pNetResource)
{
//Determine if we should custom draw the bitmap
BOOL bDrawIcon = FALSE;
int nIndexToDraw = -1;
switch (pItem->m_pNetResource->dwDisplayType)
{
case RESOURCEDISPLAYTYPE_DOMAIN:
{
bDrawIcon = TRUE;
nIndexToDraw = 0;
break;
}
case RESOURCEDISPLAYTYPE_SERVER:
{
bDrawIcon = TRUE;
nIndexToDraw = 3;
break;
}
case RESOURCEDISPLAYTYPE_SHARE:
{
//Deliberately do nothing
break;
}
case RESOURCEDISPLAYTYPE_ROOT:
{
bDrawIcon = TRUE;
nIndexToDraw = 2;
break;
}
default:
{
bDrawIcon = TRUE;
nIndexToDraw = 1;
break;
}
}
if (bDrawIcon)
{
//Draw the icon of the tree view item using the specified bitmap
CDC dc;
dc.Attach(pCustomDraw->nmcd.hdc);
//First work out the position of the icon
CRect rItemRect;
GetItemRect(hItem, rItemRect, TRUE);
CPoint point(rItemRect.left, rItemRect.top);
UINT nFlags = 0;
CPoint testPoint(pCustomDraw->nmcd.rc.left, rItemRect.top+2);
BOOL bFound = FALSE;
do
{
HitTest(testPoint, &nFlags);
//Prepare for the next time around
bFound = (nFlags & TVHT_ONITEMICON) || (nFlags & TVHT_ONITEMSTATEICON);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -