From 56931b57b7391e45f652354232a6ba28f5f3392a Mon Sep 17 00:00:00 2001 From: dahall Date: Thu, 5 Nov 2020 07:28:08 -0700 Subject: [PATCH] More work on ShellDataTable --- UnitTests/Windows.Shell/ShellDataTests.cs | 6 ++-- Windows.Shell/ShellData/ShellDataTable.cs | 57 +++++++++++++------------------ 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/UnitTests/Windows.Shell/ShellDataTests.cs b/UnitTests/Windows.Shell/ShellDataTests.cs index faee5bdc..236f424f 100644 --- a/UnitTests/Windows.Shell/ShellDataTests.cs +++ b/UnitTests/Windows.Shell/ShellDataTests.cs @@ -20,7 +20,7 @@ namespace Vanara.Windows.Shell.Tests { // Create empty table var timer = Stopwatch.StartNew(); - var shData = new ShellDataTable(new ShellFolder(KNOWNFOLDERID.FOLDERID_Documents)); + var shData = new ShellDataTable(new ShellFolder(KNOWNFOLDERID.FOLDERID_Documents), FolderItemFilter.NonFolders | FolderItemFilter.Folders | FolderItemFilter.IncludeHidden); TestContext.WriteLine($"{timer.ElapsedMilliseconds}\t** Init complete **"); // Get list of default and slow columns to fetch @@ -34,7 +34,7 @@ namespace Vanara.Windows.Shell.Tests shData.AllFastRowsAdded += (s, e) => TestContext.WriteLine($"{timer.ElapsedMilliseconds}\t** Fast items complete **"); shData.TableLoaded += (s, e) => TestContext.WriteLine($"{timer.ElapsedMilliseconds}\t** All done **"); var ct = new CancellationTokenSource(); - shData.PopulateTableAsync(cols, ShellItemQueryOptions.ShowHidden, ct.Token).Wait(TimeSpan.FromSeconds(30)); + shData.PopulateTableAsync(cols, ct.Token).Wait(TimeSpan.FromSeconds(30)); timer.Stop(); @@ -67,7 +67,7 @@ namespace Vanara.Windows.Shell.Tests shData.AllFastRowsAdded += (s, e) => TestContext.WriteLine($"{timer.ElapsedMilliseconds}\t** Fast items complete **"); shData.TableLoaded += (s, e) => TestContext.WriteLine($"{timer.ElapsedMilliseconds}\t** All done **"); var ct = new CancellationTokenSource(); - shData.PopulateTableAsync(cols, ShellItemQueryOptions.ShowHidden, ct.Token).Wait(TimeSpan.FromSeconds(30)); + shData.PopulateTableAsync(cols, ct.Token).Wait(TimeSpan.FromSeconds(30)); timer.Stop(); diff --git a/Windows.Shell/ShellData/ShellDataTable.cs b/Windows.Shell/ShellData/ShellDataTable.cs index 4197dd28..fb8cc37f 100644 --- a/Windows.Shell/ShellData/ShellDataTable.cs +++ b/Windows.Shell/ShellData/ShellDataTable.cs @@ -11,23 +11,6 @@ using static Vanara.PInvoke.Shell32; namespace Vanara.Windows.Shell { - /// Options used when requesting items from a shell folder. - [Flags] - public enum ShellItemQueryOptions - { - /// Include hidden items. - ShowHidden = 0x01, - - /// Include empty drives. - ShowEmptyDrives = 0x02, - - /// Hide the extension, if known. - HideExtIfKnown = 0x04, - - /// Include system protected items. - ShowSystemProtected = 0x08, - } - /// Represents a that is populated asynchronously with information about shell items. /// public class ShellDataTable : DataTable @@ -37,7 +20,9 @@ namespace Vanara.Windows.Shell private const string extPropKey = "PropertyKey"; private const string extSlow = "Slow"; private const string extState = "ColState"; + private readonly FolderItemFilter itemFilter; private readonly ShellFolder parent; + private DataColumn[] colsToGet; private List defCols; private IEnumerable items; @@ -51,8 +36,10 @@ namespace Vanara.Windows.Shell /// Initializes a new instance of the class with the items from a shell folder. /// The folder whose items are to be retrieved. - public ShellDataTable(ShellFolder folder) : base(folder.ParsingName) + /// The filter to determine which child items of the folder are enumerated. + public ShellDataTable(ShellFolder folder, FolderItemFilter filter = FolderItemFilter.Folders | FolderItemFilter.NonFolders) : base(folder.ParsingName) { + itemFilter = filter; BuildColumns(parent = folder); } @@ -88,43 +75,40 @@ namespace Vanara.Windows.Shell /// Populates the table with all the requested shell items. /// The names of the columns to populate. - /// The options for the query. /// The cancellation token. - public async Task PopulateTableAsync(IEnumerable columns, ShellItemQueryOptions options, CancellationToken cancellationToken) + public async Task PopulateTableAsync(IEnumerable columns, CancellationToken cancellationToken) { var columnsToGet = columns.Where(n => n != colId).Select(n => Columns[n]).ToArray(); - await PopulateTableAsync(columnsToGet, options, cancellationToken); + await PopulateTableAsync(columnsToGet, cancellationToken); } /// Populates the table with all the requested shell items. /// The PROPERTYKEY values of the columns to populate. - /// The options for the query. /// The cancellation token. - public async Task PopulateTableAsync(IEnumerable columns, ShellItemQueryOptions options, CancellationToken cancellationToken) + public async Task PopulateTableAsync(IEnumerable columns, CancellationToken cancellationToken) { var columnsToGet = columns.Join(Columns.Cast(), k => k, c => GetColumnPropertyKey(c), (k, c) => c).ToArray(); - await PopulateTableAsync(columnsToGet, options, cancellationToken); + await PopulateTableAsync(columnsToGet, cancellationToken); } /// Populates the table with all the requested shell items. /// The columns to populate. - /// The options for the query. /// The cancellation token. - public async Task PopulateTableAsync(IEnumerable columns, ShellItemQueryOptions options, CancellationToken cancellationToken) + public async Task PopulateTableAsync(IEnumerable columns, CancellationToken cancellationToken) { var columnsToGet = columns.ToArray(); if (columnsToGet.Except(Columns.Cast()).Any()) throw new ArgumentException("Columns specified that are not in table.", nameof(columnsToGet)); + colsToGet = columnsToGet; + + if (!(parent is null)) + { + items = parent.IShellFolder.EnumObjects((SHCONTF)itemFilter); + } if (items is null && !(parent is null)) { - var qFlags = FolderItemFilter.NonFolders | FolderItemFilter.Folders; - if (options.IsFlagSet(ShellItemQueryOptions.ShowHidden)) - qFlags |= FolderItemFilter.IncludeHidden; - if (options.IsFlagSet(ShellItemQueryOptions.ShowSystemProtected)) - qFlags |= FolderItemFilter.IncludeSuperHidden; - - items = parent.IShellFolder.EnumObjects((SHCONTF)qFlags); + items = parent.IShellFolder.EnumObjects((SHCONTF)itemFilter); } if (Rows.Count > 0) @@ -174,7 +158,7 @@ namespace Vanara.Windows.Shell } } catch { } - + return o switch { System.Runtime.InteropServices.ComTypes.FILETIME ft => ft.ToDateTime(), @@ -197,6 +181,11 @@ namespace Vanara.Windows.Shell } } + /// Refreshes the data table. If columns have not been previously provided, the default columns are used. + /// The cancellation token. + public async Task RefreshAsync(CancellationToken cancellationToken) => + await PopulateTableAsync((IEnumerable)colsToGet ?? DefaultColumns, cancellationToken); + private void BuildColumns(ShellFolder folder) { BeginInit();