Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Navigation items in the WMC are identified by Navigation Paths. These case-insensitive paths describe the hierarchy of how the item is arranged with respect to other nodesitems in relation to other items of the same type. The root node of the Navigation Path (called the domain) indicates the type of navigation item.

NodeDomainDescription
NAVIGATIONTREEA Navigation Path that identifies an item in the navigation tree
HELPA Navigation Path that identifies a help pane itemcontent
TASKLISTA Navigation Path that identifies an a group or item in the task list that sits below the navigation tree in the WMC.
MESSAGEBARA Navigation Path that identifies an item in the navigation bar at the top of the WMC

e.g. Examples:

NAVIGATIONTREE\ControlPanel\Events refers to the Events item in the navigation tree that sits under the Control Panel node in the navigation tree. item.

TASKLIST\Data\ResetValue refers to the task ResetValue that lies under the Data task group.

HELP\NAVIGATIONTREE\ControlPanel\Events refers to a help item that is automatically associated with the navigation tree item ControlPanel\Events

 

NavInsertItem takes a Navigation Path and uses it to create an item for at that pathlocation. The 4 separate types of navigation items have their own hierarchy and you cannot put one type into another hierarchy. The paths can be any path that you define (Apart from the root item) and have little bearing on each other apart from help items and navigation tree items which are discussed below.

Navigation Tree Items and Help

NAVIGATIONTREE and HELP items share a special relationship in the WMC. When a user navigates to an item in the navigation tree, the HELP item with that has a sub path that is the same as the Navigation Path of the item is queried and the resulting content is used to populate the help pane. Therefore, to get help working for your component you should register a HELP such that it has a Navigation Path that is the same as the one used for the NAVIGATIONTREE item. e.g.

Complete Navigation Path of navigation tree item: NAVIGATIONTREE\ControlPanel\MyComponent

Complete Navigation Path of help item: HELP\NAVIGATIONTREE\ControlPanel\MyComponent

In order to ensure the paths match, you can get the navigation path for the tree item with NavGetItem and use the strFQN field as the path passed to NavInsertItem for the help item. The following example inserts an item under the Control Panel item in the tree and associates dynamic help with it.

Code Block
static NavigationItemUIInterface notificationInterface;
 
void SetupNotificationInterface()
{
    // Set up our notification interface so we can receive messages relating to the the navigation item we will insert into the tree
    memset(&gDataUI,0,sizeof(NavigationItemUIInterface));
    notificationInterface.dwSize                    = sizeof(NavigationItemUIInterface);
    notificationInterface.NavItemCreateWindow       = NavItemCreateWindow;                      // Called when the framework wants a window from us
    notificationInterface.NavItemDrawItem           = NULL;
    notificationInterface.NavItemNotify             = NavItemNotify;                            // For receiving general messages
    notificationInterface.NavItemGetHelpContent     = NavItemGetHelpContent;                    // For dynamic help content in the help pane of the UI
    notificationInterface.NavItemFreeHelpContent    = NavItemFreeHelpContent;
    notificationInterface.NavItemShowContextHelp    = NavItemShowContextHelp;                   // For F1 help
    notificationInterface.NavItemKeyboardNavigate   = NavItemKeyboardNavigate;                  // To handle custom keyboard navigation within our panel. (optional)
}
 
// Called below
NavHandle CreateTreeItem()
{ 
 
    // Get the correct location to insert our new item under. In this case it will be the "Control Panel" node. This has a well known alias that we can use.
 
    NAVSETITEM controlPanelItem;
    if ( !NavGetItem(_T("{ControlPanel}"), &controlPanelItem) )
    {
        return NULL;                                        // Couldn't find it, so we won't go any further
    }
 
    NAVSETITEM treeItem;
    memset(&treeItem, 0, treeItem);
    treeItem.size = sizeof(NAVSETITEM);
    treeItem.flags = NI_FLAG_CUSTOMCONTAINER;               // This is a custom container where we control the panel.
    treeItem.lParam = NULL;                                 // Set any special context data that you want to be sent with messages to the notificationInterface
    treeItem.strLabel = L"Ad Blocker";
    treeItem.strDescription = L"This component adds an HTTP Filter that blocks advertising";
    treeItem.hModule = AfxGetResourceHandle();              // Where to get resources from
    treeItem.nIconId = iconResourceId;                      // Some resource id of the icon to display in the navigation tree
    treeItem.EventMask = 0;                                 // No special events. NI_EVENT_ACTIVATE, NI_EVENT_DEACTIVATE are always sent. See NavInsertItem for more information
    treeItem.pInterface = notificationInterface;            // The interface we are wanting to use to handle events from this item
    treeItem.strAlias = L"{MyCompanyAdBlocker}";          // Adds an alias. Makes it easier to find and compare navigation items later.
    if ( !NavInsertItem(controlPanelItem.hItem, L"MyCompanyAdBlockerPath", &treeItem) )   // The path "MyCompanyAdBlockerPath" is an internal name the user never sees but must be unique under a particular root.
    {
        return NULL;
    }
    return treeItem.hItem;
}
 
std::wstring GetFQNOfTreeItem(NavHandle treeItem)
{
	NAVSETITEM itemData;
	NavGetItemEx(treeItem, &itemData);
	return itemData.strFQN;
} 
 
NavHandle GetHelpRoot()
{
	NAVSETITEM item;
	if(NavGetItem(_T("HELP"), &item))
	{
		return item.hItem;
	}
	return 0;
} 
 
void SetUpNavigationItems()
{
	SetupNotificationInterface();
	NavHandle treeItem = CreateTreeItem();
	std::wstring treeItemFqn = GetFQNOfTreeItem(treeItem);
 
	NavHandle helpRoot = GetHelpRoot();
	
	NAVSETITEM helpItem;
	memset(&helpItem, 0, helpItem);
	helpItem.size = sizeof(NAVSETITEM);
	helpItem.strLabel = L"My help label";
	helpItem.strDescription = L"Help for my component";
	helpItem.flags = NI_FLAG_DYNAMICHELP;						// We want to be called dynamically.
	helpItem.EventMask = NI_EVENT_NOTIFY; 						// Need to set this so our callback for dynamic help is processed
	helpItem.pInterface = &notificationInterface;				// Interface to handle callbacks to ask for dynamic help
	NavInsertItem(helpRoot, treeItemFqn, helpItem);				// Insert the item as a child of HELP, with the same path as the tree item
}


 

Aliases

Navigation Paths can have aliases that are used to quickly reference a path without having to know the entire underlying path. NavInsertItem allows you to specify an alias when you add the item. It must consist of a '{' character followed by the (case sensitive) alias name and a '}'. e.g {ControlPanel} references the Control Panel node in the navigation tree whose real Navigation Path is NAVIGATIONTREE\ControlPanel

 

Help

HELP\NAVIGATIONTREE\Header - All Header items are put into header of help, regardless of location in tree

HELP\NAVIGATIONTREE\Main

domain with which an item lives is defined by the root of the path and levels in the hierarchy are specified by the path separator '\'. Paths can effectively be any depth you wish.

Aliases

Navigation Paths can have aliases. By using aliases the underlying navigation path can change and the framework will still be able to find it via its alias. NavInsertItem allows you to specify an alias when you add the item. Use the NavItemHelpers function MakeAliasForName to easily create an alias from a name.

If you have a component that needs to allow others to know about its navigation items (To place tree node under it for instance) then publish the alias not the full navigation path. So long as you don't rename the alias then you can move/rename the navigation path within the hierarchy and client code will continue to find your item via its alias.

Like Navigation Paths, aliases are case-insensitive.

 

Note

Qbik highly recommends that you use aliases to find parent items when inserting your own navigation items. This ensures that your items continue to operate correctly even when the underlying navigation paths change.

Note

Make sure your alias is unique. Qbik Well known aliases are undecorated but you should ensure your alias can be differentiated from someone elses. E.g. Don't call your alias File, but use something that uniquely identifies your alias such as MyCompanyScannerComponentFile, mycompany.scanner.file or a string UUID if you wish. MakeAliasFromName(L"703201E2-6ACF-463D-AA4B-038F99AD9414");