Click here to Skip to main content
15,915,324 members
Articles / Web Development / HTML

CShellTreeCtrl

Rate me:
Please Sign up or sign in to vote.
4.87/5 (47 votes)
18 Dec 2001 885.3K   11.1K   126   255
A CWaitingTreeCtrl-derived class to display Shell's resources

Image 1

CShellTreeCtrl

This is just an example of a content provider class (see article), which overrides the PopulateItem virtual function to show the Shell's resources only when the user wants to access them.

You may easily specify the resource to use as the tree control's root item, or add multiple items at the root level. You have options to display only folders, files, hidden objects, and you can choose how to display the items text. You may also get specific information about the resource associated with an existing item.

User interface features are those offered by the base class and can be further personalized with custom animations.

This version is still under development, in particular, there's no support for filtering (I accept ideas).

Demo Application

The demo project shows how to:

  • use the control in a SDI application
  • add root items to the control
  • set item's options
  • display a Shell context menu

You may use the "Test" menu to experiment with the selected item, or see the Shell context menu in the "Shell" menu. Another way to display the Shell context menu is by right-clicking on a tree item (hold on CTRL to see a cascaded popup menu).

Class Reference

CShellTreeCtrl (Still Subject to Change)

CShellTreeCtrl::AddRootItem

C++
void AddRootItem(LPCITEMIDLIST pidl, UINT nFlags = STCF_DEFAULT)

Adds the specified Shell object to the root level of the tree and sets options for the inserted item.

The first argument pidl is the object you want to add, cannot be NULL. You may use SHGetSpecialFolderLocation to get a valid argument for this function.

The nFlags argument specifies the options to apply to the inserted item and can be one or more of the following values, combined with the bitwise or operator:

STCF_DEFAULT Child items can be only folders and their names refers to the parent item (like Explorer)
STCF_INCLUDEFILES Child items can be also non-folder objects
STCF_INCLUDEHIDDEN Child items can be also hidden objects (like system files)
STCF_INCLUDEALL (STCF_INCLUDEFILES|STCF_INCLUDEHIDDEN)
STCF_SHOWFULLNAME Item's name does not refer to any other folder (like shared directories in the Network Neighbourhood folder)
STCF_SHOWPATH Item's name is a relative path
STCF_SHOWFULLPATH Item's name is an absolute path

(STCF_SHOWPATH|STCF_SHOWFULLNAME)

CShellTreeCtrl::AddRootFolderContent

C++
void AddRootFolderContent(LPCITEMIDLIST pidl, UINT nFlags = STCF_DEFAULT)

Adds the content of the specified Shell folder object to the root level of the tree and sets options for the inserted items.

The first argument pidl is the folder object you want to enumerate. A value of NULL means that the Desktop virtual folder will be added (not its content). You may use SHGetSpecialFolderLocation to get a valid argument for this function.

The nFlags argument specifies the options to apply to the folder object during enumeration (see the previous function). STCF_SHOWxxx flags currently have no effect.

CShellTreeCtrl::GetItemIDList

C++
CShellPidl GetItemIDList(HTREEITEM hItem)

It retrieves the Shell object associated to the specified item. The returned object is invalid if the function fails.

You may use the Shell's functions to get information about the returned value. See SHGetPathFromIDList, SHGetFileInfo documentation.

CShellTreeCtrl::GetItemContextMenu

C++
BOOL GetItemContextMenu(HTREEITEM hItem, CShellContextMenu &rCtxMenu)

It retrieves the Shell context menu associated to the specified item. The return value is non-zero if the function is successful.

(to do)

CShellTreeCtrl::GetCallbackMask

C++
UINT GetCallbackMask()

It retrieves which parts of a tree view item are handled by callback messages.

(see the next function)

CShellTreeCtrl::SetCallbackMask

C++
void SetCallbackMask(UINT nMask)

It specifies which parts of a tree view item are handled by callback messages.

The nMask argument can be one or more of the following values, combined with the bitwise or operator:

TVIF_TEXT The control provides item text each time it's needed
TVIF_IMAGE Same for the image
TVIF_SELECTEDIMAGE Same for the selected image
TVIF_CHILDREN Same for the item's button

Updates

  • 17th October, 2000
    • Initial public release
  • 7th February, 2000
    • Fixed a bug with SHGetFileInfo on some machines, now using IShellFolder::GetAttributesOf (thanks to He Yingxia and Markus Axelsson)
    • Now correctly sort items after insertion
  • 23rd November, 2001
    • New version of the control (beta)
    • Added wrapper classes for shell objects and interfaces
    • Added support for context menu

Conclusion

Please note that this class is not fully functional yet. Any suggestion on how to improve it would be greatly appreciated.

I developed this class also to provide an example of a content provider for my CWaitingTreeCtrl class (see article).

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.


Written By
Technical Lead RoboTech srl
Italy Italy
Paolo began programming at the age of 9 with a glorious Olivetti M24 (i8086) and GW-BASIC, then he played a bit with Turbo C, Turbo Pascal and Assembly (using the MS-DOS Debug). Quick BASIC and Visual Basic shortly followed, until he learned C++ in College. He tought himself MFC and Windows programming, along with some DHTML and Javascript.

Always attracted by low-level programming and Assembly, he started to appreciate the joys of templates and STL while working for his Master Thesis. For seven months he was playing with airplanes and automatic control at the Unversity of Illinois at Urbana-Champaign, where he first met QNX and embedded systems.

In his job experience he learned Java to develop user interfaces and graphical editors, and re-discovered the Eclipse IDE that he had used in its early versions with the QNX SDK. He also deepened his knowledge of Linux and embedded systems, microcontrollers firmware and embedded voice recognition, while also practicing electronics design.

He graduated in Computer Engineering (Ingegneria informatica) at the University of Pisa, Italy, in December 2003. Currently working for an electronics and robotics company (www.robotechsrl.com).

He lives in Pisa and in Follonica (GR), Italy.

Comments and Discussions

 
GeneralRe: History URL Pin
Paolo Messina8-Mar-02 4:38
professionalPaolo Messina8-Mar-02 4:38 
GeneralA little improvement Pin
Werner Tremmel5-Mar-02 8:19
Werner Tremmel5-Mar-02 8:19 
GeneralRe: A little improvement Pin
Paolo Messina8-Mar-02 3:40
professionalPaolo Messina8-Mar-02 3:40 
QuestionHow to get an item's full pathname? Pin
zoomac2-Feb-02 18:24
zoomac2-Feb-02 18:24 
AnswerRe: How to get an item's full pathname? Pin
Paolo Messina3-Feb-02 11:54
professionalPaolo Messina3-Feb-02 11:54 
GeneralMaestro Pin
Simone Giannecchini20-Dec-01 12:31
Simone Giannecchini20-Dec-01 12:31 
GeneralRe: Maestro Pin
Paolo Messina21-Dec-01 23:38
professionalPaolo Messina21-Dec-01 23:38 
GeneralSetting a directory as selected (answer) Pin
mynab9-Dec-01 10:47
mynab9-Dec-01 10:47 
Hey,

this is some code I grabbed from another tree control and ported to this one. It only works in 'My Computer' (did not try it in 'Network Neighborhood'). Also it works very well in Debug it sometimes fails in Release. Can't figure out why yet...

Add the following headers in CShellTreeCtrl:

BOOL IsValidPath(LPCTSTR strPath);
CString GetItemPath(HTREEITEM hItem);
BOOL SetSelPath(LPCTSTR strPath);
HTREEITEM SearchSiblingItem( HTREEITEM hItem, LPCTSTR strText);

And Here is the implementation

CString CShellTreeCtrl::GetItemPath(HTREEITEM hItem)
{
TCHAR path[MAX_PATH];
SHGetPathFromIDList((LPCITEMIDLIST)GetItemData(hItem), path);
return CString(path);
}

BOOL CShellTreeCtrl::IsValidPath(LPCTSTR strPath)
{
// This function check the Pathname

HTREEITEM hChild;
CString strItem;
CString strTempPath = strPath;
BOOL bFound = FALSE;
CFileFind find;

strTempPath.MakeUpper();
strTempPath.TrimRight('\\');

hChild = GetChildItem( TVI_ROOT );
Expand(hChild, TVE_EXPAND);
hChild = GetChildItem(hChild);

while ( hChild )
{
strItem = GetItemPath( hChild );
strItem.MakeUpper();
if ( strItem == strTempPath.Mid( 0, strItem.GetLength() ) )
{
bFound = TRUE;
break;
}
hChild = GetNextItem( hChild, TVGN_NEXT );
}

if ( !bFound )
return FALSE;

strTempPath += "\\nul";
if ( find.FindFile( strTempPath ) )
return TRUE;

return FALSE;
}

BOOL CShellTreeCtrl::SetSelPath(LPCTSTR strPath)
{
// Setting the Selection in the Tree
HTREEITEM hParent = TVI_ROOT;
int iLen = strlen(strPath) + 2;
char* pszPath = new char[iLen];
char* pPath = pszPath;
BOOL bRet = FALSE;

if ( !IsValidPath( strPath ) )
{
delete [] pszPath; // this must be added 29.03.99
return FALSE;
}

hParent = GetChildItem( TVI_ROOT );
Expand(hParent, TVE_EXPAND);

int iLen2 = strlen( pszPath );

for (WORD i = 0; i < iLen2; i++ )
{
// restore the search string...
strcpy( pszPath, strPath );
if ( pszPath[strlen(pszPath)-1] != '\\' )
strcat( pszPath, "\\" );

if ( pszPath[i] == '\\' )
{
SetRedraw( FALSE );

if (i==2)
pszPath[3] = '\0';
else
pszPath[i] = '\0';

hParent = SearchSiblingItem( hParent, pPath );
if ( !hParent ) // Not found!
break;
else
{
// Info:
// the notification OnItemExpanded
// will not called every time
// after the call Expand.
// You must call Expand with TVE_COLLAPSE | TVE_COLLAPSERESET
// to Reset the TVIS_EXPANDEDONCE Flag

UINT uState;
uState = GetItemState( hParent, TVIS_EXPANDEDONCE );
if ( uState )
{
Expand( hParent, TVE_EXPAND );
Expand( hParent, TVE_COLLAPSE | TVE_COLLAPSERESET );
InsertItem("", hParent ); // insert a blank child-item
Expand( hParent, TVE_EXPAND ); // now, expand send a notification
}
else
Expand( hParent, TVE_EXPAND );
}
}
}

delete [] pszPath;

if ( hParent ) // Ok the last subpath was found
{
SelectItem( hParent ); // select the last expanded item
bRet = TRUE;
}
else
{
bRet = FALSE;
}

SetRedraw( TRUE );

return bRet;
}

HTREEITEM CShellTreeCtrl::SearchSiblingItem( HTREEITEM hItem, LPCTSTR strText)
{
HTREEITEM hFound = GetChildItem( hItem );
CString strTemp;
while ( hFound )
{
strTemp = GetItemPath( hFound );
if ( strTemp.Compare(strText) == 0 || strTemp.CompareNoCase(strText) == 0 )
return hFound;
hFound = GetNextItem( hFound, TVGN_NEXT );
}

return NULL;
}

Regards,
Nicolas
GeneralRe: Setting a directory as selected (answer) Pin
Paolo Messina23-Dec-01 0:04
professionalPaolo Messina23-Dec-01 0:04 
GeneralBut how to use this thing? Pin
14-May-02 21:36
suss14-May-02 21:36 
QuestionHow can i get the icon for each treecontrol item ? Pin
5-Dec-01 23:48
suss5-Dec-01 23:48 
AnswerRe: How can i get the icon for each treecontrol item ? Pin
Paolo Messina23-Dec-01 0:10
professionalPaolo Messina23-Dec-01 0:10 
AnswerSalutari de la Baia Mare !!! Pin
22-Apr-02 1:51
suss22-Apr-02 1:51 
GeneralRe: Salutari de la Cluj !!! Pin
27-Apr-02 4:14
suss27-Apr-02 4:14 
GeneralRe: Salutari de la Cluj !!! Pin
Anonymous30-Mar-04 23:19
Anonymous30-Mar-04 23:19 
GeneralRe: Salutari de la Cluj !!! Pin
Anonymous2-Jul-04 14:29
Anonymous2-Jul-04 14:29 
GeneralLiviu Guta Pin
Anonymous3-Jul-04 23:05
Anonymous3-Jul-04 23:05 
GeneralRe: Salutari de la Cluj !!! Pin
Anonymous2-Jul-04 14:30
Anonymous2-Jul-04 14:30 
GeneralRe: Salutari de la Cluj !!! Pin
Anonymous3-Jul-04 23:02
Anonymous3-Jul-04 23:02 
GeneralBrowse network only Pin
25-Nov-01 20:41
suss25-Nov-01 20:41 
GeneralRe: Browse network only Pin
Paolo Messina30-Nov-01 11:16
professionalPaolo Messina30-Nov-01 11:16 
QuestionHow to navigate History under w2k? Pin
Ralfy5-Nov-01 22:28
Ralfy5-Nov-01 22:28 
AnswerRe: How to navigate History under w2k? Pin
Paolo Messina6-Nov-01 2:04
professionalPaolo Messina6-Nov-01 2:04 
GeneralLast used folder lock Pin
Andrew Medvedev24-Oct-01 22:21
Andrew Medvedev24-Oct-01 22:21 
GeneralRe: Last used folder lock Pin
Andrew Medvedev24-Oct-01 23:28
Andrew Medvedev24-Oct-01 23:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.