📄 directorytreectrl.cpp
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include "emule.h"
#include "DirectoryTreeCtrl.h"
#include "otherfunctions.h"
#include "Preferences.h"
#include "TitleMenu.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
/////////////////////////////////////////////
// written by robert rostek - tecxx@rrs.at //
/////////////////////////////////////////////
struct STreeItem
{
CString strPath;
};
// CDirectoryTreeCtrl
IMPLEMENT_DYNAMIC(CDirectoryTreeCtrl, CTreeCtrl)
BEGIN_MESSAGE_MAP(CDirectoryTreeCtrl, CTreeCtrl)
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnTvnItemexpanding)
ON_NOTIFY_REFLECT(TVN_GETDISPINFO, OnTvnGetdispinfo)
ON_WM_LBUTTONDOWN()
ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnTvnDeleteItem)
ON_WM_CONTEXTMENU()
ON_WM_RBUTTONDOWN()
ON_WM_KEYDOWN()
ON_WM_CHAR()
END_MESSAGE_MAP()
CDirectoryTreeCtrl::CDirectoryTreeCtrl()
{
m_bSelectSubDirs = false;
}
CDirectoryTreeCtrl::~CDirectoryTreeCtrl()
{
// don't destroy the system's image list
m_image.Detach();
}
void CDirectoryTreeCtrl::OnTvnItemexpanding(NMHDR *pNMHDR, LRESULT *pResult)
{
CWaitCursor curWait;
SetRedraw(FALSE);
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
// remove all subitems
HTREEITEM hRemove = GetChildItem(hItem);
while(hRemove)
{
DeleteItem(hRemove);
hRemove = GetChildItem(hItem);
}
// get the directory
CString strDir = GetFullPath(hItem);
// fetch all subdirectories and add them to the node
AddSubdirectories(hItem, strDir);
SetRedraw(TRUE);
Invalidate();
*pResult = 0;
}
void CDirectoryTreeCtrl::ShareSubDirTree(HTREEITEM hItem, BOOL bRecurse)
{
CWaitCursor curWait;
SetRedraw(FALSE);
HTREEITEM hItemVisibleItem = GetFirstVisibleItem();
CheckChanged(hItem, !GetCheck(hItem));
if (bRecurse)
{
Expand(hItem, TVE_TOGGLE);
HTREEITEM hChild = GetChildItem(hItem);
while (hChild != NULL)
{
MarkChilds(hChild, !GetCheck(hItem));
hChild = GetNextSiblingItem(hChild);
}
Expand(hItem, TVE_TOGGLE);
}
if (hItemVisibleItem)
SelectSetFirstVisible(hItemVisibleItem);
SetRedraw(TRUE);
Invalidate();
}
void CDirectoryTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
//VQB adjustments to provide for sharing or unsharing of subdirectories when control key is Down
UINT uHitFlags;
HTREEITEM hItem = HitTest(point, &uHitFlags);
if (hItem && (uHitFlags & TVHT_ONITEMSTATEICON))
ShareSubDirTree(hItem, nFlags & MK_CONTROL);
CTreeCtrl::OnLButtonDown(nFlags, point);
}
void CDirectoryTreeCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_SPACE)
{
HTREEITEM hItem = GetSelectedItem();
if (hItem)
{
ShareSubDirTree(hItem, GetKeyState(VK_CONTROL) & 0x8000);
// if Ctrl+Space is passed to the tree control, it just beeps and does not check/uncheck the item!
SetCheck(hItem, !GetCheck(hItem));
return;
}
}
CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CDirectoryTreeCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// If we let any keystrokes which are handled by us -- but not by the tree
// control -- pass to the control, the user will hear a system event
// sound (Standard Error!)
BOOL bCallDefault = TRUE;
if (GetKeyState(VK_CONTROL) & 0x8000)
{
if (nChar == VK_SPACE)
bCallDefault = FALSE;
}
if (bCallDefault)
CTreeCtrl::OnChar(nChar, nRepCnt, nFlags);
}
void CDirectoryTreeCtrl::MarkChilds(HTREEITEM hChild,bool mark) {
CheckChanged(hChild, mark);
SetCheck(hChild,mark);
Expand(hChild, TVE_TOGGLE); // VQB - make sure tree has entries
HTREEITEM hChild2;
hChild2 = GetChildItem(hChild);
while( hChild2 != NULL)
{
MarkChilds(hChild2,mark);
hChild2 = GetNextSiblingItem( hChild2 );
}
Expand(hChild, TVE_TOGGLE); // VQB - restore tree to initial disposition
}
void CDirectoryTreeCtrl::OnTvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
pTVDispInfo->item.cChildren = 1;
*pResult = 0;
}
void CDirectoryTreeCtrl::Init(void)
{
ShowWindow(SW_HIDE);
DeleteAllItems();
ModifyStyle( 0, TVS_CHECKBOXES );
// START: added by FoRcHa /////////////
WORD wWinVer = thePrefs.GetWindowsVersion(); // maybe causes problems on 98 & nt4
if(wWinVer == _WINVER_2K_ || wWinVer == _WINVER_XP_ || wWinVer == _WINVER_ME_)
{
SHFILEINFO shFinfo;
HIMAGELIST hImgList = NULL;
// Get the system image list using a "path" which is available on all systems. [patch by bluecow]
hImgList = (HIMAGELIST)SHGetFileInfo(_T("."), 0, &shFinfo, sizeof(shFinfo),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
if(!hImgList)
{
TRACE(_T("Cannot retrieve the Handle of SystemImageList!"));
//return;
}
m_image.m_hImageList = hImgList;
SetImageList(&m_image, TVSIL_NORMAL);
}
////////////////////////////////
TCHAR drivebuffer[500];
::GetLogicalDriveStrings(ARRSIZE(drivebuffer), drivebuffer); // e.g. "a:\ c:\ d:\"
const TCHAR* pos = drivebuffer;
while(*pos != _T('\0')){
// Copy drive name
TCHAR drive[4];
_tcsncpy(drive, pos, ARRSIZE(drive));
drive[ARRSIZE(drive) - 1] = _T('\0');
switch(drive[0]){
case _T('a'):
case _T('A'):
case _T('b'):
case _T('B'):
// Skip floppy disk
break;
default:
drive[2] = _T('\0');
AddChildItem(NULL, drive); // e.g. ("c:")
}
// Point to the next drive (4 chars interval)
pos = &pos[4];
}
ShowWindow(SW_SHOW);
}
HTREEITEM CDirectoryTreeCtrl::AddChildItem(HTREEITEM hRoot, CString strText)
{
CString strPath = GetFullPath(hRoot);
if (hRoot != NULL && strPath.Right(1) != _T("\\"))
strPath += _T("\\");
CString strDir = strPath + strText;
TV_INSERTSTRUCT itInsert;
memset(&itInsert, 0, sizeof(itInsert));
// START: changed by FoRcHa /////
WORD wWinVer = thePrefs.GetWindowsVersion();
if(wWinVer == _WINVER_2K_ || wWinVer == _WINVER_XP_ || wWinVer == _WINVER_ME_)
{
itInsert.item.mask = TVIF_CHILDREN | TVIF_HANDLE | TVIF_TEXT |
TVIF_STATE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
itInsert.item.stateMask = TVIS_BOLD | TVIS_STATEIMAGEMASK;
}
else
{
itInsert.item.mask = TVIF_CHILDREN | TVIF_HANDLE | TVIF_TEXT | TVIF_STATE;
itInsert.item.stateMask = TVIS_BOLD;
}
// END: changed by FoRcHa ///////
if (HasSharedSubdirectory(strDir))
itInsert.item.state = TVIS_BOLD;
else
itInsert.item.state = 0;
if (HasSubdirectories(strDir))
itInsert.item.cChildren = I_CHILDRENCALLBACK; // used to display the + symbol next to each item
else
itInsert.item.cChildren = 0;
itInsert.item.pszText = strText.GetBuffer();
itInsert.item.cchTextMax = strText.GetLength();
itInsert.hInsertAfter = hRoot ? TVI_SORT : TVI_LAST;
itInsert.hParent = hRoot;
// START: added by FoRcHa ////////////////
if(wWinVer == _WINVER_2K_ || wWinVer == _WINVER_XP_ || wWinVer == _WINVER_ME_)
{
CString strTemp = strDir;
if(strTemp.Right(1) != _T("\\"))
strTemp += _T("\\");
UINT nType = GetDriveType(strTemp);
if(DRIVE_REMOVABLE <= nType && nType <= DRIVE_RAMDISK)
itInsert.item.iImage = nType;
SHFILEINFO shFinfo;
shFinfo.szDisplayName[0] = _T('\0');
if(!SHGetFileInfo(strTemp, 0, &shFinfo, sizeof(shFinfo),
SHGFI_ICON | SHGFI_SMALLICON | SHGFI_DISPLAYNAME))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -