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
Name | Description | |
---|---|---|
![]() | Create | Create the tree control window. |
![]() | Destroy | Destroys the tree control window. |
![]() | AddDesktopToRoot | Adds the Desktop as a root item. |
![]() | AddKnownFolderToRoot | Adds a known folder as a root item. |
![]() | AddItemToRoot | Adds a shell item as a root item. |
![]() | DeleteAllItems | Removes all root items. |
![]() | GetSelectedItems | Gets the currently selected items. |
![]() | SelectItem | Selects an item. |
![]() | GetItemState | Gets the state of an item. |
![]() | SetItemState | Sets the state of an item. |
![]() | SetTheme | Sets the Window theme. |
![]() | CollapseAll | Collapses all branches in the tree. |
![]() | MoveWindow | Sets the tree control window position. |
![]() | GetPtr | Retrieves the COM INameSpaceTreeControl pointer. |
Source Code Dependencies
Windows VistaMicrosoft Visual Studio.NET 2008
Microsoft WTL 7.5 Library
Microsoft ATL Library
See Also
Project where control is usedMy Shell controls for pre-Vista
Download Files
![]() | Source Code (4 Kb) |