using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Windows.Forms; using static Vanara.PInvoke.ComCtl32; using static Vanara.PInvoke.User32; namespace Vanara.Extensions; /// Extension methods for controls. public static partial class TreeViewExtension { /// Sets the explorer theme on this instance. /// The tree view on which to set the theme. /// If set to true use the Windows Explorer theme, otherwise set to default theme. 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)); } } /// Enumerates child nodes of a given . /// The instance from which to start the enumeration. /// if set to true also includes child nodes of all child nodes. /// An of all instances in the collection. public static IEnumerable AsEnumerable(this TreeNodeCollection nodes, bool forAllChildren = false) { foreach (TreeNode item in nodes.Cast()) { yield return item; if (forAllChildren) foreach (var child in item.Nodes.AsEnumerable(true)) yield return child; } } /// Adds the file system item into a and adds the shell icon associated with it to the of the TreeView. /// The tree view into which to add the item. /// The that receives the newly created . /// The path of the item to add. /// A instance created 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); } /// Enumerates all the nodes in the . /// The tree view. /// An of all instances in this . public static IEnumerable EnumerateAllNodes(this TreeView treeView) => AsEnumerable(treeView.Nodes, true); /// Sets the values. /// The instance for which to set details. /// The instance. public static bool SetItem(this TreeNode node, ref TVITEMEX tvItem) => SendMessage(node.TreeView.Handle, TreeViewMessage.TVM_SETITEM, default, ref tvItem).ToInt32() != 0; /// Gets the node values. /// The instance for which to get details. /// The mask of items to get. /// The mask of states to get. /// A structure with the information. 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) => sz.Height switch { 16 => IconSize.Small, 48 => IconSize.ExtraLarge, 256 => IconSize.Jumbo, _ => IconSize.Large, }; }