Items Enumeration

The first method that the Windows Shell will call in your CBFS Shell Namespace Extension is EnumItems. The following is a simple example of such a method, which we first saw in the "Writing your first extension" chapter:

public override IEnumerable<ShellItem> EnumItems(SHCONTF options)
{
    yield return new ShellFolder(this, new StringKeyShellItemId("My First Folder"));
    yield return new ShellItem(this, new StringKeyShellItemId("My First Item"));
}

This EnumItems method simply tells the Shell what Shell items a given Shell folder contains. It is also used, however, by CBFS Shell when the Shell asks for one single item (e.g., for direct access, parsing, searching). For the latter purpose, the ShellFolder class defines two virtual methods, which by default, call EnumItems internally:

    /// Gets an item using its display name.
    protected virtual ShellItem GetItem(string displayName)
    {
        ... pseudo code
        return EnumItems(SHCONTF.SHCONTF_FOLDERS |
            SHCONTF.SHCONTF_NONFOLDERS |
            SHCONTF.SHCONTF_FLATLIST | // all items
            SHCONTF.SHCONTF_INCLUDEHIDDEN |
        
        SHCONTF.SHCONTF_INCLUDESUPERHIDDEN)?.FirstOrDefault(i => i.DisplayName.EqualsIgnoreCase(displayName));
    }
 
    /// Gets an item using its identifier.
    public virtual ShellItem GetItem(ShellItemId id)
    {
        ... pseudo code
        return EnumItems(SHCONTF.SHCONTF_FOLDERS |
            SHCONTF.SHCONTF_NONFOLDERS |
            SHCONTF.SHCONTF_FLATLIST | // all items
            SHCONTF.SHCONTF_INCLUDEHIDDEN |
        
        SHCONTF.SHCONTF_INCLUDESUPERHIDDEN)?.FirstOrDefault(i => i != null && i.Id != null && i.Id.EqualsOrSameBeginning(id));
    }

This scenario is obviously not optimal, Therefore, if retrieval of a single item is supported, it is strongly recommended that you override both of these methods for better performance.

Conditional Enumeration UI

If you need to show a window (like a WPF or Winforms window) from your Namespace Extension, you cannot use CBFS Shell implicit threads (threads are implicitly created by RPC incoming calls from the Shell) because these threads are not STA (Single Threaded Apartment) threads, which is a common requirement for UI-bound objects.

Thus, you can create your own STA threads or use CBFS Shell utilities. For example, the following code is used to show a WPF window before enumerating items:

public override IEnumerable<ShellItem> EnumItems(SHCONTF options)
{
    // run code on an STA thread
    var ret = callback.ShellBoost.Core.Utilities.TaskUtilities.StartSTAThreadTask(() =>
    {
        var win = new MyWpfWindow(); // create the WPF window
        return win.ShowDialog(); // show it as a modal dialog
    }).Result; // => the result of ShowDialog
    ...
}

Note: In this case, the window is modal, so the requesting Shell object (e.g., an Explorer view) will wait until the window is dismissed. In the case of an Explorer view, it usually will show the green progress line:


Copyright (c) 2022 Callback Technologies, Inc. - All rights reserved.
CBFS Shell 2022 .NET Edition - Version 22.0 [Build 8367]