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,
};
}