Hide

SftTree/DLL 7.5 - Tree Control

Display
Print

Speed Sample (C++)

This sample tests the performance when adding and deleting many items.

The source code is located at C:\Program Files (x86)\Softelvdm\SftTree DLL 7.5\Samples\MFC\Speed\SpeedDlg.cpp or C:\Program Files\Softelvdm\SftTree DLL 7.5\Samples\MFC\Speed\SpeedDlg.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 "Speed.h"
#include "SpeedDlg.h"

/////////////////////////////////////////////////////////////////////////////
// CSpeedDlg dialog

CSpeedDlg::CSpeedDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSpeedDlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CSpeedDlg)
    // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

    m_FolderClosed = NULL;           // folder item image
    m_FolderOpen = NULL;
    m_FolderLeaf = NULL;
}

CSpeedDlg::~CSpeedDlg()
{
    if (m_FolderClosed) delete m_FolderClosed;
    if (m_FolderOpen) delete m_FolderOpen;
    if (m_FolderLeaf) delete m_FolderLeaf;
}

void CSpeedDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CSpeedDlg)
    DDX_Control(pDX, IDC_TOTAL, m_CtlTotal);
    DDX_Control(pDX, IDC_SFTTREE1, m_Tree);
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSpeedDlg, CDialog)
    /* Handling expanding/collapsing items */
    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_AUTOEXPANDING(IDC_TREE, OnAutoExpand)
    //{{AFX_MSG_MAP(CSpeedDlg)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDADD100, OnAdd100)
    ON_BN_CLICKED(IDADD1000, OnAdd1000)
    ON_BN_CLICKED(IDADD10000, OnAdd10000)
    ON_BN_CLICKED(IDADD20000, OnAdd20000)
    ON_BN_CLICKED(IDADD5000, OnAdd5000)
    ON_BN_CLICKED(IDCLEAR, OnClear)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSpeedDlg message handlers

BOOL CSpeedDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);			// Set big icon
    SetIcon(m_hIcon, FALSE);		// Set small icon

    m_ItemTotal = 0;
	
    /* 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, TEXT("PNG"), MAKEINTRESOURCE(IDR_FOLDERCLOSED));
        m_FolderOpen = (Gdiplus::Image*)SftTree_LoadGDIPlusImageFromResource(AfxGetApp()->m_hInstance, TEXT("PNG"), MAKEINTRESOURCE(IDR_FOLDEROPEN));
        m_FolderLeaf = (Gdiplus::Image*)SftTree_LoadGDIPlusImageFromResource(AfxGetApp()->m_hInstance, TEXT("PNG"), MAKEINTRESOURCE(IDR_FOLDERLEAF));
        Sft_SetPictureGDIPlusImage(&aPic[0], m_FolderClosed);
        Sft_SetPictureGDIPlusImage(&aPic[1], m_FolderOpen);
        Sft_SetPictureGDIPlusImage(&aPic[2], m_FolderLeaf);
    } else {
        m_aThreeItemBitmaps[0].LoadBitmap(IDB_EXP);/* Expandable bitmap */
        Sft_SetPictureBitmap(&aPic[0], m_aThreeItemBitmaps[0]);/* Assign bitmap */
        m_aThreeItemBitmaps[1].LoadBitmap(IDB_EXPD);/* Expanded bitmap */
        Sft_SetPictureBitmap(&aPic[1], m_aThreeItemBitmaps[1]);/* Assign bitmap */
        m_aThreeItemBitmaps[2].LoadBitmap(IDB_LEAF);/* Leaf bitmap */
        Sft_SetPictureBitmap(&aPic[2], m_aThreeItemBitmaps[2]);/* Assign bitmap */
        /* 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.SetPictures(aPic);        /* Use item pictures */
    m_Tree.SetItemPictureAlign(TRUE);    /* Align item bitmaps */
    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) */
    m_Tree.SetButtons(SFTTREE_BUTTON_AUTOMATIC3);/* Automatic button style 3 */
    m_Tree.SetShowTruncated(TRUE);       /* Show ... if truncated */
    m_Tree.SetShowFocus(FALSE);          /* Don't show focus rectangle (caret) */
    m_Tree.SetSelectionStyle(SFTTREE_SELECTION_CELL1 | SFTTREE_SELECTION_OUTLINE);/* Select first cell only 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.SetScrollTips(TRUE);          /* Show Scrolltips */
    m_Tree.SetOpenEnded(TRUE);           /* Last column width */
    /* Define columns */
    {
        SFTTREE_COLUMN_EX aCol[1] = {
          { 0, 0,                        /* Reserved */
            100,                         /* Width (in pixels) */
            ES_LEFT | SFTTREE_TOOLTIP,   /* Cell alignment */
            ES_LEFT,                     /* Title style */
            _T("Title0"),                /* 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) */
            0,                           /* Column flag */
            0,                           /* Minimum column width */
          }                              
        };
        m_Tree.SetColumns(1, aCol);      /* Set column attributes */
    }

    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_BTNSHADOW | 0x80000000L;/* Tree line color */
        Colors.colorTreeLinesGrayed = COLOR_BTNSHADOW | 0x80000000L;/* Tree line color (disabled control) */
        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 */
    }

    UpdateTotal();
    return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CSpeedDlg::OnPaint() 
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CSpeedDlg::OnQueryDragIcon()
{
    return (HCURSOR) m_hIcon;
}

void CSpeedDlg::UpdateTotal()
{
    CString str;
    str.Format(_T("The tree control contains %d items."), m_ItemTotal);
    m_CtlTotal.SetWindowText(str);
}

void CSpeedDlg::AddItems(long count)
{
    CWaitCursor wt;

    long index;
    TCHAR szBuffer[512];

    m_Tree.SendMessage(WM_SETREDRAW, FALSE, 0);
    if (m_ItemTotal > 0) {
        m_Tree.SetCurSel(0);
        m_Tree.SetCaretIndex(0);
    }
    for (long i = 0 ; i < count ; ) {
        wsprintf(szBuffer, _T("Item %d"), m_ItemTotal++);
        index = m_Tree.AddString(szBuffer);
        ++i;
        wsprintf(szBuffer, _T("Item %d"), m_ItemTotal++);
        index = m_Tree.AddString(szBuffer);
        m_Tree.SetItemLevel(index, 1);
        ++i;
        wsprintf(szBuffer, _T("Item %d"), m_ItemTotal++);
        index = m_Tree.AddString(szBuffer);
        m_Tree.SetItemLevel(index, 2);
        ++i;
        wsprintf(szBuffer, _T("Item %d"), m_ItemTotal++);
        index = m_Tree.AddString(szBuffer);
        m_Tree.SetItemLevel(index, 1);
        ++i;
    }
    m_Tree.SetCurSel(index);
    m_Tree.SetCaretIndex(index);
    m_Tree.SendMessage(WM_SETREDRAW, TRUE, 0);
    m_Tree.InvalidateRect(NULL, TRUE);

    m_Tree.RecalcHorizontalExtent(100);
    m_Tree.SetHorizontalExtent(m_Tree.GetHorizontalExtent() + 30);

    UpdateTotal();
}

void CSpeedDlg::OnAdd100() 
{
    AddItems(100);
}

void CSpeedDlg::OnAdd1000() 
{
    AddItems(1000);
}

void CSpeedDlg::OnAdd5000() 
{
    AddItems(5000);
}

void CSpeedDlg::OnAdd10000() 
{
    AddItems(10000);
}

void CSpeedDlg::OnAdd20000() 
{
    AddItems(20000);
}

void CSpeedDlg::OnClear() 
{
    CWaitCursor wt;

    m_Tree.ResetContent();

    m_ItemTotal = 0;
    UpdateTotal();
}

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

void CSpeedDlg::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 CSpeedDlg::OnExpandAll()
{
    /* get index of item to expand/collapse */
    int index = m_Tree.GetExpandCollapseIndex();

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

/* Auto-Expand                                             */

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

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