Hide

SftTree/DLL 7.5 - Tree Control

Display
Print

ContextMenu Sample (C++)

This sample illustrates context menus, sort indicators and dropdown/filter buttons.

The source code is located at C:\Program Files (x86)\Softelvdm\SftTree DLL 7.5\Samples\MFC\ContextMenu\SamplVw.cpp or C:\Program Files\Softelvdm\SftTree DLL 7.5\Samples\MFC\ContextMenu\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 "ContextMenu.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_CONTEXTMENU()
    //}}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_LBUTTONDOWN_COLUMN_HEADER(IDC_TREE, OnColumnHeaderClick)
    ON_SFTTREEN_LBUTTONDBLCLK_COLUMN_HEADER(IDC_TREE, OnColumnHeaderClick)

	ON_SFTTREEN_LBUTTONDOWN_COLUMN_HEADERDD(IDC_TREE, OnColumnHeaderDDClick)
    ON_SFTTREEN_LBUTTONDBLCLK_COLUMN_HEADERDD(IDC_TREE, OnColumnHeaderDDClick)

    ON_COMMAND_RANGE( IDM_COLUMN_ENABLE+0, IDM_COLUMN_ENABLE+50, OnColumnEnable)
    ON_COMMAND( IDM_COLUMN_ENABLE_ALL, OnColumnEnableAll)

    ON_COMMAND( ID_POPUP_ITEM, OnPopupNoptImplemented)
    ON_COMMAND( ID_POPUP_EDIT, OnPopupNoptImplemented)
    ON_COMMAND( ID_POPUP_INSERT, OnPopupNoptImplemented)
    ON_COMMAND( ID_POPUP_APPEND, OnPopupNoptImplemented)
    ON_COMMAND( ID_POPUP_DELETE, OnPopupNoptImplemented)
END_MESSAGE_MAP()

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

CSampleView::CSampleView()
{
}

CSampleView::~CSampleView()
{
}

/////////////////////////////////////////////////////////////////////////////
// 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

/////////////////////////////////////////////////////////////////////////////
// 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_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 */

    /* 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]);
        m_aThreeItemBitmaps[0].LoadBitmap(IDB_EXPANDABLE);/* Expandable bitmap */
        Sft_SetPictureBitmap(&aPic[0], m_aThreeItemBitmaps[0]);/* Assign bitmap */
        m_aThreeItemBitmaps[1].LoadBitmap(IDB_EXPANDED);/* 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 */
        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.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_CELL1);/* Select first cell only */
    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.EnableSortIndicators(TRUE, TRUE);/* Automatic sort indicators - application must implement sorting */
    m_Tree.SetOpenEnded(TRUE);           /* 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 */
            ; /* Error handling goes here */
        CtrlInfo.fRowColumnHeaderColorsOverrideTheme = TRUE;
                                         /* Row/column header can override Windows themes */
        CtrlInfo.fRowColumnFooterColorsOverrideTheme = TRUE;
                                         /* Row/column footer can override Windows themes */
        CtrlInfo.iFlybyStyle = SFTTREE_FLYBY_COL1;
        if (!m_Tree.SetControlInfo(&CtrlInfo))/* Save new settings */
            ; /* Error handling goes here */
    }

    /* Define columns */
    {
        SFTTREE_COLUMN_EX aCol[3] = {
          { 0, 0,                        /* Reserved */
            41,                          /* Width (in pixels) */
            ES_LEFT | SFTTREE_TOOLTIP,   /* Cell alignment */
            ES_LEFT | SFTTREE_HEADER_UP | SFTTREE_HEADER_FILTER,/* Title style */
            _T("First Column"),          /* Column header title */
            NULL, NULL,                  /* Reserved field and bitmap handle */
            SFTTREE_BMP_RIGHT,           /* Picture alignment */
            0,                           /* Reserved */
            SFTTREE_COL_BGHORIZONTAL | SFTTREE_COL_PROGRESSHORIZONTAL | SFTTREE_COL_PROGRESSSMALL,
            0,                           /* Reserved */
            SFTTREE_NOCOLOR,             /* Default cell background color */
            SFTTREE_NOCOLOR,             /* Default cell foreground color */
            SFTTREE_NOCOLOR,             /* Default cell background color for selected cells */
            SFTTREE_NOCOLOR,             /* Default cell foreground color for selected cells */
            0,                           /* Real column position (set by SetColumns call) */
            0,                           /* Display column number (display position) */
            0,                           /* Column flag */
            0,                           /* Minimum column width */
            0,0,                         /* Reserved */
            { 0 },                       /* Image - none */
            TRUE,                        /* Allow color overrides */
            RGB(0,0,0),                  /* Column header's background color */
            RGB(0,0,0),                  /* Column header's foreground color */
            RGB(0,0,0),                  /* Column header's background color if selected */
            RGB(0,0,0),                  /* Column header's foreground color if selected */
            RGB(0,0,0),                  /* Column header's background color if disabled */
            RGB(0,0,0),                  /* Column header's foreground color if disabled */
            RGB(0,0,0),                  /* Column header's background color if disabled and selected */
            RGB(0,0,0),                  /* Column header's foreground color if disabled and selected */
            RGB(0,0,0),                  /* Column's cell default background color (ending color for gradient fill) */
            RGB(0,0,0),                  /* Column's cell default background color if selected (ending color for gradient fill) */
            RGB(0,0,0),                  /* Column's default progressbar color */
            RGB(0,0,0),                  /* Column's default progressbar color  (ending color for gradient fill) */
            ES_LEFT,                     /* Footer style */
            TEXT(""),                    /* Column footer title */
            NULL,                        /* Reserved field */
            { 0 },                       /* Image - none */
            SFTTREE_BMP_LEFT,            /* Picture alignment */
            TRUE,                        /* Allow color overrides */
            RGB(0,0,0),                  /* Column footer's background color */
            RGB(0,0,0),                  /* Column footer's foreground color */
            RGB(0,0,0),                  /* Column footer's background color if selected */
            RGB(0,0,0),                  /* Column footer's foreground color if selected */
            RGB(0,0,0),                  /* Column footer's background color if disabled */
            RGB(0,0,0),                  /* Column footer's foreground color if disabled */
            RGB(0,0,0),                  /* Column footer's background color if disabled and selected */
            RGB(0,0,0),                  /* Column footer's foreground color if disabled and selected */
          },                             
          { 0, 0,                        /* Reserved */
            190,                         /* Width (in pixels) */
            ES_LEFT | SFTTREE_TOOLTIP,   /* Cell alignment */
            ES_LEFT | SFTTREE_HEADER_UP | SFTTREE_HEADER_FILTER,/* Title style */
            _T("Second Column"),         /* Column header title */
            NULL, NULL,                  /* Reserved field and bitmap handle */
            SFTTREE_BMP_RIGHT,           /* Picture alignment */
            0,                           /* Reserved */
            SFTTREE_COL_BGHORIZONTAL | SFTTREE_COL_PROGRESSHORIZONTAL | SFTTREE_COL_PROGRESSSMALL,
            0,                           /* Reserved */
            SFTTREE_NOCOLOR,             /* Default cell background color */
            SFTTREE_NOCOLOR,             /* Default cell foreground color */
            SFTTREE_NOCOLOR,             /* Default cell background color for selected cells */
            SFTTREE_NOCOLOR,             /* Default cell foreground color for selected cells */
            0,                           /* Real column position (set by SetColumns call) */
            1,                           /* Display column number (display position) */
            0,                           /* Column flag */
            0,                           /* Minimum column width */
            0,0,                         /* Reserved */
            { 0 },                       /* Image - none */
            TRUE,                        /* Allow color overrides */
            RGB(0,0,0),                  /* Column header's background color */
            RGB(0,0,0),                  /* Column header's foreground color */
            RGB(0,0,0),                  /* Column header's background color if selected */
            RGB(0,0,0),                  /* Column header's foreground color if selected */
            RGB(0,0,0),                  /* Column header's background color if disabled */
            RGB(0,0,0),                  /* Column header's foreground color if disabled */
            RGB(0,0,0),                  /* Column header's background color if disabled and selected */
            RGB(0,0,0),                  /* Column header's foreground color if disabled and selected */
            RGB(0,0,0),                  /* Column's cell default background color (ending color for gradient fill) */
            RGB(0,0,0),                  /* Column's cell default background color if selected (ending color for gradient fill) */
            RGB(0,0,0),                  /* Column's default progressbar color */
            RGB(0,0,0),                  /* Column's default progressbar color  (ending color for gradient fill) */
            ES_LEFT,                     /* Footer style */
            TEXT(""),                    /* Column footer title */
            NULL,                        /* Reserved field */
            { 0 },                       /* Image - none */
            SFTTREE_BMP_LEFT,            /* Picture alignment */
            TRUE,                        /* Allow color overrides */
            RGB(0,0,0),                  /* Column footer's background color */
            RGB(0,0,0),                  /* Column footer's foreground color */
            RGB(0,0,0),                  /* Column footer's background color if selected */
            RGB(0,0,0),                  /* Column footer's foreground color if selected */
            RGB(0,0,0),                  /* Column footer's background color if disabled */
            RGB(0,0,0),                  /* Column footer's foreground color if disabled */
            RGB(0,0,0),                  /* Column footer's background color if disabled and selected */
            RGB(0,0,0),                  /* Column footer's foreground color if disabled and selected */
          },                             
          { 0, 0,                        /* Reserved */
            237,                         /* Width (in pixels) */
            ES_LEFT | SFTTREE_TOOLTIP,   /* Cell alignment */
            ES_LEFT | SFTTREE_HEADER_UP | SFTTREE_HEADER_FILTER,/* Title style */
            _T("Third Column"),          /* Column header title */
            NULL, NULL,                  /* Reserved field and bitmap handle */
            SFTTREE_BMP_RIGHT,           /* Picture alignment */
            0,                           /* Reserved */
            SFTTREE_COL_BGHORIZONTAL | SFTTREE_COL_PROGRESSHORIZONTAL | SFTTREE_COL_PROGRESSSMALL,
            0,                           /* Reserved */
            SFTTREE_NOCOLOR,             /* Default cell background color */
            SFTTREE_NOCOLOR,             /* Default cell foreground color */
            SFTTREE_NOCOLOR,             /* Default cell background color for selected cells */
            SFTTREE_NOCOLOR,             /* Default cell foreground color for selected cells */
            0,                           /* Real column position (set by SetColumns call) */
            2,                           /* Display column number (display position) */
            0,                           /* Column flag */
            0,                           /* Minimum column width */
            0,0,                         /* Reserved */
            { 0 },                       /* Image - none */
            TRUE,                        /* Allow color overrides */
            RGB(0,0,0),                  /* Column header's background color */
            RGB(0,0,0),                  /* Column header's foreground color */
            RGB(0,0,0),                  /* Column header's background color if selected */
            RGB(0,0,0),                  /* Column header's foreground color if selected */
            RGB(0,0,0),                  /* Column header's background color if disabled */
            RGB(0,0,0),                  /* Column header's foreground color if disabled */
            RGB(0,0,0),                  /* Column header's background color if disabled and selected */
            RGB(0,0,0),                  /* Column header's foreground color if disabled and selected */
            RGB(0,0,0),                  /* Column's cell default background color (ending color for gradient fill) */
            RGB(0,0,0),                  /* Column's cell default background color if selected (ending color for gradient fill) */
            RGB(0,0,0),                  /* Column's default progressbar color */
            RGB(0,0,0),                  /* Column's default progressbar color  (ending color for gradient fill) */
            ES_LEFT,                     /* Footer style */
            TEXT(""),                    /* Column footer title */
            NULL,                        /* Reserved field */
            { 0 },                       /* Image - none */
            SFTTREE_BMP_LEFT,            /* Picture alignment */
            TRUE,                        /* Allow color overrides */
            RGB(0,0,0),                  /* Column footer's background color */
            RGB(0,0,0),                  /* Column footer's foreground color */
            RGB(0,0,0),                  /* Column footer's background color if selected */
            RGB(0,0,0),                  /* Column footer's foreground color if selected */
            RGB(0,0,0),                  /* Column footer's background color if disabled */
            RGB(0,0,0),                  /* Column footer's foreground color if disabled */
            RGB(0,0,0),                  /* Column footer's background color if disabled and selected */
            RGB(0,0,0),                  /* Column footer's foreground color if disabled and selected */
          }                              
        };
        m_Tree.SetColumns(3, aCol);      /* Set column attributes */
    }

    m_Tree.SetShowRowHeader(SFTTREE_ROWSTYLE_BUTTONCOUNT1);/* Row style */
    m_Tree.SetRowColHeaderText(_T("?"));       /* Row/column header text */
    m_Tree.SetRowColHeaderStyle(ES_LEFT | SFTTREE_HEADER_UP);/* Row/column header style */
    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("In this sample, all items offer a context menu"));/* Add an item */
        index = m_Tree.AddString(_T("The column headers also offer a context menu"));/* Add another item */
        //m_Tree.SetItemLevel(index, 1);/* change level */
        m_Tree.SetText(index, 1, _T("2nd Column"));/* Set text in next column */
        m_Tree.SetText(index, 2, _T("3nd Column"));/* Set text in next column */

        index = m_Tree.AddString(_T("A third item"));/* Add another item */
        m_Tree.SetText(index, 1, _T("2nd Column"));/* Set text in next column */
        m_Tree.SetText(index, 2, _T("3nd Column"));/* Set text in next column */
        index = m_Tree.AddString(_T("The last item"));/* Add another item */
        m_Tree.SetText(index, 1, _T("2nd Column"));/* Set text in next column */
        m_Tree.SetText(index, 2, _T("3nd Column"));/* Set text in next column */

        index = m_Tree.AddString(_T("Item A"));/* Add another item */
        index = m_Tree.AddString(_T("Item B"));/* Add another item */
        index = m_Tree.AddString(_T("Item C"));/* Add another item */
    }

    /*------------------------------------------------------------------------------*/
    /* Once ALL TREE CONTROL ITEMS HAVE BEEN ADDED, you can set additional tree     */
    /* control attributes.                                                          */
    /*------------------------------------------------------------------------------*/
    
    /* Make all column widths optimal, so text and pictures are */
    /* not clipped horizontally.                               */
    m_Tree.MakeColumnOptimal(-1, 0, FALSE);/* Make column widths optimal */
    /* 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.RecalcHorizontalExtent(0, FALSE);/* Update horizontal scroll bar */

    return 0;
}

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

/* 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 */
    }
}

/* This sample code sorts the selected column (items on    */
/* level 0 ONLY) based on the current sort indicator which */
/* is automatically managed by the tree control.           */

void CSampleView::OnColumnHeaderClick()
{
    int sortCol, sortStyle;
    if (m_Tree.GetSortColumn1(sortCol, sortStyle)) {/* Retrieve the current sort column */
        BOOL ascending = (sortStyle == SFTTREE_SORT_ASC);
        m_Tree.SortDependents(-1, sortCol,
            ascending ? SortCallbackExAscending : SortCallbackExDescending);/* Sort level 0 items using the column and order specified */
    }
}

/* Colummn Dropdown/Filter was clicked */
void CSampleView::OnColumnHeaderDDClick()
{
	int col = m_Tree.GetHeaderButton();
	if (col >= 0) {
		CRect rect;
		if (m_Tree.GetDisplayHeaderDropDownRect(col, &rect)) {
			m_Tree.MapWindowPoints(NULL, &rect);
			ShowHeaderMenu(CPoint(rect.left, rect.bottom));
		}
	}
}

/*------------------------------------------------------------------------------*/
/* This sample code can be used to implement a sorting callback routine.        */
/* This routine is called to compare two items while sorting tree control       */
/* items using SortDependents.                                                  */
/*------------------------------------------------------------------------------*/

int CALLBACK CSampleView::SortCallbackExAscending(HWND hwnd, LPCTSTR lpszString1, LPCTSTR lpszString2, SFTTREE_DWORD_PTR item1, SFTTREE_DWORD_PTR item2)
{
    /* In this example, items are sorted in descending order. */

    int rc = lstrcmp(lpszString1, lpszString2);
    if (rc < 0)
        return -1;
    else if (rc > 0)
        return 1;
    return 0;
}

int CALLBACK CSampleView::SortCallbackExDescending(HWND hwnd, LPCTSTR lpszString1, LPCTSTR lpszString2, SFTTREE_DWORD_PTR item1, SFTTREE_DWORD_PTR item2)
{
    /* In this example, items are sorted in descending order. */

    int rc = lstrcmp(lpszString1, lpszString2);
    if (rc > 0)
        return -1;
    else if (rc < 0)
        return 1;
    return 0;
}

/**********************************************************************/
/*                            Context Menu                            */
/**********************************************************************/

void CSampleView::ShowHeaderMenu(CPoint pt)
{
    // the right mouse button was clicked in the column header, display
    // a menu to allow the user to hide/show columns
    int realCol, displayCol;
    int total = 0;
    BOOL fAdded = FALSE;

    // get column information
    LPSFTTREE_COLUMN_EX lpCols;
    int nCols = m_Tree.GetColumns(&lpCols);

    m_PopupMenu.DestroyMenu();
    m_PopupMenu.CreatePopupMenu();

    // determine how many columns are currently visible.  
    // If only one is visible, that menu entry must be grayed, it can't be unchecked 
    // (or we would have 0 visible columns.  Some users might object to that.
    for (realCol = 0 ; realCol < nCols ; ++realCol) {
        if (lpCols[realCol].width > 0)
            ++total;
    }
    // add a menu entry for each column
    for (displayCol = 0 ; displayCol < nCols ; ++displayCol) {
        int col;
        UINT nFlags = MF_STRING;
        LPCTSTR lpszMenuText;
        // translate the display column # to the actual column number
        col = lpCols[displayCol].realPos;
        // build a menu item
        if (lpCols[col].width > 0) {
            if (total == 1)
                nFlags |= MF_GRAYED;
            nFlags |= MF_CHECKED;
        }
        if (lpCols[col].minWidth > 0)
            nFlags |= MF_GRAYED;
        // use title as menu 
        lpszMenuText = TEXT("(No title)");
        if (lpCols[col].lpszTitle && *lpCols[col].lpszTitle)
            lpszMenuText = lpCols[col].lpszTitle;

        m_PopupMenu.AppendMenu(nFlags, IDM_COLUMN_ENABLE+displayCol, lpszMenuText);
        fAdded = TRUE;
    }
    // if nothing was added to the menu, don't display it
    if (fAdded) {
        m_PopupMenu.AppendMenu(MF_SEPARATOR, 0, TEXT(""));
        m_PopupMenu.AppendMenu(MF_STRING | (total < nCols ? 0 : MF_GRAYED), IDM_COLUMN_ENABLE_ALL, TEXT("Show All"));

        // Always send a WM_CANCELMODE to the tree control before displaying a popup menu
        m_Tree.SendMessage(WM_CANCELMODE);
        // Display the menu
        m_PopupMenu.TrackPopupMenu(TPM_LEFTALIGN
#if !defined(_WIN32_WCE)
            |TPM_LEFTBUTTON|TPM_RIGHTBUTTON
#endif
                , pt.x, pt.y, this, NULL);
    }
}

void CSampleView::OnColumnEnableAll()
{
    LPSFTTREE_COLUMN_EX lpCols;
    int realCol;
    int nCols = m_Tree.GetColumns(NULL);
    for (realCol = 0 ; realCol < nCols ; ++realCol) {
        // the column is no longer locked
        m_Tree.GetColumns(&lpCols);
        lpCols[realCol].colFlag &= ~SFTTREE_COL_LOCKED;
        m_Tree.SetColumns(nCols, lpCols);
        // resize the column
        m_Tree.MakeColumnOptimal(realCol);
    }    
    m_Tree.RecalcHorizontalExtent();
}

void CSampleView::OnColumnEnable(UINT id)
{
    // Get column information
    LPSFTTREE_COLUMN_EX lpCols;
    int nCols = m_Tree.GetColumns(&lpCols);

    // calculate the column number
    int displayCol = id - IDM_COLUMN_ENABLE;
    // this is the display number, so translate the display column # to 
    // the actual column number
    int realCol = m_Tree.GetRealColumn(displayCol);

    // now resize the column 
    if (lpCols[realCol].width == 0) {
        // the column is no longer locked
        lpCols[realCol].colFlag &= ~SFTTREE_COL_LOCKED;
        // save new attributes
        m_Tree.SetColumns(nCols, lpCols);
        // optimally resize the column
        m_Tree.MakeColumnOptimal(realCol);
    } else {
        // the column must be locked so the user can't resize it
        lpCols[realCol].colFlag |= SFTTREE_COL_LOCKED;
        // hide the column
        lpCols[realCol].width = 0;
        // save new attributes
        m_Tree.SetColumns(nCols, lpCols);
    }
    m_Tree.RecalcHorizontalExtent();
}

void CSampleView::OnPopupNoptImplemented()
{
    ::MessageBox(NULL, TEXT("This sample doesn't implement any actions for the item menu."),
                TEXT("SftTree/DLL Sample"), MB_OK|MB_TASKMODAL);
}

void CSampleView::ShowItemMenu(int index, CPoint pt)
{
    // the right mouse button was clicked on an item, display
    // a menu for the item
    CMenu menu;
    CMenu* popupMenu;

    m_Tree.SetCurSel(index); // select it
    m_Tree.SetCaretIndex(index); // make it the current item

    menu.LoadMenu(MAKEINTRESOURCE(IDR_MENU1));
    popupMenu = menu.GetSubMenu(0);

    CString str;
    m_Tree.GetText(index, 0, str);
    popupMenu->ModifyMenu(0, MF_BYPOSITION|MF_STRING, ID_POPUP_ITEM, str);

    // Always send a WM_CANCELMODE to the tree control before displaying a popup menu
    m_Tree.SendMessage(WM_CANCELMODE);
    // Display the menu
    popupMenu->TrackPopupMenu(TPM_LEFTALIGN
#if !defined(_WIN32_WCE)
        |TPM_LEFTBUTTON|TPM_RIGHTBUTTON
#endif
            , pt.x, pt.y, this, NULL);
}

void CSampleView::OnContextMenu( CWnd* pWnd, CPoint pt)
{
    RECT rect;
    int index;
    POINT ptTree;

    if (pt.x < 0 && pt.y < 0)             // Shift+F10 or VK_APPS pressed (not used in this sample)
        return;

    ptTree = pt;
    ScreenToClient(&ptTree);

    // check if header right-clicked - we don't show the popup there
    m_Tree.GetHeaderRect(-1, &rect);
    if (PtInRect(&rect, ptTree))
        return;

    // check if an item cell right-clicked
    index = m_Tree.CalcIndexFromPointEx(&ptTree);
    if (index >= 0 && index < m_Tree.GetCount()) {
        // on an item
        ShowItemMenu(index, pt);
        return;
    }
}