SftTree/DLL 7.5 - Tree Control
SftBox/OCX 5.0 - Combo Box Control
SftButton/OCX 3.0 - Button Control
SftMask/OCX 7.0 - Masked Edit Control
SftTabs/OCX 6.5 - Tab Control (VB6 only)
SftTree/OCX 7.5 - Tree Control
SftPrintPreview/DLL 2.0 - Print Preview Control (discontinued)
SftTree/DLL 7.5 - Tree Control
SftBox/OCX 5.0 - Combo Box Control
SftButton/OCX 3.0 - Button Control
SftDirectory 3.5 - File/Folder Control (discontinued)
SftMask/OCX 7.0 - Masked Edit Control
SftOptions 1.0 - Registry/INI Control (discontinued)
SftPrintPreview/OCX 1.0 - Print Preview Control (discontinued)
SftTabs/OCX 6.5 - Tab Control (VB6 only)
SftTree/OCX 7.5 - Tree Control
SftTabs/NET 6.0 - Tab Control (discontinued)
SftTree/NET 2.0 - Tree Control
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); }