📄 filetreectrl.cpp
字号:
if (!bFound)
testPoint.x++;
}
while (!bFound);
point.x = testPoint.x;
CRect r(point.x, point.y, point.x+16, point.y+16);
//Draw it using the IL
dc.FillSolidRect(&r, RGB(255, 255, 255));
m_ilNetwork.Draw(&dc, nIndexToDraw, point, ILD_NORMAL);
//Release the DC
dc.Detach();
}
}
*pResult = CDRF_DODEFAULT;
break;
}
default:
{
break;
}
}
return TRUE; //Allow the message to be reflected again
}
BOOL CTreeFileCtrl::OnSelChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
//Nothing selected
if (pNMTreeView->itemNew.hItem == NULL)
return FALSE;
//Check to see if the current item is valid, if not then delete it (Exclude network items from this check)
CTreeFileCtrlItemInfo* pItem = (CTreeFileCtrlItemInfo*) GetItemData(pNMTreeView->itemNew.hItem);
ASSERT(pItem);
CString sPath = pItem->m_sFQPath;
if ((pNMTreeView->itemNew.hItem != m_hNetworkRoot) && (pItem->m_pNetResource == NULL) &&
(pNMTreeView->itemNew.hItem != m_hMyComputerRoot) && !IsDrive(sPath) && (GetFileAttributes(sPath) == 0xFFFFFFFF))
{
//Before we delete it see if we are the only child item
HTREEITEM hParent = GetParentItem(pNMTreeView->itemNew.hItem);
//Delete the item
DeleteItem(pNMTreeView->itemNew.hItem);
//Remove all the child items from the parent
SetHasPlusButton(hParent, FALSE);
*pResult = 1;
return FALSE; //Allow the message to be reflected again
}
//Add to the prev array the item we were just at
if (pNMTreeView->itemOld.hItem && !m_bUpdatingHistorySelection)
{
if (m_PrevItems.GetSize() > m_nMaxHistory)
m_PrevItems.RemoveAt(0);
m_PrevItems.Add(pNMTreeView->itemOld.hItem);
}
//Remeber the serial number for this item (if it is a drive)
if (IsDrive(sPath))
{
int nDrive = sPath.GetAt(0) - _T('A');
GetSerialNumber(sPath, m_dwMediaID[nDrive]);
}
//call the virtual function
OnSelectionChanged(pNMTreeView, sPath);
*pResult = 0;
return FALSE; //Allow the message to be reflected again
}
void CTreeFileCtrl::OnSelectionChanged(NM_TREEVIEW*, const CString&)
{
}
BOOL CTreeFileCtrl::OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pDispInfo = (TV_DISPINFO*)pNMHDR;
if (pDispInfo->item.pszText)
{
SHFILEOPSTRUCT shfo;
ZeroMemory(&shfo, sizeof(SHFILEOPSTRUCT));
shfo.hwnd = AfxGetMainWnd()->GetSafeHwnd();
shfo.wFunc = FO_RENAME;
shfo.fFlags = FOF_ALLOWUNDO;
//Work out the "From" string
CString sFrom = ItemToPath(pDispInfo->item.hItem);
int nFromLength = sFrom.GetLength();
TCHAR* pszFrom = new TCHAR[nFromLength + 2];
_tcscpy(pszFrom, sFrom);
pszFrom[nFromLength+1] = _T('\0');
shfo.pFrom = pszFrom;
HTREEITEM hParent = GetParentItem(pDispInfo->item.hItem);
CString sParent = ItemToPath(hParent);
//Work out the "To" string
CString sTo;
CString sToRelative(pDispInfo->item.pszText);
if (IsDrive(sParent))
sTo = sParent + pDispInfo->item.pszText;
else
sTo = sParent + _T("\\") + pDispInfo->item.pszText;
CTreeFileCtrlItemInfo* pItem = (CTreeFileCtrlItemInfo*) GetItemData(pDispInfo->item.hItem);
ASSERT(pItem);
if (pItem->m_bExtensionHidden)
{
TCHAR szExt[_MAX_EXT];
_tsplitpath(sFrom, NULL, NULL, NULL, szExt);
sTo += szExt;
sToRelative += szExt;
}
int nToLength = _tcslen(sTo);
TCHAR* pszTo = new TCHAR[nToLength + 2];
_tcscpy(pszTo, sTo);
pszTo[nToLength+1] = _T('\0');
shfo.pTo = pszTo;
BOOL bOldAutoRefresh = m_bAutoRefresh;
m_bAutoRefresh = FALSE; //Prevents us from getting thread notifications
//Let the shell perform the actual rename
if (SHFileOperation(&shfo) == 0 && shfo.fAnyOperationsAborted == FALSE)
{
*pResult = TRUE;
//Update its text
SetItemText(pDispInfo->item.hItem, pDispInfo->item.pszText);
//Update the item data
pItem->m_sFQPath = sTo;
pItem->m_sRelativePath = sToRelative;
//Also update the icons for it (if need be)
if (!pItem->m_bExtensionHidden)
{
CString sPath = ItemToPath(pDispInfo->item.hItem);
SetItemImage(pDispInfo->item.hItem, GetIconIndex(sPath), GetSelIconIndex(sPath));
}
}
m_bAutoRefresh = bOldAutoRefresh;
//Don't forget to free up the memory we allocated
delete [] pszFrom;
delete [] pszTo;
}
*pResult = 0;
return FALSE; //Allow the message to be reflected again
}
BOOL CTreeFileCtrl::PreTranslateMessage(MSG* pMsg)
{
// When an item is being edited make sure the edit control
// receives certain important key strokes
if (GetEditControl())
{
::TranslateMessage(pMsg);
::DispatchMessage(pMsg);
return TRUE; // DO NOT process further
}
//Context menu via the keyboard
if ((((pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN) && // If we hit a key and
(pMsg->wParam == VK_F10) && (GetKeyState(VK_SHIFT) & 0x8000)) != 0) || // it's Shift+F10 OR
(pMsg->message == WM_CONTEXTMENU)) // Natural keyboard key
{
CRect rect;
GetItemRect(GetSelectedItem(), rect, TRUE);
ClientToScreen(rect);
OnContextMenu(NULL, rect.CenterPoint());
return TRUE;
}
//Hitting the Escape key, Cancelling drag & drop
else if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE && IsDragging())
{
EndDragging(TRUE);
return TRUE;
}
//Hitting the Alt-Enter key combination, show the properties sheet
else if (pMsg->message == WM_SYSKEYDOWN && pMsg->wParam == VK_RETURN)
{
PostMessage(WM_COMMAND, ID_TREEFILECTRL_PROPERTIES);
return TRUE;
}
//Hitting the Enter key, open the item
else if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
{
PostMessage(WM_COMMAND, ID_TREEFILECTRL_OPEN);
return TRUE;
}
//Hitting the delete key, delete the item
else if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_DELETE)
{
PostMessage(WM_COMMAND, ID_TREEFILECTRL_DELETE);
return TRUE;
}
//hitting the backspace key, go to the parent folder
else if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_BACK)
{
UpOneLevel();
return TRUE;
}
//hitting the F2 key, being in-place editing of an item
else if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F2)
{
PostMessage(WM_COMMAND, ID_TREEFILECTRL_RENAME);
return TRUE;
}
//hitting the F5 key, force a refresh of the whole tree
else if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F5)
{
PostMessage(WM_COMMAND, ID_TREEFILECTRL_REFRESH);
return TRUE;
}
//Hitting the Alt-Left Arrow key combination, move to the previous item
else if (pMsg->message == WM_SYSKEYDOWN && pMsg->wParam == VK_LEFT)
{
PostMessage(WM_COMMAND, ID_TREEFILECTRL_BACK);
return TRUE;
}
//Hitting the Alt-Right Arrow key combination, move to the next item
else if (pMsg->message == WM_SYSKEYDOWN && pMsg->wParam == VK_RIGHT)
{
PostMessage(WM_COMMAND, ID_TREEFILECTRL_FORWARD);
return TRUE;
}
//Let the parent class do its thing
return CTreeCtrl::PreTranslateMessage(pMsg);
}
void CTreeFileCtrl::OnUpOneLevel()
{
HTREEITEM hItem = GetSelectedItem();
if (hItem)
{
HTREEITEM hParent = GetParentItem(hItem);
if (hParent)
Select(hParent, TVGN_CARET);
}
}
void CTreeFileCtrl::UpOneLevel()
{
SendMessage(WM_COMMAND, ID_TREEFILECTRL_UPONELEVEL);
}
void CTreeFileCtrl::OnUpdateUpOneLevel(CCmdUI* pCmdUI)
{
HTREEITEM hItem = GetSelectedItem();
if (hItem)
pCmdUI->Enable(GetParentItem(hItem) != NULL);
else
pCmdUI->Enable(FALSE);
}
BOOL CTreeFileCtrl::IsFile(HTREEITEM hItem)
{
return IsFile(ItemToPath(hItem));
}
BOOL CTreeFileCtrl::IsFolder(HTREEITEM hItem)
{
return IsFolder(ItemToPath(hItem));
}
BOOL CTreeFileCtrl::IsDrive(HTREEITEM hItem)
{
return IsDrive(ItemToPath(hItem));
}
BOOL CTreeFileCtrl::DriveHasRemovableMedia(const CString& sPath)
{
BOOL bRemovableMedia = FALSE;
if (IsDrive(sPath))
{
UINT nDriveType = GetDriveType(sPath);
bRemovableMedia = ((nDriveType == DRIVE_REMOVABLE) ||
(nDriveType == DRIVE_CDROM));
}
return bRemovableMedia;
}
BOOL CTreeFileCtrl::IsCompressed(HTREEITEM hItem)
{
return IsCompressed(ItemToPath(hItem));
}
BOOL CTreeFileCtrl::IsEncrypted(HTREEITEM hItem)
{
return IsEncrypted(ItemToPath(hItem));
}
BOOL CTreeFileCtrl::IsFile(const CString& sPath)
{
DWORD dwAttributes = GetFileAttributes(sPath);
return ((dwAttributes != 0xFFFFFFFF) && ((dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0));
}
BOOL CTreeFileCtrl::IsFolder(const CString& sPath)
{
DWORD dwAttributes = GetFileAttributes(sPath);
return ((dwAttributes != 0xFFFFFFFF) && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY));
}
BOOL CTreeFileCtrl::IsDrive(const CString& sPath)
{
return (sPath.GetLength() == 3 && sPath.GetAt(1) == _T(':') && sPath.GetAt(2) == _T('\\'));
}
BOOL CTreeFileCtrl::IsCompressed(const CString& sPath)
{
BOOL bCompressed = FALSE;
if (!IsDrive(sPath))
{
DWORD dwAttributes = GetFileAttributes(sPath);
bCompressed = ((dwAttributes != 0xFFFFFFFF) && (dwAttributes & FILE_ATTRIBUTE_COMPRESSED));
}
return bCompressed;
}
BOOL CTreeFileCtrl::IsEncrypted(const CString& sPath)
{
BOOL bEncrypted = FALSE;
if (!IsDrive(sPath))
{
DWORD dwAttributes = GetFileAttributes(sPath);
bEncrypted = ((dwAttributes != 0xFFFFFFFF) && (dwAttributes & FILE_ATTRIBUTE_ENCRYPTED));
}
return bEncrypted;
}
BOOL CTreeFileCtrl::HasGotSubEntries(const CString& sDirectory)
{
ASSERT(sDirectory.GetLength());
if (DriveHasRemovableMedia(sDirectory))
{
return TRUE; //we do not bother searching for files on drives
//which have removable media as this would cause
//the drive to spin up, which for the case of a
//floppy is annoying
}
else
{
//First check to see if there is any sub directories
CFileFind find1;
CString sFile;
if (sDirectory.GetAt(sDirectory.GetLength()-1) == _T('\\'))
sFile = sDirectory + _T("*.*");
else
sFile = sDirectory + _T("\\*.*");
BOOL bFind = find1.FindFile(sFile);
while (bFind)
{
bFind = find1.FindNextFile();
if (CanDisplayFolder(find1))
return TRUE;
}
//Now check to see if there is any files of the specfied file mask
CFileFind find2;
if (sDirectory.GetAt(sDirectory.GetLength()-1) == _T('\\'))
sFile = sDirectory + m_sFileNameMask;
else
sFile = sDirectory + _T("\\") + m_sFileNameMask;
bFind = find2.FindFile(sFile);
while (bFind)
{
bFind = find2.FindNextFile();
if (CanDisplayFile(find2))
return TRUE;
}
}
return FALSE;
}
void CTreeFileCtrl::PopulateTree()
{
ASSERT(GetSafeHwnd()); //Should only call this function after the creat
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -