SOL9 2.0 Class: FolderTreeView

 SOL9 C++ Class Library  SOL9 Samples  SOL9 Tutorial  SOL9 FAQ  SOL9 ClassTree 

Source code

/*
 * FolderTreeView.h 
 * Copyright (c) 2011 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// SOL++2000
// 2000.02.18
#pragma once

#include <sol\TreeView.h>

#include <sol\ImageList.h>


namespace SOL {

class FolderTreeView :public TreeView {
private:
    int        iconId;
    int        selIconId;
    ImageList* imageList;

private:

    HTREEITEM hasEntry(HTREEITEM child, const TCHAR* name)
    {
        HTREEITEM found = NULL;
        HTREEITEM item = child;
        while(item) {
            TV_ITEM hitem;

            TCHAR text[_MAX_PATH];
            hitem.mask       = TVIF_TEXT|TVIF_HANDLE;
            hitem.hItem      = item;
            hitem.pszText    = text;
            hitem.cchTextMax = _MAX_PATH;
            getItem(&hitem);
    
            if(strcmp(text, name) == 0) {
                found = item;
                break;
            }
            item = getNextSibling(item);
        }
        return found;
    }

public:      
    FolderTreeView():TreeView() { }


public:
    FolderTreeView(View* parent, const TCHAR* name, Args& args)
    :TreeView(parent, name,
        args.set(XmNexStyle, (ulong)WS_EX_CLIENTEDGE)
            .set(XmNstyle, (ulong)TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT) )

    {
        imageList = NULL;
        HINSTANCE hInst = getInstanceHandle();

        imageList = new ImageList(16, 16, ILC_COLOR24, 2,1);

        TCHAR dir[_MAX_PATH];
        ::GetWindowsDirectory(dir, sizeof(dir));
        SHFILEINFO shfi;
        ::SHGetFileInfo(dir, FILE_ATTRIBUTE_DIRECTORY,
            &shfi, sizeof(shfi), SHGFI_ICON|SHGFI_SMALLICON);

        imageList -> setBkColor(::GetSysColor(COLOR_WINDOW));
        iconId   = imageList -> addIcon(shfi.hIcon);

        ::SHGetFileInfo(dir, FILE_ATTRIBUTE_DIRECTORY,
            &shfi, sizeof(shfi), 
            SHGFI_ICON|SHGFI_OPENICON|SHGFI_SMALLICON);
        selIconId = imageList -> addIcon(shfi.hIcon); 

        setImageList(imageList, 0);
    }

public:
    ~FolderTreeView()
    {
        delete imageList; 
    }

public:
    virtual Boolean create(View* parent, const TCHAR* name, Args& args)
    {
        Boolean rc = TreeView::create(parent, name,
            args.set(XmNexStyle, (ulong)WS_EX_CLIENTEDGE)
                .set(XmNstyle, (ulong)TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT) );

        imageList = NULL;
        HINSTANCE hInst = getInstanceHandle();

        imageList = new ImageList(16, 16, ILC_COLOR24, 2,1);

        TCHAR dir[_MAX_PATH];
        ::GetWindowsDirectory(dir, sizeof(dir));
        SHFILEINFO shfi;
        ::SHGetFileInfo(dir, FILE_ATTRIBUTE_DIRECTORY,
            &shfi, sizeof(shfi), SHGFI_ICON|SHGFI_SMALLICON);

        imageList -> setBkColor(::GetSysColor(COLOR_WINDOW));
        iconId   = imageList -> addIcon(shfi.hIcon);

        ::SHGetFileInfo(dir, FILE_ATTRIBUTE_DIRECTORY,
            &shfi, sizeof(shfi), 
            SHGFI_ICON|SHGFI_OPENICON|SHGFI_SMALLICON);
        selIconId = imageList -> addIcon(shfi.hIcon); 

        setImageList(imageList, 0);

        return rc;
    }

public:
    void buildDirTree()
    {
        TCHAR dir[_MAX_PATH];
        ::GetWindowsDirectory(dir, sizeof(dir));

        TCHAR path[10];
        DWORD d = ::GetLogicalDrives();

        HTREEITEM item = NULL;
        for(int i = 0; i<26; i++) {
            if(d & 1) {
                //wsprintf(path, "%c:", 'A'+i);
                _stprintf_s(path, SizeOf(path), _T("%c:"), 'A' + 1);

                item = addItem(NULL, TVI_LAST, path);
                findDirectories(item, dir, 0, 2);
                sortChildren(item, TRUE);
                if(path[0] == dir[0]) {
                    expand(item, TVE_EXPAND);
                }
            }
            d = d >> 1;
        }
    }


public:
    void findDirectories(HTREEITEM parent, const TCHAR* dir,
                  int level, int max)
    {
        if(level < max) {
            WIN32_FIND_DATA data;
            HTREEITEM item = (HTREEITEM)TVI_FIRST;

            TCHAR* buffer = new TCHAR[_MAX_PATH];
            _stprintf_s(buffer, _MAX_PATH, _T("%s\\*"), dir);
        
            HANDLE fFile= ::FindFirstFile(buffer, &data);

            HTREEITEM child = getChild(parent);

            if(fFile != INVALID_HANDLE_VALUE) {
                do {
                    if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                        if (strcmp(_T("."), data.cFileName) != 0 && 
                            strcmp(_T(".."), data.cFileName) != 0) {

                            item = hasEntry(child, data.cFileName);

                        // 
                            if(item == NULL) {
                                item = addItem(parent, item, 
                                        data.cFileName,
                                        iconId, selIconId);
                            }
                            TCHAR* subDir = new TCHAR[_MAX_PATH];
                            _stprintf_s(subDir, _MAX_PATH, _T("%s\\%s"), dir, data.cFileName);
                
                            findDirectories(item, (const TCHAR*)subDir,
                                level+1, max);
                            delete [] subDir;
                        }
                    }
                } while(FindNextFile(fFile, &data)); 
                ::FindClose(fFile);
            }
            delete [] buffer;
        }
    }

public:
    // 2008/07/11
    // It's much better to us StringBuffer for buff.

    void getHierachy(HTREEITEM selItem, TCHAR* buff, TCHAR* delim)
    {
        TV_ITEM hitem;

        HTREEITEM parent = getParent(selItem);
        if(parent) {
            // parent node
            getHierachy(parent, buff, delim);
            TCHAR* text       = new TCHAR[_MAX_PATH];
            hitem.mask       = TVIF_TEXT|TVIF_HANDLE;
            hitem.hItem      = selItem;
            hitem.pszText    = text;
            hitem.cchTextMax = _MAX_PATH;
            getItem(&hitem);
            strcat(buff, delim);
            strcat(buff, text);
            delete [] text;
        }
        else {
            TCHAR* text       = new TCHAR[_MAX_PATH];
            hitem.mask       = TVIF_TEXT|TVIF_HANDLE;
            hitem.hItem      = selItem;
            hitem.pszText    = text;
            hitem.cchTextMax = _MAX_PATH;
            getItem(&hitem);
            strcat(buff, text);
            delete [] text;
        }
    }

};

}




Last modified: 1 Feb 2012

Copyright (c) 2009-2012 Antillia.com ALL RIGHTS RESERVED.