📄 dirtreeview.cpp
字号:
strcpy (fd.cFileName, buff);
fd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
image1 = GetIconIndex (fd);
fd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY | SHGFI_OPENICON;
image2 = GetIconIndex (fd);
newNode = InsertChild (node, buff, image1, image2, TVI_SORT);
}
}
// Build a path name based on the node.
BuildPath(dirPath, newNode);
// Add wildcards
dirPath += "*.*";
//
// Look for the first match. Return if none.
if ((hFind = FindFirstFile(dirPath, &fd)) == INVALID_HANDLE_VALUE)
{
return;
}
// add one to the level we are on
m_nLevel++;
do
{
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& (!(fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)))
{
if (!strcmp (fd.cFileName, "."))
{
; // Current directory. Do nothing.
}
else if (!strcmp (fd.cFileName, ".."))
{
; // Parent directory. Do nothing.
}
else
{
// If the are building the intial tree structure (tmShort) or we are
// expanding a level (tmDetail), add the node by recursion.
if (((mode == CDirTreeView::tmShort)
&& (m_nLevel < 2))
|| (mode == CDirTreeView::tmDetail))
AddNode(fd.cFileName, newNode, 0, mode); // type, 0); // mode);
// If we're building the initial structure, we want to add only one
// subnode to make the plus symbold appear.
if (mode == CDirTreeView::tmShort)
break;
// In the detail mode we need to fill this branch completely
// but only one sub-node per node under this branch. Again,
// we have to do this so the + sign shows up next to the node.
if (mode == CDirTreeView::tmDetail && m_nLevel > 1)
{
break;
}
}
}
} while (::FindNextFile (hFind, &fd)); // Look for the next match
FindClose (hFind);
// decrement the level counter
m_nLevel--;
}
//
// InsertChild() inserts a new node in the tree as a child of the node
// passed as the parent.Images default to 0 and SortType default to TVI_SORT
//
HTREEITEM CDirTreeView::InsertChild(HTREEITEM parent, char * label, int image, int selimage, HTREEITEM SortType)
{
CTreeCtrl& tc = GetTreeCtrl ();
TV_INSERTSTRUCT TreeItem;
//
// Zero out the new structure. CTreeCtrl doesn't like stray data.
//
memset ((char *) &TreeItem, '\0', sizeof (TV_INSERTSTRUCT));
TreeItem.hParent = parent == NULL ? TVI_ROOT : parent;
TreeItem.hInsertAfter = SortType;
TreeItem.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
TreeItem.item.pszText = label;
TreeItem.item.cchTextMax = strlen (label) + 1;
TreeItem.item.lParam = 0;
TreeItem.item.iImage = image;
TreeItem.item.iSelectedImage = image;
TreeItem.item.iSelectedImage = selimage;
return (tc.InsertItem(&TreeItem));
}
void CDirTreeView::SelectStartDir(char * StartDir)
{
char *startDir, Drive[32];
char *s;
CTreeCtrl& tc = GetTreeCtrl ();
HTREEITEM RootNode, node, SelectedNode;
if ((StartDir == NULL) || !strlen (StartDir))
return;
//
// Make a copy of the directory string.
//
startDir = new char [strlen (StartDir) + 1];
strcpy (startDir, StartDir);
//
// Make sure the path contains no forward slashes.
//
while ((s = strchr (startDir, '/')) != NULL)
*s = '\\';
s = strtok (startDir, "\\");
if (s == NULL)
{
s = startDir;
}
//
// Make it all upper case. Less confusion that way. Our first node
// should be the device. Append the trailing backslash, which is the
// way the node is returned from BuildPath
//
//
strupr (s);
sprintf (Drive, "%s\\", s);
// Get the root node
RootNode = tc.GetRootItem ();
// Get the first child item of the root node
node = tc.GetNextItem(RootNode, TVGN_ROOT);
//
// Loop through the siblings until we find our drive
//
for (; node; node = tc.GetNextItem(node, TVGN_NEXT))
{
CString ItemText;
BuildPath (ItemText, node);
//
// If the root paths match, we've found it
//
if (!strcmpi (Drive, (LPCSTR) ItemText))
break;
}
//
// Did we find the start for our directory?
//
if (node == NULL)
{
delete [] startDir;
return;
}
//
// Select this item just in case the next strtok is NULL
//
SelectedNode = node;
s = strtok (NULL, "\\"); // Get the next part of the path
if (s == NULL) // If none, we are finished.
{
tc.Select (SelectedNode, TVGN_CARET);
delete [] startDir;
return;
}
//
// There's more to look for, so expand this item.
//
tc.Expand (node, TVE_EXPAND); // Always expand
while (s != NULL)
{
// for (node = tc.GetNextItem(node, TVGN_CHILD);
for (node = tc.GetNextItem(SelectedNode, TVGN_CHILD);
node;
node = tc.GetNextItem(node, TVGN_NEXT))
{
CString ItemText = tc.GetItemText (node);
if (!ItemText.CompareNoCase (s))
break;
}
//
// If the node was not found, we can't continue. Leave the current
// selection as it is.
//
if (node == NULL)
break;
//
// Select the current item.
//
SelectedNode = node;
s = strtok (NULL, "\\");
// If the next token is not null, expand the current item.
if (s != NULL)
tc.Expand (node, TVE_EXPAND); // Always expand
}
tc.Select (SelectedNode, TVGN_CARET);
delete [] startDir;
}
// BuildPath() builds the path name by recursing backward
// through the tree.
//
void CDirTreeView::BuildPath(CString & path, HTREEITEM node)
{
CTreeCtrl& tc = GetTreeCtrl ();
// get the parent of the current node
HTREEITEM parent = tc.GetParentItem(node);
// Get the text of the node. We'll use it to build the path
CString buff = tc.GetItemText (node);
// add the backslash to the node
buff += "\\";
// Add the current directory name to the path.
//
buff += path;
path = buff;
// If this node has a parent then we recurse until no parent is found.
// If there is no parent, then we are finished building the path.
//
if (parent)
{
BuildPath(path, parent);
}
else
{
// If the parent is found then we need to strip the volume name
// from the string. It is enclosed in parentheses, so look for the
// first open paren and pick up the left side, then find the first
// close paren and pick up the right part.
//
CString dPath = path;
int Length = path.GetLength ();
int pos = dPath.Find("(");
if (pos > 0)
path = dPath.Left (pos - 1);
pos = dPath.Find (")");
if (pos > 0)
path += dPath.Right (Length - pos - 1);
}
}
void CDirTreeView::OnDestroy()
{
m_Images.Detach();
CTreeView::OnDestroy ();
}
int CDirTreeView::GetIconIndex (WIN32_FIND_DATA fd)
{
SHFILEINFO sfi;
memset(&sfi, 0, sizeof(sfi));
CString strFilePath = fd.cFileName;
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
SHGetFileInfo (
strFilePath,
FILE_ATTRIBUTE_DIRECTORY,
&sfi,
sizeof(sfi),
SHGFI_SMALLICON |
SHGFI_SYSICONINDEX |
SHGFI_USEFILEATTRIBUTES |
(fd.dwFileAttributes & SHGFI_OPENICON)
);
return (sfi.iIcon);
}
else
{
SHGetFileInfo (
strFilePath,
FILE_ATTRIBUTE_NORMAL,
// fd.dwFileAttributes,
&sfi,
sizeof(sfi),
// SHGFI_SMALLICON | SHGFI_SYSICONINDEX | SHGFI_USEFILEATTRIBUTES | (fd.dwFileAttributes & SHGFI_OPENICON)
SHGFI_SMALLICON | SHGFI_SYSICONINDEX | (fd.dwFileAttributes & SHGFI_OPENICON)
);
return sfi.iIcon;
}
return (-1);
}
BOOL CDirTreeView::LoadSystemImageList(UINT uiImageList)
{
SHFILEINFO sfiInfo;
memset(&sfiInfo, 0, sizeof(SHFILEINFO));
HIMAGELIST hImages = (HIMAGELIST) (
SHGetFileInfo (
"C:\\",
0,
&sfiInfo,
sizeof(sfiInfo),
SHGFI_SYSICONINDEX | uiImageList)
);
if (hImages == NULL)
return (FALSE);
switch (uiImageList)
{
case SHGFI_SMALLICON:
if (m_Images.m_hImageList != NULL)
m_Images.Detach ();
m_Images.Attach (hImages);
break;
default:
return (FALSE);
}
return (TRUE);
}
CString & CDirTreeView::GetCurrentDirectory()
{
static CString strCurrentPath;
strCurrentPath.Empty ();
int nBytes = ::GetCurrentDirectory (0, NULL);
char *szDir = new char [nBytes + 1];
::GetCurrentDirectory (nBytes + 1, szDir);
strCurrentPath = szDir;
delete [] szDir;
return (strCurrentPath);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -