Click here to Skip to main content
15,881,588 members
Articles / Desktop Programming / MFC
Article

CTreeFileCtrl & CSortedArray v1.06

Rate me:
Please Sign up or sign in to vote.
4.97/5 (20 votes)
3 Mar 2000 296.7K   4.3K   70   78
Implements a tree control similar to the left hand side of Windows Explorer.
  • Download source files - 31 Kb
  • Introduction

    CTreeFileCtrl provides an MFC class which provides a tree control similar to the left hand side of Windows Explorer. Also provided is CSortedArray which is used internally by CTreeFileCtrl. This is a class derived from the MFC template class CArray. It provides for ordered insertion of items into an MFC CArray aswell as searching and sorting of its items. The compare function used to determine ordering in the array can be easily customised at run-time.

    Image 1


    Features
    History
    Usage
    API Reference
    To Do
    Contacting the Author


    Features

    • CTreeFileCtrl is derived from CTreeCtrl and can be created using the same mechanisms.
    • Uses the system image list for the icons for folders and files.
    • Can have multiple instances of the control active at one time
    • Optionally allows files to be displayed as well as folders.
    • Integrates with the shell to allow the file to be "opened" and its properties page to be displayed.
    • Provides for deletion and moving to the recycle bin. Message boxes used are the same as those provided in Windows Explorer.
    • Supports drag & drop and auto scrolling while dragging.
    • Standard MFC DDX functions are provided to easily integrate with dialog based apps.
    • Supports in place renaming of items.
    • Provides a full set of keyboard accelerators similar to Windows Explorer.
    • Unicode enabled and all code compiles cleanly at warning level 4.
    • CSortedArray is publically derived from CArray meaning than all the functionality of CArray is available in addition to its own functionality.
    • Instances which currently use CArray can be very easily changed to use CSortedArray by simply replacing the text "CArray" with "CSortedArray".
    • How items are sorted in CSortedArray can be easily changed at runtime via its SetCompareFunction method.


    History

    v1.0 (27 December 1999)
    • Initial public release.

    v1.01 (12 January 2000)

    • Added some asserts to HasGotSubEntries().
    • Fixed a problem with calling OnDblclk() when no tree item is selected.
    • Removed an unused variable from SetSelectedPath().
    • Fixed a stack overflow in CSortedArray::Sort().
    • Now supports check boxes with each item in the tree control.

    v1.02 (25 January 2000)

    • Minor update to the code in CTreeFileCtrl::OnDblclk() to only allow selected items to be opened.

    v1.03 (31 January 2000)

    • Fixed a problem when you right mouse click over a non - selected item. The control now implements the same behavior as Explorer for this.
    • Removed check for keyboard invocation of the context menu in OnContextMenu().
    • Now displays the context menu over the selected item when invoked via the keyboard. Again this is the same behavior as Explorer has.
    • Optimized the code in PreTranslateMessage().
    • Fixed a bug in CTreeFileCtrl::OnEndlabeledit().
    • Some of the menus in the sample app have been fixed.
    • Menu items have been added to the sample app to allow the SetAllow... functions to be tried out.

    v1.04 (21 February 2000)

    • Fixed a number of problems in CSortedArray::Find().

    v1.05 (22 February 2000)

    • Fixed a problem in CSortedArray::Find() when there are no items in the array.

    v1.06 (29 February 2000)

    • Fixed a problem in CSortedArray::Sort() when there are no items in the array.


    Usage

    • To use CSortedArray in your code simply #include "SortedArray.h" in your project and include it in which ever modules you want to instantiate it in.
    • To use CTreeFileCtrl, include FileTreeCtrl.cpp / .h in your project (in addition to SortedArray.h) and #include "FileTreeCtrl.h" in the module you want to instantiate it in. You can use the usual MFC ways of hooking up the class. If you are using the class in a dialog resource, then you can use the DDX function provided or call the CWnd::SubclassWindow() function directly. You can also create the control dynamically by calling its parent classes CTreeCtrl::Create() method.


    API Reference

    The following functions are provided:

    CSortedArray::CSortedArray
    CSortedArray::OrderedInsert
    CSortedArray::Sort
    CSortedArray::Find
    CSortedArray::SetCompareFunction
    CSortedArray::GetCompareFunction

    CTreeFileCtrl::CTreeFileCtrl
    CTreeFileCtrl::SetRootFolder
    CTreeFileCtrl::GetRootFolder
    CTreeFileCtrl::ItemToPath
    CTreeFileCtrl::GetSelectedPath
    CTreeFileCtrl::SetSelectedPath
    CTreeFileCtrl::SetShowFiles
    CTreeFileCtrl::GetShowFiles
    CTreeFileCtrl::SetAllowDragDrop
    CTreeFileCtrl::GetAllowDragDrop
    CTreeFileCtrl::SetAllowRename
    CTreeFileCtrl::GetAllowRename
    CTreeFileCtrl::SetAllowOpen
    CTreeFileCtrl::GetAllowOpen
    CTreeFileCtrl::SetAllowProperties
    CTreeFileCtrl::GetAllowProperties
    CTreeFileCtrl::SetAllowDelete
    CTreeFileCtrl::GetAllowDelete
    CTreeFileCtrl::IsFile
    CTreeFileCtrl::IsFolder
    CTreeFileCtrl::IsDrive
    CTreeFileCtrl::Rename
    CTreeFileCtrl::ShowProperties
    CTreeFileCtrl::Delete
    CTreeFileCtrl::Open
    CTreeFileCtrl::SetFlags

    DDX_FileTreeControl
    DDX_FileTreeValue


    CSortedArray::CSortedArray

    CSortedArray();

    Remarks:
    Constructs an empty array. Internally this just sets compare function pointer to NULL to ensure that you call SetCompareFunction() prior to calling any methods of CSortedArray.


    CSortedArray::OrderedInsert

    int OrderedInsert(ARG_TYPE newElement, int nCount = 1);

    Return Value:
    The index where the item has been inserted.

    Parameters:

    • newElement -- The item to add to the array. Its type is determined when the class is instantiated as with the parent class CArray.
    • nCount -- The number of times this element should be inserted (defaults to 1).

    Remarks:
    Inserts the element into the array. The code internally uses a binary search to determine where the item should be inserted. This assumes that the elements in the array are already ordered. If they are not then you should call the Sort method first. Because the class is publically derived from CArray, you can call all of CArray's methods in addition to the methods implemented in CSortedArray.


    CSortedArray::Sort

    void Sort(int nLowIndex = 0, int nHighIndex = -1);

    Return Value:
    The index where the item has been inserted.

    Parameters:

    • nLowIndex -- The index of the first element in the array to sort.
    • nHighIndex -- The index of the last element in the array to sort. The default value of -1 represents the last element in the array.

    Remarks:
    Performs a sort of the specified elements in the array. Internally the code will use the "Quicksort" algorithm to do the sort.


    CSortedArray::Find

    int Find(ARG_TYPE element, int nLowIndex = 0, int nHighLowIndex = -1);

    Return Value:
    The index of the item if found otherwise -1 if not.

    Parameters:

    • element -- The item to search for in the array.
    • nLowIndex -- The index of the first element in the array to search.
    • nHighIndex -- The index of the last element in the array to search. The default value of -1 represents the last element in the array.

    Remarks:
    Searches for an item in the array. The code internally uses a binary search to determine if the element is present or not.


    CSortedArray::SetCompareFunction

    void SetCompareFunction(LPCOMPARE_FUNCTION lpfnCompareFunction);

    Parameters:

    • lpfnCompareFunction -- The new function to use for comparisons to determine the ordering of elements in the array.

    Remarks:
    This sets the function which is used internally for item comparisons. LPCOMPARE_FUNCTION is a pointer to a function as defined:

    typedef int COMPARE_FUNCTION(ARG_TYPE element1, ARG_TYPE element2);<br>
           typedef COMPARE_FUNCTION* LPCOMPARE_FUNCTION;


    CSortedArray::GetCompareFunction

    LPCOMPAREFUNCTION GetCompareFunction() const;

    Return Value:
    A pointer to the function which is currently used to determine the ordering of elements in the array.

    Remarks:
    This is the corollary function to the SetCompareFunction().


    CTreeFileCtrl::CTreeFileCtrl

    CTreeFileCtrl();

    Remarks:
    Constructs a CTreeFileCtrl object.


    CTreeFileCtrl::SetRootFolder

    void SetRootFolder(const CString& sPath);

    Parameters:

    • sPath -- The folder to use as the parent for all items in the tree control.

    Remarks:
    This allows you to set the parent folder to be something other than the default which displays all the drive letters at the root. For example this would allow you to produce a UI to allow you to specify a "Program Group" as would be required by an install program.


    CTreeFileCtrl::GetRootFolder

    CString GetRootFolder() const;

    Return Value: The current folder used as the parent for all items in the tree control.

    Remarks:
    This is the corollary function to the SetRootFolder().


    CTreeFileCtrl::ItemToPath

    CString ItemToPath(HTREEITEM hItem);

    Return Value:
    The folder / file path as represented by the tree item hItem.

    Parameters:

    • hItem -- The tree item to get the path for.

    Remarks:
    This function allows an tree item's file name or folder name to be retrieved given it's HTREEITEM. Internally this function is used in the GetSelectedPath() function.


    CTreeFileCtrl::GetSelectedPath

    CString GetSelectedPath();

    Return Value:
    The current folder / file path as selected in the tree control.

    Remarks:
    This function returns the file name or folder name currently selected in the tree control.


    CTreeFileCtrl::SetSelectedPath

    void SetSelectedPath(const CString& sPath, BOOL bExpanded = FALSE);

    Return Value:
    The folder / file path as represented by the tree item hItem.

    Parameters:

    • sPath -- The folder or file name path to select in the tree control.
    • bExpanded -- TRUE if the new item should be shown expanded otherwise FALSE.

    Remarks:
    This allows you to set the currently selected item in the tree control.


    CTreeFileCtrl::SetShowFiles

    void SetShowFiles(BOOL bFiles);

    Parameters:

    • bFiles -- TRUE if the tree control should display files in addition to folders.

    Remarks:
    This allows you to decide whether the tree control should display files.


    CTreeFileCtrl::GetShowFiles

    BOOL GetShowFiles() const;

    Return Value:
    TRUE if the tree control is displaying files otherwise FALSE.

    Remarks:
    This is the corollary function to the SetShowFiles().


    CTreeFileCtrl::SetAllowDragDrop

    void SetAllowDragDrop(BOOL bAllowDragDrop);

    Parameters:

    • bAllowDragDrop -- TRUE if the tree control should allow drag/drop of items otherwise FALSE.

    Remarks:
    This allows you to decide whether the tree control should allow drag/drop of items.


    CTreeFileCtrl::GetAllowDragDrop

    BOOL GetAllowDragDrop() const;

    Return Value:
    TRUE if the tree control is allowing drag/drop otherwise FALSE.

    Remarks:
    This is the corollary function to the SetAllowDragDrop().


    CTreeFileCtrl::SetAllowRename

    void SetAllowRename(BOOL bAllowRename);

    Parameters:

    • bAllowRename -- TRUE if the tree control should allow items to be renamed otherwise FALSE.

    Remarks:
    This allows you to decide whether the tree control should allow items to be renamed (via the F2 keyboard accelerator and in-place editing of items).


    CTreeFileCtrl::GetAllowRename

    BOOL GetAllowRename() const;

    Return Value:
    TRUE if the tree control is allowing items to be renamed otherwise FALSE.

    Remarks:
    This is the corollary function to the SetAllowRename().


    CTreeFileCtrl::SetAllowOpen

    void SetAllowOpen(BOOL bAllowOpen);

    Parameters:

    • bAllowOpen -- TRUE if the tree control should allow items to be "opened" via the shell.

    Remarks:
    This allows you to decide whether the tree control should allow items to be "opened" via the shell (via the Enter keyboard accelerator and double clicking of items).


    CTreeFileCtrl::GetAllowOpen

    BOOL GetAllowOpen() const;

    Return Value:
    TRUE if the tree control is allowing items to be opened via the shell otherwise FALSE.

    Remarks:
    This is the corollary function to the SetAllowOpen().


    CTreeFileCtrl::SetAllowProperties

    void SetAllowProperties(BOOL bAllowProperties);

    Parameters:

    • bAllowProperties -- TRUE if the tree control should allow an item's property dialog to be displayed.

    Remarks:
    This allows you to decide whether the tree control should allow property dialogs to be displayable (via the Alt-Enter keyboard accelerator).


    CTreeFileCtrl::GetAllowProperties

    BOOL GetAllowProperties() const;

    Return Value:
    TRUE if the tree control is allowing an item's property dialog to be displayable otherwise FALSE.

    Remarks:
    This is the corollary function to the SetAllowProperties().


    CTreeFileCtrl::SetAllowDelete

    void SetAllowDelete(BOOL bAllowDelete);

    Parameters:

    • bAllowDelete -- RUE if the tree control should allow items to be deleted.

    Remarks:
    This allows you to decide whether the tree control should allow items to be deleted (via the Delete keyboard accelerator).


    CTreeFileCtrl::GetAllowDelete

    BOOL GetAllowDelete() const;

    Return Value:
    TRUE if the tree control is allowing an items to be deleted otherwise FALSE.

    Remarks:
    This is the corollary function to the SetAllowDelete().


    CTreeFileCtrl::IsFile

    BOOL IsFile(HTREEITEM hItem);
    BOOL IsFile(const CString& sPath);

    Return Value:
    TRUE if the tree control item or path is a file otherwise FALSE.

    Parameters:

    • hItem -- The tree item to be determined if it is a file.
    • sPath -- The path of the object to be determined if it is a file.

    Remarks:
    Use these functions to determine if an item is a file.


    CTreeFileCtrl::IsFolder

    BOOL IsFolder(HTREEITEM hItem);
    BOOL IsFolder(const CString& sPath);

    Return Value:
    TRUE if the tree control item or path is a folder otherwise FALSE.

    Parameters:

    • hItem -- The tree item to be determined if it is a folder / directory.
    • sPath -- The path of the object to be determined if it is a folder / directory.

    Remarks:
    Use these functions to determine if an item is a folder / directory.


    CTreeFileCtrl::IsDrive

    BOOL IsDrive(HTREEITEM hItem);
    BOOL IsDrive(const CString& sPath);

    Return Value:
    TRUE if the tree control item or path is a drive letter otherwise FALSE.

    Parameters:

    • hItem -- The tree item to be determined if it is a drive letter.
    • sPath -- The path of the object to be determined if it is a drive letter.

    Remarks:
    Use these functions to determine if an item is a drive letter e.g. "A:\".


    CTreeFileCtrl::Rename

    BOOL Rename(HTREEITEM hItem);

    Return Value:
    TRUE if in-place editing of the specified item was started successfully otherwise FALSE.

    Parameters:

    • hItem -- The tree item to begin in-place editing of.

    Remarks:
    Use this function to start in-place editing i.e. renaming of the specified item. To edit a specific path use the function SetSelectedPath().


    CTreeFileCtrl::ShowProperties

    BOOL ShowProperties(HTREEITEM hItem);

    Return Value:
    TRUE if the shells property dialog of the specified item was shown successfully otherwise FALSE.

    Parameters:

    • hItem -- The tree item to show the properties dialog of.

    Remarks:
    Use this function to show the standard Windows properties dialog of an item. To show the properties of a specific path use the function SetSelectedPath().


    CTreeFileCtrl::Delete

    BOOL Delete(HTREEITEM hItem);

    Return Value:
    TRUE if the item was successfully deleted otherwise FALSE.

    Parameters:

    • hItem -- The tree item to delete.

    Remarks:
    Use this function to delete the specified item. To delete a specific path use the function SetSelectedPath(). Internally the function looks at the keyboard state to implement real deletion or moving of the item to the recycle bin. It will also use the standard confirmation dialogs provided by the shell when you delete something.


    CTreeFileCtrl::Open

    BOOL Open(HTREEITEM hItem);

    Return Value:
    TRUE if the item was successfully "opened" by the shell otherwise FALSE.

    Parameters:

    • hItem -- The tree item to "open".

    Remarks:
    Use this function to "open" the specified item. In the case of an executable, the program will be run, while in the case of a document file, the default verb as setup in the shell will be used. To execute a specific path use the function SetSelectedPath().


    CTreeFileCtrl::SetFlags

    void SetFlags(DWORD dwFlags);

    Parameters:

    • dwFlags -- The flags / styles to associate with the tree control.

    Remarks:
    Use this function as a shortcut way of calling the SetAllow...() functions. This function is used internally by the DDX_FileTreeControl() function. The flags that can be used as are as follows:

    TFC_SHOWFILES Control will show files aswell as show folders
    TFC_ALLOWDRAGDROP Control allows drag / drop
    TFC_ALLOWRENAME Control allows renaming of items
    TFC_ALLOWOPEN Control allows items to be "opened" by the shell
    TFC_ALLOWPROPERTIES Control allows the "Properties" dialog to be shown
    TFC_ALLOWDELETE Control allows items to be deleted

    These flags can be or'ed together when calling the function.


    DDX_FileTreeControl

    void DDX_FileTreeControl(CDataExchange* pDX, int nIDC, CTreeFileCtrl& ctrlFileTree, DWORD dwFlags);

    Parameters:

    • pDX -- The usual CDataExchange object which will be passed into your DoDataExchange function.
    • nIDC -- The dialog ID of the tree control to subclass.
    • ctrlFileTree -- Upon returnwill contain the CTreeFileCtrl control instance.
    • dwFlags -- A combination of bit values to customise the display of the control. See the function SetFlags() for all the allowable values.

    Remarks:
    Associates an existing tree control with dialog ID nIDC to a CTreeFileCtrl control instance. Normally you would call this function in your dialog class's DoDataExchange member function. Internally the function uses the dwFlags in a call to SetFlags.().


    DDX_FileTreeValue

    void DDX_FileTreeValue(CDataExchange* pDX, CTreeFileCtrl& ctrlFileTree, CString& sItem);

    Parameters:

    • pDX -- The usual CDataExchange object which will be passed into your DoDataExchange function.
    • ctrlFileTree -- The tree control to get or set the folder / file for.
    • sItem -- The actual folder / file to get or set into the control depending on the direction of data exchange occurring.

    Remarks:
    Allows the selected folder / file to be quickly set / retrieved in a CTreeFileCtrl instance using the normal MFC DDX mechanism.



    To Do

    • Any ideas, please let me know!


    Contacting the Author

    PJ Naughter
    Email: pjn@indigo.ie
    Web: http://www.naughter.com
    29 February 2000


    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
    United States United States
    This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

    Comments and Discussions

     
    GeneralRe: Auto refresh bug Pin
    pjnaughter28-Jan-03 12:17
    pjnaughter28-Jan-03 12:17 
    GeneralSelect Multiple files Pin
    9-Aug-01 3:01
    suss9-Aug-01 3:01 
    GeneralRe: Select Multiple files Pin
    3-Dec-01 2:26
    suss3-Dec-01 2:26 
    GeneralBUG with Windows 98 Pin
    4-Jul-01 0:28
    suss4-Jul-01 0:28 
    GeneralMFC RunTime Module Pin
    31-May-01 7:46
    suss31-May-01 7:46 
    GeneralRe: MFC RunTime Module Pin
    19-Jul-01 9:12
    suss19-Jul-01 9:12 
    GeneralRe: MFC RunTime Module Pin
    7-Sep-01 7:26
    suss7-Sep-01 7:26 
    GeneralRe: MFC RunTime Module Pin
    8-Mar-02 6:11
    suss8-Mar-02 6:11 
    GeneralRe: MFC RunTime Module Pin
    Lakitu28-Mar-02 4:14
    Lakitu28-Mar-02 4:14 
    GeneralRe: MFC RunTime Module Pin
    pjnaughter28-Jan-03 12:19
    pjnaughter28-Jan-03 12:19 
    GeneralBUGS: GetIconIndex && GetSelIconIndex Pin
    18-May-01 0:18
    suss18-May-01 0:18 
    GeneralRe: BUGS: GetIconIndex && GetSelIconIndex Pin
    pjnaughter28-Jan-03 12:21
    pjnaughter28-Jan-03 12:21 
    GeneralRe: BUGS: GetIconIndex &amp;&amp; GetSelIconIndex Pin
    pjnaughter3-Aug-03 2:47
    pjnaughter3-Aug-03 2:47 
    GeneralError Log Viewer Pin
    raghu15-May-01 0:21
    raghu15-May-01 0:21 
    GeneralLooks like a great Class. Thanks! Pin
    6-Feb-01 6:06
    suss6-Feb-01 6:06 
    Generalproblem if more than 3000 files in the folder Pin
    30-Dec-00 5:04
    suss30-Dec-00 5:04 
    GeneralThank you!!! Pin
    29-Nov-00 6:24
    suss29-Nov-00 6:24 
    GeneralRe:Implementing Binary Trees Pin
    11-Nov-00 10:39
    suss11-Nov-00 10:39 
    GeneralNetworkNeighbourhood Pin
    beretta12-Sep-00 10:02
    beretta12-Sep-00 10:02 
    GeneralRe: NetworkNeighbourhood Pin
    28-Aug-01 14:23
    suss28-Aug-01 14:23 
    GeneralRe: NetworkNeighbourhood Pin
    pjnaughter28-Jan-03 12:24
    pjnaughter28-Jan-03 12:24 
    GeneralImagelist and multiple instances of the class bug Pin
    Petter Nilsen2-Sep-00 8:12
    Petter Nilsen2-Sep-00 8:12 
    GeneralRe: Imagelist and multiple instances of the class bug Pin
    pjnaughter28-Jan-03 12:24
    pjnaughter28-Jan-03 12:24 
    GeneralA small bug in SetRootFolder Pin
    Malkav25-May-00 22:23
    Malkav25-May-00 22:23 
    GeneralGood job, but right-click bug Pin
    Laurent Guinnard8-Apr-00 10:11
    Laurent Guinnard8-Apr-00 10:11 

    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.