viksoe.dk

Namespace Tree control

Namespace Tree control


This article was submitted .


This is a description of a control from another project I recently completed. This is the Windows Vista Namespace Tree Control. It shows the Shell Namespace hierarchy in a tree control. It is quite similar to a control I wrote some years ago, but now the Windows Shell team released a component that is part of the Windows distribution.

While you don't actually need the WTL library to use the new Vista control, I decided that it would be easier to deal with if it acted like the regular TreeView control. The Vista control is COM based so using it through the native interfaces is a bit of a departure from regular windows messaging. Wrapping the control to send regular TVN_ITEMSELECTED, etc. messages helps a bit if you just need the most basic functionality it offers.

To create the control, add a member variable to the window or dialog:

CNamespaceTreeControl m_ctrlTree;
And then in during window creation, initialize it:
m_ctrlTree.Create(m_hWnd, IDC_SHELLTREE)
...
m_ctrlTree.AddDesktopToRoot();
The Create() method can optionally take a few flags to configure how the control should appear, not unlike the regular TVS_XXX style flags.
The above sample code adds the Desktop to the tree as a root item. You can add several roots to the tree through some of the helper methods the wrapper exposes. You can also specify if each root should just display its folders, or even display non-folder items, such as files.

When your window is destroyed, you must manually call the Destroy() method to tear down the tree control link. This is important and somewhat different from the usual common controls.

m_ctrlTree.Destroy();

Once the tree is initialized with items, you will start receiving window notify messages in the form of WM_NOTIFY messages. The wrapper emulates some of the most important TreeView message:

BEGIN_MSG_MAP(CView)
   NOTIFY_HANDLER(IDC_SHELLTREE, TVN_SELCHANGED, OnSelChanged);
END_MSG_MAP()

LRESULT OnSelChanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
{
   LPNMNAMESPACETREE pnst = (LPNMNAMESPACETREE) pnmh;
   ...
   return 0;
}
However unlike the regular tree and list controls, the Namespace Tree control refers to its items via a IShellItem COM object. The Shell item object is a wrapper for the old PIDL structure way of accessing the available items. My old sample needed these PIDL structures (or LPCITEMIDLIST pointers) to refer to the shell hierarchy, but it always seemed a little odd for non-savvy Shell programmers that when you needed to query a file for some attributes you would have to talk to it through its folder. The Shell item object offers a neat COM wrapper to the same underlying structures.

To get from a filename to a Shell item and back, you can use the following access functions in Windows Vista.

CComPtr<IShellItem> spItem;
::SHCreateItemFromParsingName(pwszFilename, NULL, 
  IID_PPV_ARGS(&spItem));

CComHeapPtr<WCHAR> strFilename;
spItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING,
  &strFilename);
The strFilename variable now contains a pointer to a wide-string filename. It is automatically freed using the OLE allocator.
It may seem a little convoluted at first, but keeping things IShellItem in your code for as long as possible can be a great help rather than instantly converting them to paths. Remember that not all Shell items are file-system objects, some are virtual objects and they may not translate to an actual physical file-system path.

Interface

 NameDescription
CreateCreate the tree control window.
DestroyDestroys the tree control window.
AddDesktopToRootAdds the Desktop as a root item.
AddKnownFolderToRootAdds a known folder as a root item.
AddItemToRootAdds a shell item as a root item.
DeleteAllItemsRemoves all root items.
GetSelectedItemsGets the currently selected items.
SelectItemSelects an item.
GetItemStateGets the state of an item.
SetItemStateSets the state of an item.
SetThemeSets the Window theme.
CollapseAllCollapses all branches in the tree.
MoveWindowSets the tree control window position.
GetPtrRetrieves the COM INameSpaceTreeControl pointer.

Source Code Dependencies

Windows Vista
Microsoft Visual Studio.NET 2008
Microsoft WTL 7.5 Library
Microsoft ATL Library

See Also

Project where control is used
My Shell controls for pre-Vista

Download Files

DownloadSource Code (4 Kb)

To the top