mirror of https://github.com/dahall/Vanara.git
119 lines
5.4 KiB
C#
119 lines
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows.Forms;
|
|
using Vanara.PInvoke;
|
|
using static Vanara.PInvoke.ComCtl32;
|
|
using static Vanara.PInvoke.Shell32;
|
|
using static Vanara.PInvoke.User32;
|
|
|
|
namespace Vanara.Extensions
|
|
{
|
|
/// <summary>Extension methods for <see cref="TreeView"/> controls.</summary>
|
|
public static partial class TreeViewExtension
|
|
{
|
|
/// <summary>Sets the explorer theme on this <see cref="TreeView"/> instance.</summary>
|
|
/// <param name="treeView">The tree view on which to set the theme.</param>
|
|
/// <param name="on">If set to <c>true</c> use the Windows Explorer theme, otherwise set to default theme.</param>
|
|
public static void SetExplorerTheme(this TreeView treeView, bool on = true)
|
|
{
|
|
if (Environment.OSVersion.Version.Major >= 6)
|
|
{
|
|
// Make sure the TVS_NOHSCROLL style is set
|
|
treeView.SetStyle((int)TreeViewStyle.TVS_NOHSCROLL);
|
|
|
|
// Set explorer theme, set critical properties, and set extended styles
|
|
treeView.SetWindowTheme(on ? "explorer" : null);
|
|
if (!on) return;
|
|
treeView.HotTracking = true;
|
|
treeView.ShowLines = false;
|
|
SendMessage(treeView.Handle, (uint)TreeViewMessage.TVM_SETEXTENDEDSTYLE, (IntPtr)(TreeViewStyleEx.TVS_EX_FADEINOUTEXPANDOS | TreeViewStyleEx.TVS_EX_AUTOHSCROLL), (IntPtr)(TreeViewStyleEx.TVS_EX_FADEINOUTEXPANDOS | TreeViewStyleEx.TVS_EX_AUTOHSCROLL));
|
|
}
|
|
}
|
|
|
|
/// <summary>Enumerates child nodes of a given <see cref="TreeNodeCollection"/>.</summary>
|
|
/// <param name="nodes">The <see cref="TreeNodeCollection"/> instance from which to start the enumeration.</param>
|
|
/// <param name="forAllChildren">if set to <c>true</c> also includes child nodes of all child nodes.</param>
|
|
/// <returns>An <see cref="IEnumerable{T}"/> of all <see cref="TreeNode"/> instances in the collection.</returns>
|
|
public static IEnumerable<TreeNode> AsEnumerable(this TreeNodeCollection nodes, bool forAllChildren = false)
|
|
{
|
|
foreach (TreeNode item in nodes)
|
|
{
|
|
yield return item;
|
|
if (forAllChildren)
|
|
foreach (var child in item.Nodes.AsEnumerable(true))
|
|
yield return child;
|
|
}
|
|
}
|
|
|
|
/// <summary>Adds the file system item into a <see cref="TreeView"/> and adds the shell icon associated with it to the <see cref="ImageList"/> of the <c>TreeView</c>.</summary>
|
|
/// <param name="tv">The tree view into which to add the item.</param>
|
|
/// <param name="nodes">The <see cref="TreeNodeCollection"/> that receives the newly created <see cref="TreeNode"/>.</param>
|
|
/// <param name="systemItemPath">The path of the item to add.</param>
|
|
/// <returns>A <see cref="TreeNode"/> instance created </returns>
|
|
public static TreeNode AddSystemItemAsNode(this TreeView tv, TreeNodeCollection nodes, string systemItemPath)
|
|
{
|
|
var ext = Path.GetExtension(systemItemPath);
|
|
if (string.IsNullOrEmpty(ext))
|
|
ext = "5EEB255733234c4dBECF9A128E896A1E";
|
|
//ext = fullName.EndsWith("\\") ? "5EEB255733234c4dBECF9A128E896A1E" : "F9EB930C78D2477c80A51945D505E9C4";
|
|
else if (ext.Equals(".exe", StringComparison.InvariantCultureIgnoreCase) || ext.Equals(".lnk", StringComparison.InvariantCultureIgnoreCase))
|
|
ext = Path.GetFileName(systemItemPath);
|
|
|
|
if (!tv.ImageList.Images.ContainsKey(ext))
|
|
{
|
|
try
|
|
{
|
|
tv.ImageList.Images.Add(ext, IconExtension.GetFileIcon(ext, GetIconSizeFromSize(tv.ImageList.ImageSize)));
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
throw new ArgumentException($"File \"{systemItemPath}\" does" + " not exist!", ex);
|
|
}
|
|
}
|
|
return nodes.Add(systemItemPath, Path.GetFileName(systemItemPath), ext, ext);
|
|
}
|
|
|
|
/// <summary>Enumerates all the nodes in the <see cref="TreeView"/>.</summary>
|
|
/// <param name="treeView">The tree view.</param>
|
|
/// <returns>An <see cref="IEnumerable{T}"/> of all <see cref="TreeNode"/> instances in this <see cref="TreeView"/>.</returns>
|
|
public static IEnumerable<TreeNode> EnumerateAllNodes(this TreeView treeView) => AsEnumerable(treeView.Nodes, true);
|
|
|
|
/// <summary>Sets the <see cref="TVITEM"/> values.</summary>
|
|
/// <param name="node">The <see cref="TreeNode"/> instance for which to set details.</param>
|
|
/// <param name="tvItem">The <see cref="TVITEMEX"/> instance.</param>
|
|
public static bool SetItem(this TreeNode node, ref TVITEMEX tvItem) => SendMessage(node.TreeView.Handle, TreeViewMessage.TVM_SETITEM, default, ref tvItem).ToInt32() != 0;
|
|
|
|
/// <summary>Gets the node values.</summary>
|
|
/// <param name="node">The <see cref="TreeNode"/> instance for which to get details.</param>
|
|
/// <param name="mask">The mask of items to get.</param>
|
|
/// <param name="stateMask">The mask of states to get.</param>
|
|
/// <returns>A <see cref="TVITEMEX"/> structure with the information.</returns>
|
|
public static TVITEMEX GetItem(this TreeNode node, TreeViewItemMask mask = (TreeViewItemMask)0x13FF, TreeViewItemStates stateMask = (TreeViewItemStates)0xFFFF)
|
|
{
|
|
var tvItem = new TVITEMEX
|
|
{
|
|
hItem = node.Handle,
|
|
mask = mask.SetFlags(TreeViewItemMask.TVIF_HANDLE).SetFlags(TreeViewItemMask.TVIF_TEXT, false),
|
|
stateMask = stateMask
|
|
};
|
|
SendMessage(node.TreeView.Handle, TreeViewMessage.TVM_GETITEM, default, ref tvItem);
|
|
return tvItem;
|
|
}
|
|
|
|
private static IconSize GetIconSizeFromSize(Size sz)
|
|
{
|
|
switch (sz.Height)
|
|
{
|
|
case 16: return IconSize.Small;
|
|
case 48: return IconSize.ExtraLarge;
|
|
case 256: return IconSize.Jumbo;
|
|
case 32:
|
|
default:
|
|
return IconSize.Large;
|
|
}
|
|
}
|
|
}
|
|
} |