Hide

SftTree/DLL 7.5 - Tree Control

Display
Print

Pictures Sample (C++)

This sample illustrates various image types, progress bars, checkbox and radio button manipulation.

The source code is located at C:\Program Files (x86)\Softelvdm\SftTree DLL 7.5\Samples\MFC\Pictures\SamplVw.cpp or C:\Program Files\Softelvdm\SftTree DLL 7.5\Samples\MFC\Pictures\SamplVw.cpp (on 32-bit Windows versions).

/****************************************************************************/
/* SftTree/DLL 7.5 - Tree Control for C/C++                                 */
/* Copyright (C) 1995, 2016  Softel vdm, Inc. All Rights Reserved.          */
/****************************************************************************/

#include "stdafx.h"
#include "Pictures.h"

#include "sampldoc.h"
#include "samplvw.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSampleView

IMPLEMENT_DYNCREATE(CSampleView, CView)

BEGIN_MESSAGE_MAP(CSampleView, CView)
    //{{AFX_MSG_MAP(CSampleView)
    ON_WM_CREATE()
    ON_WM_SIZE()
    ON_WM_TIMER()
    ON_WM_DESTROY()
    //}}AFX_MSG_MAP
    ON_SFTTREEN_LBUTTONDBLCLK_TEXT(IDC_TREE, OnLButtonExpandCollapse)
    ON_SFTTREEN_LBUTTONDOWN_BUTTON(IDC_TREE, OnLButtonExpandCollapse)
    ON_SFTTREEN_LBUTTONDBLCLK_BUTTON(IDC_TREE, OnLButtonExpandCollapse)
    ON_SFTTREEN_EXPANDALL(IDC_TREE, OnExpandAll)
    ON_SFTTREEN_LBUTTONDBLCLK_COLUMNRES(IDC_TREE, OnLButtonDblClkColumnResize)
    ON_SFTTREEN_SELCHANGE(IDC_TREE, OnSelChange)
    ON_SFTTREEN_LBUTTONDOWN_ITEM(IDC_TREE, OnToggleItemPicture)
    ON_SFTTREEN_LBUTTONDBLCLK_ITEM(IDC_TREE, OnToggleItemPicture)
    ON_SFTTREEN_LBUTTONDOWN_CELLBMP(IDC_TREE, OnToggleCellPicture)
    ON_SFTTREEN_LBUTTONDBLCLK_CELLBMP(IDC_TREE, OnToggleCellPicture)
    ON_SFTTREEN_LBUTTONDOWN_COLUMN_HEADER(IDC_TREE, OnSetSortDirection)
    ON_SFTTREEN_LBUTTONDBLCLK_COLUMN_HEADER(IDC_TREE, OnSetSortDirection)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSampleView construction/destruction

CSampleView::CSampleView()
{
    // load sample images
    m_hIconSmall = (HICON) LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
    m_BitmapSmall.LoadBitmap(IDB_SMILE);
    m_BitmapLarge.LoadBitmap(IDB_LOGO);
    m_ImgList.Create(IDB_TOOLBAR, 16, 0, RGB(255,0,0));

    // In this example, we are using GDI+ images.
    // GDI+ images CANNOT be added as BITMAP resources. They are always added with
    // a custom resource type, in this example we use "PNG".
    m_ButtonExpanded = NULL;         // GDI+ images for expand/collapse buttons
    m_ButtonExpandedHot = NULL;      // These can simply be cast to (Gdiplus::Image*)
    m_ButtonCollapsed = NULL;
    m_ButtonCollapsedHot = NULL;
    m_FolderClosed = NULL;           // folder item image
    m_FolderOpen = NULL;
    m_FolderLeaf = NULL;

    m_PNGImage = NULL;
    m_PNGImage2 = NULL;

    m_fAscending = TRUE; // sort direction
}

CSampleView::~CSampleView()
{
    if (m_hIconSmall)
        DestroyIcon(m_hIconSmall);

    if (m_ButtonExpanded) delete m_ButtonExpanded;
    if (m_ButtonExpandedHot) delete m_ButtonExpandedHot;
    if (m_ButtonCollapsed) delete m_ButtonCollapsed;
    if (m_ButtonCollapsedHot) delete m_ButtonCollapsedHot;
    if (m_FolderClosed) delete m_FolderClosed;
    if (m_FolderOpen) delete m_FolderOpen;
    if (m_FolderLeaf) delete m_FolderLeaf;
    if (m_PNGImage) delete m_PNGImage;
    if (m_PNGImage2) delete m_PNGImage2;
}

/////////////////////////////////////////////////////////////////////////////
// CSampleView drawing

void CSampleView::OnDraw(CDC* pDC)
{
    CSampleDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
}

/////////////////////////////////////////////////////////////////////////////
// CSampleView diagnostics

#ifdef _DEBUG
void CSampleView::AssertValid() const
{
    CView::AssertValid();
}

void CSampleView::Dump(CDumpContext& dc) const
{
    CView::Dump(dc);
}

CSampleDoc* CSampleView::GetDocument() // non-debug version is inline
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSampleDoc)));
    return (CSampleDoc*)m_pDocument;
}
#endif //_DEBUG

/**********************************************************************/
/*                         Helper Routines                            */
/**********************************************************************/

void CSampleView::SetCellPicture(int index, SFT_PICTURE* pPic, int align)
{
    SFTTREE_CELLINFOPARM CellInfo;
    CellInfo.version = 7;         
    CellInfo.index = index;
    CellInfo.iCol = 0;
    m_Tree.GetCellInfo(&CellInfo);
    Sft_ClearPicture(&CellInfo.Cell.CellPicture1);
    Sft_CopyPicture(&CellInfo.Cell.CellPicture1, pPic);
    CellInfo.Cell.flag = align;
    m_Tree.SetCellInfo(&CellInfo);
}

void CSampleView::SetRowPicture(int index, SFT_PICTURE* pPic)
{
    SFTTREE_ROWINFOPARM RowInfo;
    RowInfo.version = 7;          
    RowInfo.index = index;
    m_Tree.GetRowInfo(&RowInfo);
    Sft_ClearPicture(&RowInfo.Row.RowPicture1);
    Sft_CopyPicture(&RowInfo.Row.RowPicture1, pPic);
    RowInfo.Row.flag = SFTTREE_BMP_RIGHT;
    m_Tree.SetRowInfo(&RowInfo);
}

void CSampleView::UpdatePictures(int index, SFT_PICTURE* pPic, int align)
{
    int w, h;

    SetCellPicture(index, pPic, align);

    Sft_GetPictureSize(pPic, &w, &h);
    if (w <= PIC_SIZEX || h <= PIC_SIZEY)  { // don't use images that are too large
        m_Tree.SetItemPicture(index, pPic);
        m_Tree.SetItemLabelPicture(index, pPic);
        SetRowPicture(index, pPic);
    }
}

void CSampleView::CopyPictureFromCurrentItem()
{
    SFTTREE_CELLINFOPARM CellInfo;
    LPSFTTREE_COLUMN_EX lpCol;
    int nCols;
    int w, h;

    int index = m_Tree.GetCurSel();

    if (index < 0) return;

    // retrieve current cell picture
    CellInfo.version = 7;         
    CellInfo.index = index;
    CellInfo.iCol = 0;
    m_Tree.GetCellInfo(&CellInfo);

    Sft_GetPictureSize(&CellInfo.Cell.CellPicture1, &w, &h);

    if (w <= PIC_SIZEX || h <= PIC_SIZEY)  { // don't use images that are too large for the header
        // copy it to row/column header and column header
        m_Tree.SetRowColHeaderPicture(&CellInfo.Cell.CellPicture1);/* Row/column picture */

        nCols = m_Tree.GetColumns(&lpCol);/* Get column attributes */
        Sft_CopyPicture(&lpCol[1].Picture1, &CellInfo.Cell.CellPicture1); // second column
        m_Tree.SetColumns(nCols, lpCol);  /* Set new column attributes */
    } else {
        m_Tree.SetRowColHeaderPicture(NULL);

        nCols = m_Tree.GetColumns(&lpCol);/* Get column attributes */
        Sft_ClearPicture(&lpCol[1].Picture1); // second column
        m_Tree.SetColumns(nCols, lpCol);  /* Set new column attributes */
    }
}

BOOL CSampleView::TogglePicture(SFT_PICTURE* pPic)
{
    if (pPic->type == SFT_PICTURE_CB ||                   // check box
            pPic->type == SFT_PICTURE_CB3 ||              // 3 state check box
            pPic->type == SFT_PICTURE_RB ||               // radio button
            pPic->type == SFT_PICTURE_UPDOWN ||           // up/down button
            pPic->type == SFT_PICTURE_UPDOWNSORT)         // sort direction indicator
        pPic->Picture.CheckBox.state = pPic->Picture.CheckBox.state == 1 ? 0 : 1;
    else    
        return FALSE; // nothing to change
    return TRUE;
}

void CSampleView::ToggleItemPicture(int index)
{
    SFT_PICTURE Pic;
    Sft_InitPicture(&Pic);
    m_Tree.GetItemPicture(index, &Pic);
    if (TogglePicture(&Pic))
        m_Tree.SetItemPicture(index, &Pic);
}

void CSampleView::ToggleCellPicture(int index)
{
    SFTTREE_CELLINFOPARM CellInfo;
    CellInfo.version = 7;         
    CellInfo.index = index;
    CellInfo.iCol = 0;
    m_Tree.GetCellInfo(&CellInfo);
    if (TogglePicture(&CellInfo.Cell.CellPicture1))
        m_Tree.SetCellInfo(&CellInfo);
}

/**********************************************************************/
/*                        Column Header Sorting                       */
/**********************************************************************/

void CSampleView::ShowSortDirection(BOOL fAscending)
{
    LPSFTTREE_COLUMN_EX lpCol;
    int nCols;

    nCols = m_Tree.GetColumns(&lpCol);/* Get column attributes */
    Sft_SetPictureUpDownSort(&lpCol[0].Picture1, fAscending ? 1 : 0, PIC_SIZEX_SORT, PIC_SIZEY_SORT, TRUE);
    m_Tree.SetColumns(nCols, lpCol);  /* Set new column attributes */

    m_fAscending = fAscending;
}

/*static */ int CALLBACK CSampleView::SortCallbackExAscending(HWND hwnd, LPCTSTR lpszString1, LPCTSTR lpszString2, 
                  SFTTREE_DWORD_PTR itemData1, SFTTREE_DWORD_PTR itemData2) 
{
    return lstrcmp(lpszString1, lpszString2); 
} 

/*static */ int CALLBACK CSampleView::SortCallbackExDescending(HWND hwnd, LPCTSTR lpszString1, LPCTSTR lpszString2, 
                  SFTTREE_DWORD_PTR itemData1, SFTTREE_DWORD_PTR itemData2) 
{
    return lstrcmp(lpszString2, lpszString1); 
} 

void CSampleView::SortItems(int index, BOOL fAscending)
{
    int parentIndex;

    // sort this item's dependents
    m_Tree.SortDependents(index, 0, fAscending ? SortCallbackExAscending : SortCallbackExDescending);
    // now visit all dependents and sort each dependent's child items.
    if (index < 0)
        parentIndex = 0;
    else
        parentIndex = m_Tree.GetDependent(index, SFTTREE_DEPENDENT_FIRST);// start with first item
    for ( ; parentIndex >= 0 ; parentIndex = m_Tree.GetSibling(parentIndex, SFTTREE_SIBLING_NEXT)) {
        SortItems(parentIndex, fAscending);
    }
}

void CSampleView::SetSortDirection(BOOL fAscending)
{
    ShowSortDirection(fAscending);
    SortItems(-1, fAscending);
}

/**********************************************************************/
/*                            Color Samples                           */
/**********************************************************************/

struct tagColorEntry {
    LPCTSTR lpszName;
    COLORREF color;
} aPropListColors[] = {
    { _T("Black"),      RGB(  0,  0,  0),  },
    { _T("Blue"),       RGB(  0,  0,255),  },
    { _T("Cyan"),       RGB(  0,255,255),  },
    { _T("Green"),      RGB(  0,255,  0),  },
    { _T("Magenta"),    RGB(255,  0,255),  },
    { _T("Red"),        RGB(255,  0,  0),  },
    { _T("White"),      RGB(255,255,255),  },
    { _T("Yellow"),     RGB(255,255,  0),  },
    { _T("Dk Blue"),    RGB(  0,  0,128),  },
    { _T("Dk Cyan"),    RGB(  0,128,128),  },
    { _T("Dk Green"),   RGB(  0,128,  0),  },
    { _T("Dk Magenta"), RGB(128,  0,128),  },
    { _T("Dk Red"),     RGB(128,  0,  0),  },
    { _T("Dk Yellow"),  RGB(128,128,  0),  },
    { _T("Dk Gray"),    RGB(128,128,128),  },
    { _T("Lt Gray"),    RGB(192,192,192),  },
    { _T("3DDKSHADOW - Dark shadow for 3D elements"), 0x80000000L | COLOR_3DDKSHADOW, },
    { _T("3DFACE - Face color for 3D elements"), 0x80000000L | COLOR_3DFACE, },
    { _T("3DHILIGHT - Edges facing the light source"), 0x80000000L | COLOR_3DHILIGHT, },
    { _T("3DLIGHT - Edges facing the light source"), 0x80000000L | COLOR_3DLIGHT, },
    { _T("3DSHADOW - Edges facing away from the light source"), 0x80000000L | COLOR_3DSHADOW, },
    { _T("INFOBK - Background color for tooltip controls"), 0x80000000L | COLOR_INFOBK, },
    { _T("INFOTEXT - Text color for tooltip controls"), 0x80000000L | COLOR_INFOTEXT, },
    { _T("MENUTEXT - Text in menus"), 0x80000000L | COLOR_MENUTEXT, },
    { _T("ACTIVEBORDER - Active window border"), 0x80000000L | COLOR_ACTIVEBORDER, },
    { _T("ACTIVECAPTION - Active window caption"), 0x80000000L | COLOR_ACTIVECAPTION, },
    { _T("APPWORKSPACE - Background color MDI applications"), 0x80000000L | COLOR_APPWORKSPACE, },
    { _T("BACKGROUND - Desktop"), 0x80000000L | COLOR_BACKGROUND, },
    { _T("BTNFACE - Face shading on push buttons"), 0x80000000L | COLOR_BTNFACE, },
    { _T("BTNHILIGHT - Highlight color for buttons"), 0x80000000L | COLOR_BTNHIGHLIGHT, },
    { _T("BTNSHADOW - Edge shading on push buttons"), 0x80000000L | COLOR_BTNSHADOW, },
    { _T("BTNTEXT - Text on push buttons"), 0x80000000L | COLOR_BTNTEXT, },
    { _T("CAPTIONTEXT - Text in caption"), 0x80000000L | COLOR_CAPTIONTEXT, },
    { _T("GRAYTEXT - Grayed (disabled) text"), 0x80000000L | COLOR_GRAYTEXT, },
    { _T("HIGHLIGHT - Selected Item(s)"), 0x80000000L | COLOR_HIGHLIGHT, },
    { _T("HIGHLIGHTTEXT - Text of selected item(s)"), 0x80000000L | COLOR_HIGHLIGHTTEXT, },
    { _T("INACTIVEBORDER - Inactive window border"), 0x80000000L | COLOR_INACTIVEBORDER, },
    { _T("INACTIVECAPTION - Inactive window caption"), 0x80000000L | COLOR_INACTIVECAPTION, },
    { _T("INACTIVECAPTIONTEXT - Inactive caption text color"), 0x80000000L | COLOR_INACTIVECAPTIONTEXT, },
    { _T("MENU - Menu background"), 0x80000000L | COLOR_MENU, },
    { _T("SCROLLBAR - Scroll bar gray area"), 0x80000000L | COLOR_SCROLLBAR, },
    { _T("WINDOW - Window background"), 0x80000000L | COLOR_WINDOW, },
    { _T("WINDOWFRAME - Window frame"), 0x80000000L | COLOR_WINDOWFRAME, },
    { _T("WINDOWTEXT - Text in windows"), 0x80000000L | COLOR_WINDOWTEXT, },
    { NULL, 0 },
};

/////////////////////////////////////////////////////////////////////////////
// CSampleView message handlers

int CSampleView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    if (!m_Tree.CreateEx(
        WS_EX_CLIENTEDGE,
        SFTTREESTYLE_NOTIFY |            /* Notify parent window */
        SFTTREESTYLE_VARIABLE |          /* Variable height items */
        SFTTREESTYLE_LEFTBUTTONONLY |    /* Only respond to left mouse button */
        SFTTREESTYLE_SCROLL |            /* Honor WS_H/VSCROLL */
        WS_HSCROLL | WS_VSCROLL |        /* Vertical and horizontal scrollbars */
        WS_VISIBLE | WS_CHILD,           /* Visible, child window */
        CRect(0,0,0,0),                  /* Location */
        this,                            /* Parent window */
        IDC_TREE))                       /* Tree control ID */
            return -1;
    
    m_Tree.SetShowHeader(TRUE);          /* Show column headers */
    m_Tree.SetItemLines(5);              /* (Maximum) number of text lines */

    SFT_PICTURE Pic;

    /* Register the label picture size.  All label pictures    */
    /* used must be the same size.  Only one picture needs to  */
    /* be registered, even if several are used.                */
    Sft_InitPicture(&Pic);               /* Initialize */
    Sft_SetPictureSizeOnly(&Pic, PIC_SIZEX, PIC_SIZEY);/* Dimensions only for registration */
    m_Tree.SetItemLabelPicture(-1, &Pic);/* Register the label picture size */
    /* Set individual label pictures using the following sample code: */
    // Sft_SetPictureBitmap(&Pic, m_anotherLabelBitmap);/* Assign bitmap */
    // m_Tree.SetItemLabelPicture(index, &Pic);/* Set a label picture */
    /* Register the item pictures.  These pictures are used    */
    /* for all items in the tree control. All three pictures   */
    /* must be the same size.                                  */
    SFT_PICTURE aPic[3];
    Sft_InitPicture(&aPic[0]);
    Sft_InitPicture(&aPic[1]);
    Sft_InitPicture(&aPic[2]);

    if (m_Tree.GetGDIPlusAvailable()) {
        // In this example, we are using GDI+ images.
        // GDI+ images CANNOT be added as BITMAP resources. They are always added with
        // a custom resource type, in this example we use "PNG".
        m_FolderClosed = (Gdiplus::Image*)SftTree_LoadGDIPlusImageFromResource(AfxGetApp()->m_hInstance, _T("PNG"), MAKEINTRESOURCE(IDR_FOLDERCLOSED));
        m_FolderOpen = (Gdiplus::Image*)SftTree_LoadGDIPlusImageFromResource(AfxGetApp()->m_hInstance, _T("PNG"), MAKEINTRESOURCE(IDR_FOLDEROPEN));
        m_FolderLeaf = (Gdiplus::Image*)SftTree_LoadGDIPlusImageFromResource(AfxGetApp()->m_hInstance, _T("PNG"), MAKEINTRESOURCE(IDR_FOLDERLEAF));
        Sft_SetPictureGDIPlusImage(&aPic[0], m_FolderClosed);
        Sft_SetPictureGDIPlusImage(&aPic[1], m_FolderOpen);
        Sft_SetPictureGDIPlusImage(&aPic[2], m_FolderLeaf);
    } else {
        m_BitmapClosed.LoadBitmap(MAKEINTRESOURCE(IDB_EXPANDABLE));
        m_BitmapOpen.LoadBitmap(MAKEINTRESOURCE(IDB_EXPANDED));
        m_BitmapLeaf.LoadBitmap(MAKEINTRESOURCE(IDB_LEAF));
        Sft_SetPictureBitmap(&aPic[0], m_BitmapClosed);/* Expandable picture */
        Sft_SetPictureBitmap(&aPic[1], m_BitmapOpen);/* Expanded picture */
        Sft_SetPictureBitmap(&aPic[2], m_BitmapLeaf);/* Leaf picture */
    }
    m_Tree.SetPictures(aPic);        /* Use item pictures */
    /* Override individual item bitmaps using: */
    // m_OtherItemPicture.LoadBitmap(IDB_your_bitmap);/* Item bitmap */
    // Sft_SetPictureBitmap(&Pic, m_OtherItemPicture);/* Assign bitmap */
    // m_Tree.SetItemPicture(index, &Pic);/* Set an item picture */
    m_Tree.SetItemPictureAlign(TRUE);    /* Align item bitmaps */
    /* Register the cell picture size.  All cell pictures used */
    /* must be the same size.  Only one picture needs to be    */
    /* registered, even if several are used.                   */
    {
        SFTTREE_CELLINFOPARM CellInfo;
        CellInfo.version = 7;            
        CellInfo.index = -1;             /* Registering picture size */
        Sft_InitPicture(&CellInfo.Cell.CellPicture1);/* Initialize */
        Sft_SetPictureSizeOnly(&CellInfo.Cell.CellPicture1, PIC_SIZEX, PIC_SIZEY);/* Dimensions only for registration */
        m_Tree.SetCellInfo(&CellInfo);   /* Register use of cell pictures */
        /* Set individual cell pictures using this sample code: */

        // SFTTREE_CELLINFOPARM CellInfo;
        // CellInfo.version = 7;         
        // CellInfo.index = cell_index_to_change;
        // CellInfo.iCol = column_number_to_change;
        // m_Tree.GetCellInfo(&CellInfo);
        // /* m_CellBitmap.LoadBitmap(IDB_your_bitmap); *//* Cell picture */
        // Sft_SetPictureBitmap(&CellInfo.Cell.CellPicture1, m_CellBitmap);
        // CellInfo.Cell.flag = SFTTREE_BMP_RIGHT;
        // m_Tree.SetCellInfo(&CellInfo);
    }
    m_Tree.SetTreeLineStyle(SFTTREE_TREELINE_AUTOMATIC0);/* Dotted tree lines (incl. level 0) */
    m_Tree.SetShowButtons(TRUE);         /* Expand/collapse buttons (level 1..n) */
    m_Tree.SetShowButton0(TRUE);         /* Show expand/collapse buttons (level 0) */
    if (m_Tree.GetGDIPlusAvailable())
        m_Tree.SetButtons(SFTTREE_BUTTON_USERDEF);/* User-defined buttons */
    else
        m_Tree.SetButtons(SFTTREE_BUTTON_AUTOMATIC3);/* Automatic button style 3 */
    m_Tree.SetShowGrid(TRUE);            /* Show grid */
    m_Tree.SetGridStyle(SFTTREE_GRID_BOTH_DOT);/* Dotted grid lines */
    m_Tree.SetShowTruncated(TRUE);       /* Show ... if truncated */
    m_Tree.SetSelectionStyle(SFTTREE_SELECTION_ALL | SFTTREE_SELECTION_OUTLINE);/* Select entire item using outline */
    m_Tree.SetSelectionArea(SFTTREE_SELECTIONAREA_ALLCELLS);/* Selection changes by clicking on an item's cells */
    m_Tree.SetFlyby(TRUE);               /* Flyby highlighting */
    m_Tree.SetUpdateCaretExpandCollapse(FALSE);/* don't update caret location when expand/collapse button clicked */
    m_Tree.SetScrollTips(TRUE);          /* Show Scrolltips */
    m_Tree.SetInheritBgColor(TRUE);      /* Inherit background color of first cell */
    m_Tree.SetReorderColumns(TRUE);      /* Column reordering */
    m_Tree.SetOpenEnded(FALSE);          /* Last column width */
    m_Tree.SetShowHeaderButtons(TRUE);   /* Show column header as buttons */

    /* Define control attributes */
    {
        SFTTREE_CONTROL CtrlInfo;
        memset(&CtrlInfo, 0, sizeof(SFTTREE_CONTROL));
        CtrlInfo.cbSize = sizeof(SFTTREE_CONTROL);
        if (!m_Tree.GetControlInfo(&CtrlInfo))/* Get current settings */
            _ASSERT(0); /* Error handling goes here */
        // You need to create a images for at least the ButtonExpanded and ButtonCollapsed button state
        //Sft_SetPictureBitmap(&CtrlInfo.ButtonExpanded, a_bitmap_handle);
        //Sft_SetPictureBitmap(&CtrlInfo.ButtonCollapsed, a_bitmap_handle);

        if (m_Tree.GetGDIPlusAvailable()) {
            // In this example, we are using GDI+ images.
            // GDI+ images CANNOT be added as BITMAP resources. They are always added with
            // a custom resource type, in this example we use "PNG".
            m_ButtonExpanded = (Gdiplus::Image*)SftTree_LoadGDIPlusImageFromResource(AfxGetApp()->m_hInstance, _T("PNG"), MAKEINTRESOURCE(IDR_BUTTONEXPANDED));
            m_ButtonExpandedHot = (Gdiplus::Image*)SftTree_LoadGDIPlusImageFromResource(AfxGetApp()->m_hInstance, _T("PNG"), MAKEINTRESOURCE(IDR_BUTTONEXPANDED_HOT));
            m_ButtonCollapsed = (Gdiplus::Image*)SftTree_LoadGDIPlusImageFromResource(AfxGetApp()->m_hInstance, _T("PNG"), MAKEINTRESOURCE(IDR_BUTTONCOLLAPSED));
            m_ButtonCollapsedHot = (Gdiplus::Image*)SftTree_LoadGDIPlusImageFromResource(AfxGetApp()->m_hInstance, _T("PNG"), MAKEINTRESOURCE(IDR_BUTTONCOLLAPSED_HOT));
            Sft_SetPictureGDIPlusImage(&CtrlInfo.ButtonExpanded, m_ButtonExpanded);
            Sft_SetPictureGDIPlusImage(&CtrlInfo.ButtonExpandedHot, m_ButtonExpandedHot);
            Sft_SetPictureGDIPlusImage(&CtrlInfo.ButtonCollapsed, m_ButtonCollapsed);
            Sft_SetPictureGDIPlusImage(&CtrlInfo.ButtonCollapsedHot, m_ButtonCollapsedHot);
        }
        if (!m_Tree.SetControlInfo(&CtrlInfo))/* Save new settings */
            _ASSERT(0); /* Error handling goes here */
    }

    /* Define columns */
    {
        SFTTREE_COLUMN_EX aCol[2] = {
          { 0, 0,                        /* Reserved */
            221,                         /* Width (in pixels) */
            ES_LEFT | SFTTREE_MULTILINE | SFTTREE_TOOLTIP,/* Cell alignment */
            ES_LEFT | SFTTREE_HEADER_UP, /* Title style */
            _T("Picture"),               /* Column header title */
            NULL, NULL,                  /* Reserved field and bitmap handle */
            SFTTREE_BMP_RIGHT,           /* Picture alignment */
            0, 0, 0,                     /* Reserved fields */
            SFTTREE_NOCOLOR,             /* Cell background color */
            SFTTREE_NOCOLOR,             /* Cell foreground color */
            SFTTREE_NOCOLOR,             /* Selected cell background color */
            SFTTREE_NOCOLOR,             /* Selected cell foreground color */
            0,                           /* Real column position (set by SetColumns call) */
            0,                           /* Display column number (display position) */
            SFTTREE_COL_MERGE |          /* Column can merge with next */
            SFTTREE_COL_MERGEINTO |      /* Previous column can merge into this column */
            0,                           /* Column flag */
            0,                           /* Minimum column width */
          },                             
          { 0, 0,                        /* Reserved */
            300,                         /* Width (in pixels) */
            ES_LEFT | SFTTREE_MULTILINE | SFTTREE_WRAP | SFTTREE_TOOLTIP,/* Cell alignment */
            ES_LEFT | SFTTREE_HEADER_UP, /* Title style */
            _T("Description"),          /* Column header title */
            NULL, NULL,                  /* Reserved field and bitmap handle */
            SFTTREE_BMP_RIGHT,           /* Picture alignment */
            0, 0, 0,                     /* Reserved fields */
            SFTTREE_NOCOLOR,             /* Cell background color */
            SFTTREE_NOCOLOR,             /* Cell foreground color */
            SFTTREE_NOCOLOR,             /* Selected cell background color */
            SFTTREE_NOCOLOR,             /* Selected cell foreground color */
            0,                           /* Real column position (set by SetColumns call) */
            1,                           /* Display column number (display position) */
            SFTTREE_COL_MERGE |          /* Column can merge with next */
            SFTTREE_COL_MERGEINTO |      /* Previous column can merge into this column */
            0,                           /* Column flag */
            0,                           /* Minimum column width */
          }                              
        };
        m_Tree.SetColumns(2, aCol);/* Set column attributes */
    }

    /* Use column header pictures.  All pictures used must be  */
    /* the same size.                                          */
    {
        LPSFTTREE_COLUMN_EX lpCol;
        int nCols;
        nCols = m_Tree.GetColumns(&lpCol);/* Get column attributes */
        Sft_SetPictureSizeOnly(&lpCol[0].Picture1, PIC_SIZEX, PIC_SIZEY);/* Set column header picture size */
        Sft_SetPictureSizeOnly(&lpCol[1].Picture1, PIC_SIZEX, PIC_SIZEY);/* Set column header picture size */
        m_Tree.SetColumns(nCols, lpCol); /* Set new column attributes */
    }

    m_Tree.SetShowRowHeader(SFTTREE_ROWSTYLE_BUTTONCOUNT1);/* Row style */
    /* Register the row header picture size.  All row header   */
    /* pictures used must be the same size.  Only one picture  */
    /* needs to be registered, even if several are used.       */
    {
        SFTTREE_ROWINFOPARM RowInfo;
        RowInfo.version = 7;             
        RowInfo.index = -1;
        Sft_InitPicture(&RowInfo.Row.RowPicture1);
        Sft_SetPictureSizeOnly(&RowInfo.Row.RowPicture1, PIC_SIZEX, PIC_SIZEY);
        m_Tree.SetRowInfo(&RowInfo);
        /* Set individual row header bitmaps using: */
        // SFTTREE_ROWINFOPARM RowInfo;
        // RowInfo.version = 7;          
        // RowInfo.index = index;
        // m_Tree.GetRowInfo(&RowInfo);
        // /* m_RowBitmap.LoadBitmap(IDB_your_bitmap); *//* Row header picture */
        // Sft_SetPictureBitmap(&RowInfo.Row.RowPicture1, m_RowBitmap);
        // RowInfo.Row.flag = SFTTREE_BMP_RIGHT;
        // m_Tree.SetRowInfo(&RowInfo);
    }
    m_Tree.SetRowColHeaderText(_T("?"));       /* Row/column header text */
    m_Tree.SetRowColHeaderStyle(ES_LEFT | SFTTREE_HEADER_UP);/* Row/column header style */
    Sft_InitPicture(&Pic);               /* Initialize */
    Sft_SetPictureSizeOnly(&Pic, PIC_SIZEX, PIC_SIZEY);/* Row/column header picture */
    m_Tree.SetRowColHeaderPicture(&Pic);       /* Row/column picture */
    m_Tree.SetRowColHeaderPictureStyle(SFTTREE_BMP_RIGHT);/* Row/column picture alignment */
    m_Tree.SetCharSearchMode(SFTTREE_CHARSEARCH_ALLCHARS, -1);/* Consider all characters typed */
    /* Change the default colors */
    {
        SFTTREE_COLORS Colors;
        m_Tree.GetCtlColors(&Colors);    /* Get current color settings */
        Colors.colorTreeLines = COLOR_3DDKSHADOW | 0x80000000L;/* Tree line color */
        Colors.colorSelBgNoFocus = COLOR_BTNFACE | 0x80000000L;/* Selection background color (no input focus) */
        Colors.colorSelFgNoFocus = COLOR_BTNTEXT | 0x80000000L;/* Selection foreground color (no input focus) */
        m_Tree.SetCtlColors(&Colors);    /* Set new colors */
    }

    /*------------------------------------------------------------------------------*/
    /* Add a few items.                                                             */
    /*------------------------------------------------------------------------------*/

    {
        int index;

        index = m_Tree.AddString(_T("Progress Bars"));
        m_Tree.SetText(index, 0, _T("SftTree/DLL supports progress bars as cell background (partial or full size)."));

        // add progress bar samples
        {
            SFTTREE_CELLINFOPARM CellInfo;

            int i = m_Tree.AddString(_T("Progress Bar - Full Size"));
            m_Tree.SetItemLevel(i, 1);
            CellInfo.version = 7;
            CellInfo.index = i;
            CellInfo.iCol = 0;
            m_Tree.GetCellInfo(&CellInfo);
            CellInfo.Cell.progressMax = 100;    // maximum value 0 - 100
            CellInfo.Cell.progressVal = 33;     // current value
            m_Tree.SetCellInfo(&CellInfo);

            i = m_Tree.AddString(_T("Progress Bar - Partial"));
            m_Tree.SetItemLevel(i, 1);
            CellInfo.version = 7;
            CellInfo.index = i;
            CellInfo.iCol = 0;
            m_Tree.GetCellInfo(&CellInfo);
            CellInfo.Cell.flag3 = SFTTREE_CELL_PROGRESSHORIZONTAL|SFTTREE_CELL_PROGRESSSMALL;
            CellInfo.Cell.progressMax = 200;    // maximum value 0 - 200
            CellInfo.Cell.progressVal = 133;    // current value
            m_Tree.SetCellInfo(&CellInfo);

            i = m_Tree.AddString(_T("Progress Bar - with gradient fill"));
            m_Tree.SetItemLevel(i, 1);
            CellInfo.version = 7;
            CellInfo.index = i;
            CellInfo.iCol = 0;
            m_Tree.GetCellInfo(&CellInfo);
            CellInfo.Cell.flag3 = SFTTREE_CELL_PROGRESSHORIZONTAL|SFTTREE_CELL_PROGRESSSMALL;
            CellInfo.Cell.progressMax = 50;    // maximum value 0 - 50
            CellInfo.Cell.progressVal = 40;    // current value
            CellInfo.Cell.colorProgress = RGB(128,128, 0);
            CellInfo.Cell.colorProgressEnd = RGB(255,255, 0);
            m_Tree.SetCellInfo(&CellInfo);

            i = m_Tree.AddString(_T("Progress Bar - customizable colors"));
            m_Tree.SetItemLevel(i, 1);
            CellInfo.version = 7;
            CellInfo.index = i;
            CellInfo.iCol = 0;
            m_Tree.GetCellInfo(&CellInfo);
            CellInfo.Cell.flag3 = SFTTREE_CELL_PROGRESSSMALL|SFTTREE_CELL_PROGRESSVERTICAL|SFTTREE_CELL_BGHORIZONTAL;
            CellInfo.Cell.progressMax = 150;    // maximum value 0 - 150
            CellInfo.Cell.progressVal = 40;    // current value
            CellInfo.Cell.colorProgress = RGB(128,128, 0);
            CellInfo.Cell.colorProgressEnd = RGB(255,255, 0);
            CellInfo.Cell.colorBg = COLOR_WINDOW | 0x80000000L;
            CellInfo.Cell.colorBgEnd = RGB(255,0,0);
            m_Tree.SetCellInfo(&CellInfo);
        }
       
        index = m_Tree.AddString(_T("Supported Picture Types"));
        m_Tree.SetText(index, 1, _T("SftTree/DLL supports numerous image types, such as bitmaps, icons, ImageLists and also offers numerous built-in images."));

        index = m_Tree.AddString(_T("GDI+ Images"));
        m_Tree.SetItemLevel(index, 1);
        m_Tree.SetText(index, 1, _T("All GDI+ images are supported, like GIF, JPEG, Exif, PNG, TIFF and device-independent bitmaps (up to 64bpp) with semi-transparent and translucent areas."));

        if (m_Tree.GetGDIPlusAvailable()) {

            int i = m_Tree.AddString(_T("PNG Sample with alpha-channel for translucent edges"));
            m_Tree.SetItemLevel(i, 2);
            m_PNGImage = (Gdiplus::Image*) SftTree_LoadGDIPlusImageFromResource(AfxGetApp()->m_hInstance, _T("PNG"), MAKEINTRESOURCE(IDR_WORLD));
            Sft_SetPictureGDIPlusImage(&Pic, m_PNGImage);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);

            i = m_Tree.AddString(_T("Another PNG Sample with alpha-channel for translucent edges"));
            m_Tree.SetItemLevel(i, 2);
            m_PNGImage2 = (Gdiplus::Image*) SftTree_LoadGDIPlusImageFromResource(AfxGetApp()->m_hInstance, _T("PNG"), MAKEINTRESOURCE(IDR_WARN));
            Sft_SetPictureGDIPlusImage(&Pic, m_PNGImage2);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
        }

        index = m_Tree.AddString(_T("Bitmaps"));
        m_Tree.SetItemLevel(index, 1);
        m_Tree.SetText(index, 1, _T("Bitmaps can be of varying sizes and also support Bitmap Transparency, which allows the background to show through the image (in areas selected by the bitmap designer)."));

        // add bitmap samples
        {
            int i = m_Tree.AddString(_T("Large Bitmap"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureBitmap(&Pic, (HBITMAP) m_BitmapLarge);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);

            i = m_Tree.AddString(_T("Various bitmap sizes"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureBitmap(&Pic, (HBITMAP) m_BitmapSmall);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
        }

        index = m_Tree.AddString(_T("Icons"));
        m_Tree.SetItemLevel(index, 1);
        m_Tree.SetText(index, 1, _T("The supported icons can be stardard size icons (32x32) or any other size supported by the operating system."));

        // add icon samples
        {
            int i = m_Tree.AddString(_T("Standard Icon (32x32)"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureIcon(&Pic, LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_ICON1)));
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);

            i = m_Tree.AddString(_T("Any other size"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureIcon(&Pic, m_hIconSmall);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
        }

        index = m_Tree.AddString(_T("ImageLists"));
        m_Tree.SetItemLevel(index, 1);
        m_Tree.SetText(index, 1, _T("Complete ImageList support simplifies bitmap handling and can avoid the limited resource availability on earlier Windows versions."));

        // add imaglist samples
        {
            int c, count = m_ImgList.GetImageCount();
            for (c = 0 ; c < count ; ++c) {
                TCHAR szBuffer[80];
                int i;
                wsprintf(szBuffer, _T("Image %d"), c);
                i = m_Tree.AddString(szBuffer);
                m_Tree.SetItemLevel(i, 2);
                Sft_SetPictureImageList(&Pic, (HIMAGELIST) m_ImgList, (short) c, 0);
                UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            }
        }


        index = m_Tree.AddString(_T("Color Samples"));
        m_Tree.SetItemLevel(index, 1);
        m_Tree.SetText(index, 1, _T("Using the built-in color sample image, simple color selection can easily be implemented.  Color samples can display all colors available."));

        // add color samples from table
        {
            struct tagColorEntry* pc = aPropListColors;
            for ( ; pc->lpszName ; ++pc) {
                int i = m_Tree.AddString(pc->lpszName);
                m_Tree.SetItemLevel(i, 2);
                Sft_SetPictureColorSample(&Pic, PIC_SIZEX_COLORSAMPLE, PIC_SIZEY_COLORSAMPLE, pc->color, 0x80000000L|COLOR_WINDOWTEXT);
                UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            }
        }

        index = m_Tree.AddString(_T("Predefined (Built-in) Pictures"));
        m_Tree.SetText(index, 1, _T("Predefined images are available for commonly used items, such as check boxes, radio buttons, sort direction indicators and more..."));

        index = m_Tree.AddString(_T("Check Boxes - Honors Windows Themes"));
        m_Tree.SetItemLevel(index, 1);

        // add checkbox sample
        {
            int i = m_Tree.AddString(_T("Enabled, Selected Check Box"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureCheckBox(&Pic, 1, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, TRUE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Disabled, Selected Check Box"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureCheckBox(&Pic, 1, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, FALSE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Enabled Check Box"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureCheckBox(&Pic, 0, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, TRUE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Disabled Check Box"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureCheckBox(&Pic, 0, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, FALSE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
        }

        index = m_Tree.AddString(_T("Check Boxes (3-State) - Honors Windows Themes"));
        m_Tree.SetItemLevel(index, 1);

        // add checkbox (3-state) sample
        {
            int i = m_Tree.AddString(_T("Enabled, Selected Check Box"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureCheckBox3(&Pic, 1, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, TRUE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Disabled, Selected Check Box"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureCheckBox3(&Pic, 1, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, FALSE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Enabled Check Box"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureCheckBox3(&Pic, 0, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, TRUE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Disabled Check Box"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureCheckBox3(&Pic, 0, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, FALSE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Enabled, Unknown Check Box"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureCheckBox3(&Pic, -1, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, TRUE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Disabled, Unknown Check Box"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureCheckBox3(&Pic, -1, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, FALSE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
        }

        index = m_Tree.AddString(_T("Radio Buttons - Honors Windows Themes"));
        m_Tree.SetItemLevel(index, 1);

        // add radio button sample
        {
            int i = m_Tree.AddString(_T("Enabled, Selected Radio Button"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureRadioButton(&Pic, 1, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, TRUE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Disabled, Selected Radio Button"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureRadioButton(&Pic, 1, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, FALSE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Enabled Radio Button"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureRadioButton(&Pic, 0, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, TRUE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Disabled Radio Button"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureRadioButton(&Pic, 0, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, FALSE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
        }

        index = m_Tree.AddString(_T("Up/Down Buttons - Honors Windows Themes"));
        m_Tree.SetItemLevel(index, 1);

        // add up/down button sample
        {
            int i = m_Tree.AddString(_T("Enabled Up Button"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureUpDown(&Pic, 1, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, TRUE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Disabled Up Button"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureUpDown(&Pic, 1, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, FALSE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Enabled Down Button"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureUpDown(&Pic, 0, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, TRUE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Disabled Down Button"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureUpDown(&Pic, 0, PIC_SIZEX_CHECKBOX, PIC_SIZEY_CHECKBOX, FALSE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
        }

        index = m_Tree.AddString(_T("Sort Direction Indicator"));
        m_Tree.SetItemLevel(index, 1);

        // add sort direction indicator sample
        {
            int i = m_Tree.AddString(_T("Enabled Ascending Indicator"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureUpDownSort(&Pic, 1, PIC_SIZEX_SORT, PIC_SIZEY_SORT, TRUE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Disabled Ascending Indicator"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureUpDownSort(&Pic, 1, PIC_SIZEX_SORT, PIC_SIZEY_SORT, FALSE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Enabled Descending Indicator"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureUpDownSort(&Pic, 0, PIC_SIZEX_SORT, PIC_SIZEY_SORT, TRUE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
            i = m_Tree.AddString(_T("Disabled Descending Indicator"));
            m_Tree.SetItemLevel(i, 2);
            Sft_SetPictureUpDownSort(&Pic, 0, PIC_SIZEX_SORT, PIC_SIZEY_SORT, FALSE);
            UpdatePictures(i, &Pic, SFTTREE_BMP_RIGHT);
        }
    }

    /*------------------------------------------------------------------------------*/
    /* Once ALL TREE CONTROL ITEMS HAVE BEEN ADDED, you can set additional tree     */
    /* control attributes.                                                          */
    /*------------------------------------------------------------------------------*/
    
    /* Make row header width optimal, so text and pictures are  */
    /* not clipped horizontally.                               */
    m_Tree.MakeRowHeaderOptimal(0, FALSE);/* Make row header width optimal */

    m_Tree.MakeColumnOptimal(0);/* Only make the first column optimal */
    m_Tree.RecalcHorizontalExtent(0, FALSE);/* Update horizontal scroll bar */

    m_Tree.SetCaretIndex(0);
    m_Tree.SetCurSel(0);
    CopyPictureFromCurrentItem();

    // Set a timer so we can update our progress bars every once in a while
    SetTimer(TIMERID, 333, NULL);

    return 0;
}

void CSampleView::OnSize(UINT nType, int cx, int cy) 
{
    CView::OnSize(nType, cx, cy);
    m_Tree.MoveWindow(0, 0, cx, cy);
}

void CSampleView::OnTimer( UINT_PTR ID)
{
    // update all cells that have a progress bar by incrementing the progress value
    // we know that only the first few items can have a progress bar, so we only scan
    // the first dozen items.
    int items = min(12, m_Tree.GetCount());
    int nCols = m_Tree.GetColumns();
    for (int item = 0 ; item < items ; ++item) {
        for (int col = 0 ; col < nCols ; ++col) {
            SFTTREE_CELLINFOPARM CellInfo;
            CellInfo.version = 7;
            CellInfo.index = item;
            CellInfo.iCol = col;
            m_Tree.GetCellInfo(&CellInfo);
            if (CellInfo.Cell.progressMax > 0) {
                CellInfo.Cell.progressVal = (CellInfo.Cell.progressVal+4) % CellInfo.Cell.progressMax;
                m_Tree.SetCellInfo(&CellInfo);
            }
        }
    }
}

void CSampleView::OnDestroy()
{
    KillTimer(TIMERID);
    CView::OnDestroy();
}

/* Respond to events as the user clicks on different tree  */
/* components.  The events handled here can be changed to  */
/* suit your application.                                  */

void CSampleView::OnLButtonExpandCollapse()
{
    /* get index of item to expand/collapse */
    int index = m_Tree.GetExpandCollapseIndex();
    /* get current expand/collapsed status */
    BOOL fExpanded = m_Tree.GetItemExpand(index);
    /* if control key is used we'll expand all dependents */
    BOOL fDepth = (::GetKeyState(VK_CONTROL)&0x8000);

    if (fExpanded)
        m_Tree.Collapse(index, TRUE);
    else
        m_Tree.Expand(index, TRUE, fDepth);
}

/* Respond to numeric keypad multiply key.                 */

void CSampleView::OnExpandAll()
{
    /* get index of item to expand/collapse */
    int index = m_Tree.GetExpandCollapseIndex();

   m_Tree.Expand(index, TRUE, TRUE);
}

/* Respond to events as the user double-clicks on the      */
/* column resizing area.  The events handled here can be   */
/* changed to suit your application.                       */

void CSampleView::OnLButtonDblClkColumnResize()
{
    /* Resize column optimally */
    int realCol = m_Tree.GetResizeColumn();
    if (realCol >= 0) {
        m_Tree.MakeColumnOptimal(realCol);/* Make column width optimal */
        m_Tree.RecalcHorizontalExtent(0, FALSE);/* Update horizontal scroll bar */
    }
}

void CSampleView::OnSelChange()
{
    CopyPictureFromCurrentItem();
}

void CSampleView::OnToggleItemPicture()
{
    ToggleItemPicture(m_Tree.GetCaretIndex());
}

void CSampleView::OnToggleCellPicture()
{
    ToggleCellPicture(m_Tree.GetCaretIndex());
}

void CSampleView::OnSetSortDirection()
{
    if (m_Tree.GetHeaderButton() == 0) // sort column 0
        SetSortDirection(!m_fAscending);
}