M-Files UI Extensibility Framework
Using ShellUI Module
M-Files UI Extensibility Framework > Technical Articles > Using ShellUI Module

Shell Object Lifetimes

The main object of ShellUI module, the ShellUI object, lives as long as the shell window or any of its descent window lives. The lifetime of the shell window begins when the user navigates or opens a window with Windows Explorer, and points the window to the document vault on M-Files drive. The ShellUI is preserved as long as the window is used to point a folder on M-Files drive. The user may open a descend window to the document vault, like history or relationships window, so that these windows share the same ShellUI object. The ShellUI object gets decommissioned when the user navigates out from the document vault, or closes all windows.

If the user has two parallel and independent Windows Explorer windows, both windows have their own ShellUI. Only descend windows share the ShellUI object.

The ShellFrame object represents the inner area of the Windows Explorer window. The ShellFrame is actually a container object for shell panes (tasks pane, search pane, side panes), the shell listing, and for shell commands. The ShellFrame object is not preserved when navigating between folders (views), but is re-created every time the folder changes. Therefore the application module must trace the ShellFrame object creations and destructions constantly, and re-apply the modifications done for ShellFrame every time it changes.

Respectively, a new ShellFrame object appears when a new embedded shell frame is created. For example, the relationships window contains three tabs, each containing individual listing content view. Therefore three ShellFrame objects are created when the relationships window is opened.

ShellFrame Types and Characteristics

The creation of a new ShellFrame window is notified with Event_NewShellframe event (OnNewShellFrame). However the new ShellFrame object may appear in various situations, and the application may be interested to customize only certain instances of shell frame objects.

There are other events that can be used to react only to certain types of shell frame objects. The table below lists all events that are sent with different shell frame contexts.

Event

Triggered for

Event_NewShellFrame

(OnNewShellFrame)

Any shell frame

Event_NewNormalShellFrame

(OnNewNormalShellFrame)

Normal shell frames, i.e. no shell frames in common dialogs, no embedded shell frames

Event_NewCommonDialogShellFrame

(OnNewCommonDialogShellFrame)

Shell frames in common dialogs only

Event_NewEmbeddedShellFrame

(OnNewEmbeddedShellFrame)

Embedded shell frames only (e.g. history window, relationships window,subobjects window, clear local cache window, etc.)

 

Certain ShellFrame types cannot host search pane or tasks pane. The side pane availability can be verified with ITaskPane::Available and ISearchPane::Available properties.

Limiting the Shell Commands Availability

Application that uses the ShellUI module can change the state of M-Files built-in commands. The built-in commands can be seen in Windows Explorer menus, in context menu, and on tasks pane. The application can disable or hide the command label in some or all command locations. If the command is hidden entirely from all locations, it is excluded out and its keyboard shortcut behavior is blocked, too.

The application can only decrease the command availability, i.e. active commands can be disabled (grayed) or hidden, and inactive commands can be only hidden. Disabled commands cannot be made active.

Command states are accessed via ICommands interface of ShellFrame object. Note that because the commands are specific for shell frame, their states need to be re-set each time the shell frame changes. The code below entirely hides the checkout command from right-button menu.

{

    // Here the shellFrame refers to IShellFrame object.

    // Hide the checkout command from context menu.

    shellFrame.Commands.SetCommandState(

        BuiltinCommand_CheckOut, CommandLocation_ContextMenu, CommandState_Hidden );

}

 

Displaying Own Commands

The ShellUI module can add own commands (custom commands) to show in M-Files user interface. Commands can be added to context menu (right-button menu), and to task pane. The command location in context menu can be chosen from pre-set placeholders. On tasks pane the command can be added to either one of the built-in groups, or to new group.

The code below adds a custom command, and appends it to context menu and task pane.

{

    // Here the shellFrame refers to IShellFrame object.

    // Create new command.

    var commandId = shellFrame.Commands.CreateCustomCommand( "Custom Command" );

 

    // Append the command to context menu.

    shellFrame.Commands.AddCustomCommandToMenu(

        commandId, MenuLocation_ContextMenu_Bottom, 0 );

 

    // Append the command to built-in task pane group.

    shellFrame.TaskPane.AddCustomCommandToGroup( commandId, TaskPaneGroup_GoTo, 0 );

}

 

The custom command state can be altered in similar manner with built-in commands, using ICommands::SetCommandState method. The custom command activation can be handled by implementing an event handler for custom commands, as implemented in code below.

{

    // Here the shellFrame refers to IShellFrame object.

    // Add custom command handler.

    shellFrame.Commands.Events.OnCustomCommand = function( activatedCommandId ) {

        if( activatedCommandId == commandId )

        {

            // Handle custom command

        }

    }

}

 

Listing Content and Selection

ShellUI module can access the listing content and the current selection in the listing view. It doesn’t matter if the listing is actually visible or replaced with a dashboard or report, the listing still exists under the graphics.

Listing-related actions like reading the content and selecting an item can be performed with methods in IShellListing interface. For example, the code below loops through all selected objects.

{

    // Here the shellFrame variable refers to IShellFrame object.

    // Loop all selected objects.

    var selectedItems = shellFrame.ActiveListing.CurrentSelection;

    for( var i = 1; i <= selectedItems.ObjectVersions.Count; ++i )

    {

           var objectversion = selectedItems.ObjectVersions.Item( i );

        /// ...

    }

}

 

If the application is interested about the shell listing content, it may wish to handle Event_ContentChanged events. This event occurs every time when there is a change in the listing content. E.g. a new items appear, old items get removed, a node expands or collapses, or existing item data changes. The event is not sent synchronously but after a timer interval, in order to avoid too many event notifications.

If the application is interested about selected item, it should track the listing selection. There are two selection-related events:

-          Event_SelectionChanged is sent when a listing item gets selected, or selected item is unselected. Event_SelectedItemsChanged is sent when a selected item data changes (properties are changed etc.).

These events are not sent synchronously but after a timer interval, in order to avoid too many event notifications.

Shell Navigation

ShellUI module can request the shell to navigate to another folder. See IShellFrame::NavigateToParent method and IShellFrame::CurrentPath property.

The application can also navigate to a view by selecting and activating a view item in the listing. See IShellListing ::ActivateSelected.