2023-09-24 17:26:46 -04:00
using System.Collections.Generic ;
2018-03-26 17:01:36 -04:00
using System.Drawing ;
using System.IO ;
2023-09-29 13:58:35 -04:00
using System.Linq ;
2017-11-27 13:11:20 -05:00
using System.Windows.Forms ;
using static Vanara . PInvoke . ComCtl32 ;
2019-08-27 18:03:21 -04:00
using static Vanara . PInvoke . User32 ;
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
namespace Vanara.Extensions ;
/// <summary>Extension methods for <see cref="TreeView"/> controls.</summary>
public static partial class TreeViewExtension
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
/// <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 )
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
if ( Environment . OSVersion . Version . Major > = 6 )
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
// Make sure the TVS_NOHSCROLL style is set
treeView . SetStyle ( ( int ) TreeViewStyle . TVS_NOHSCROLL ) ;
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
// 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 ) ) ;
2017-11-27 13:11:20 -05:00
}
2023-03-31 11:47:53 -04:00
}
2017-11-27 13:11:20 -05:00
2023-03-31 11:47:53 -04:00
/// <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 )
{
2023-09-29 13:58:35 -04:00
foreach ( TreeNode item in nodes . Cast < TreeNode > ( ) )
2017-11-27 13:11:20 -05:00
{
2023-03-31 11:47:53 -04:00
yield return item ;
if ( forAllChildren )
foreach ( var child in item . Nodes . AsEnumerable ( true ) )
yield return child ;
2017-11-27 13:11:20 -05:00
}
2023-03-31 11:47:53 -04:00
}
2018-03-26 17:01:36 -04:00
2023-03-31 11:47:53 -04:00
/// <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 ) ;
2018-03-26 17:01:36 -04:00
2023-03-31 11:47:53 -04:00
if ( ! tv . ImageList . Images . ContainsKey ( ext ) )
{
try
2018-03-26 17:01:36 -04:00
{
2023-12-30 19:50:35 -05:00
tv . ImageList . Images . Add ( ext , IconExtension . GetFileIcon ( ext , GetIconSizeFromSize ( tv . ImageList . ImageSize ) ) ! ) ;
2023-03-31 11:47:53 -04:00
}
catch ( ArgumentException ex )
{
throw new ArgumentException ( $"File \" { systemItemPath } \ " does" + " not exist!" , ex ) ;
2018-03-26 17:01:36 -04:00
}
}
2023-03-31 11:47:53 -04:00
return nodes . Add ( systemItemPath , Path . GetFileName ( systemItemPath ) , ext , ext ) ;
}
2018-03-26 17:01:36 -04:00
2023-03-31 11:47:53 -04:00
/// <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 ) ;
2018-03-26 17:01:36 -04:00
2023-03-31 11:47:53 -04:00
/// <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 ;
2020-02-12 22:06:52 -05:00
2023-03-31 11:47:53 -04:00
/// <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
2020-02-12 22:06:52 -05:00
{
2023-03-31 11:47:53 -04:00
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 ;
}
2020-02-12 22:06:52 -05:00
2023-09-29 13:58:35 -04:00
private static IconSize GetIconSizeFromSize ( Size sz ) = > sz . Height switch
2023-03-31 11:47:53 -04:00
{
2023-09-29 13:58:35 -04:00
16 = > IconSize . Small ,
48 = > IconSize . ExtraLarge ,
256 = > IconSize . Jumbo ,
_ = > IconSize . Large ,
} ;
2017-11-27 13:11:20 -05:00
}