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\C\ContextMenu\ContextMenu.c or C:\Program Files\Softelvdm\SftTree DLL 7.5\Samples\C\ContextMenu\ContextMenu.c (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 <windows.h>

#include "SftTree.h"                     /* SftTree/DLL Header File */

#include "resource.h"                    // resource IDs

/**********************************************************************/
/*                              Globals                               */
/**********************************************************************/

#define IDC_TREE                100     /* Tree control ID */

#define IDM_COLUMN_ENABLE_ALL   200     /* Menu command entries */
#define IDM_COLUMN_ENABLE       201

HINSTANCE g_hInst;                      // App Instance Handle
HWND g_hwndTree;                        /* Tree control */
HMENU g_hPopupMenu;                     /* Popup menu */

// Miscellaneous bitmaps
SFT_PICTURE m_aThreeItemPictures[3];    /* Three default item pictures, see SetPictures in online help */
//SFT_PICTURE m_OtherItemPicture;       /* Another item picture, see SetItemPicture in online help */

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

static void ShowHeaderMenu(HWND hwndParent, HWND hwndTree, int x, int y)
{
    // 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 = SftTree_GetColumnsEx(hwndTree, &lpCols);

    if (g_hPopupMenu)
        DestroyMenu(g_hPopupMenu);
    g_hPopupMenu = 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;

        AppendMenu(g_hPopupMenu, nFlags, IDM_COLUMN_ENABLE+displayCol, lpszMenuText);
        fAdded = TRUE;
    }
    // if nothing was added to the menu, don't display it
    if (fAdded) {
        AppendMenu(g_hPopupMenu, MF_SEPARATOR, 0, TEXT(""));
        AppendMenu(g_hPopupMenu, 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
        SendMessage(hwndTree, WM_CANCELMODE, 0, 0);
        // Display the menu
        TrackPopupMenu(g_hPopupMenu, TPM_LEFTALIGN
#if !defined(_WIN32_WCE)
            |TPM_LEFTBUTTON|TPM_RIGHTBUTTON
#endif
                , x, y, 0, hwndParent, NULL);
    }
}

static void OnColumnEnableAll(HWND hwndTree)
{
    LPSFTTREE_COLUMN_EX lpCols;
    int realCol;
    int nCols = SftTree_GetColumnsEx(hwndTree, NULL);
    for (realCol = 0 ; realCol < nCols ; ++realCol) {
        // the column is no longer locked
        SftTree_GetColumnsEx(hwndTree, &lpCols);
        lpCols[realCol].colFlag &= ~SFTTREE_COL_LOCKED;
        SftTree_SetColumnsEx(hwndTree, nCols, lpCols);
        // resize the column
        SftTree_MakeColumnOptimal(hwndTree, realCol);
    }
    SftTree_RecalcHorizontalExtent(hwndTree);
}

static void OnColumnEnable(HWND hwndTree, UINT id)
{
    // Get column information
    LPSFTTREE_COLUMN_EX lpCols;
    int nCols = SftTree_GetColumnsEx(hwndTree, &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 = SftTree_GetRealColumn(hwndTree, 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
        SftTree_SetColumnsEx(hwndTree, nCols, lpCols);
        // optimally resize the column
        SftTree_MakeColumnOptimal(hwndTree, 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
        SftTree_SetColumnsEx(hwndTree, nCols, lpCols);
    }
    SftTree_RecalcHorizontalExtent(hwndTree);
}

static void ShowItemMenu(HWND hwndParent, HWND hwndTree, int index, int x, int y)
{
    // the right mouse button was clicked on an item, display
    // a menu for the item
    HMENU hMenu;
    TCHAR szBuffer[1000];

    SftTree_SetCurSel(hwndTree, index); // select it
    SftTree_SetCaretIndex(hwndTree, index); // make it the current item

    hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MENU1));

    if (g_hPopupMenu)
        DestroyMenu(g_hPopupMenu);
    g_hPopupMenu = GetSubMenu(hMenu, 0);

    SftTree_GetTextCol(hwndTree, index, 0, szBuffer);
    ModifyMenu(g_hPopupMenu, 0, MF_BYPOSITION|MF_STRING, ID_POPUP_ITEM, szBuffer);

    // Always send a WM_CANCELMODE to the tree control before displaying a popup menu
    SendMessage(hwndTree, WM_CANCELMODE, 0, 0);
    // Display the menu
    TrackPopupMenu(g_hPopupMenu, TPM_LEFTALIGN
#if !defined(_WIN32_WCE)
        |TPM_LEFTBUTTON|TPM_RIGHTBUTTON
#endif
            , x, y, 0, hwndParent, NULL);

    DestroyMenu(hMenu);
}

static void HandleContextMenu(HWND hwndParent, HWND hwndTree, int x, int y)
{
    RECT rect;
    int index;
    POINT pt;

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

    pt.x = x; pt.y = y;
    MapWindowPoints(NULL, hwndTree, &pt, 1);

    // check if header right-clicked - we don't show the context menu there
    SftTree_GetHeaderRect(hwndTree, -1, &rect);
    if (PtInRect(&rect, pt))
        return;

    // check if an item cell right-clicked
    index = SftTree_CalcIndexFromPointEx(hwndTree, &pt);
    if (index >= 0 && index < SftTree_GetCount(hwndTree)) {
        // on an item
        ShowItemMenu(hwndParent, hwndTree, index, x, y);
        return;
    }
}

/*------------------------------------------------------------------------------*/
/* 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 SftTree_SortColDependentsEx.                                     */
/*------------------------------------------------------------------------------*/

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

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

int CALLBACK Tree_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;
}

/**********************************************************************/
/*                          Frame Window Proc                         */
/**********************************************************************/

LRESULT CALLBACK SDI_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg) {

    case WM_CREATE: {
        g_hwndTree = CreateWindowEx(
            WS_EX_CLIENTEDGE,
            TEXT(SFTTREE_CLASS),             /* Window class */
            TEXT(""),                        /* Caption (none) */
            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 */
            0, 0, 0, 0,                      /* Location */
            hwnd,                            /* Parent window */
            (HMENU) IDC_TREE,                /* Tree control ID */
            g_hInst,                         /* Application instance */
            NULL);
        if (!g_hwndTree)
            return -1;

        /* Resources, such as bitmaps, should be loaded and must remain    */
        /* valid until the tree control is destroyed or no longer uses     */
        /* these.  For example, use DeleteObject to delete any bitmaps.    */

        SftTree_SetShowHeader(g_hwndTree, 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_InitPicture(&m_aThreeItemPictures[0]);
        Sft_InitPicture(&m_aThreeItemPictures[1]);
        Sft_InitPicture(&m_aThreeItemPictures[2]);
        Sft_SetPictureBitmap(&m_aThreeItemPictures[0], LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_EXPANDABLE)));/* Expandable picture */
        Sft_SetPictureBitmap(&m_aThreeItemPictures[1], LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_EXPANDED)));/* Expanded picture */
        Sft_SetPictureBitmap(&m_aThreeItemPictures[2], LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_LEAF)));/* Leaf picture */
        SftTree_SetPictures(g_hwndTree, m_aThreeItemPictures);/* Use item picture */
        /* Override individual item pictures using: */
        // Sft_InitPicture(&m_OtherItemPicture);
        // Sft_SetPictureBitmap(m_OtherItemPicture, LoadBitmap(app_instance, MAKEINTRESOURCE(IDB_your_bitmap)));/* Item picture */
        // SftTree_SetItemPicture(g_hwndTree, index, m_OtherItemPicture);/* Set an item bitmap */
        SftTree_SetItemPictureAlign(g_hwndTree, TRUE);/* Align item bitmaps */
        SftTree_SetTreeLineStyle(g_hwndTree, SFTTREE_TREELINE_AUTOMATIC0);/* Dotted tree lines (incl. level 0) */
        SftTree_SetShowButtons(g_hwndTree, TRUE);/* Expand/collapse buttons (level 1..n) */
        SftTree_SetShowButton0(g_hwndTree, TRUE);/* Show expand/collapse buttons (level 0) */
        SftTree_SetButtons(g_hwndTree, SFTTREE_BUTTON_AUTOMATIC3);/* Automatic button style 3 */
        SftTree_SetShowGrid(g_hwndTree, TRUE);/* Show grid */
        SftTree_SetGridStyle(g_hwndTree, SFTTREE_GRID_BOTH_DOT);/* Dotted grid lines */
        SftTree_SetShowTruncated(g_hwndTree, TRUE);/* Show ... if truncated */
        SftTree_SetSelectionStyle(g_hwndTree, SFTTREE_SELECTION_CELL1);/* Select first cell only */
        SftTree_SetSelectionArea(g_hwndTree, SFTTREE_SELECTIONAREA_ALLCELLS);/* Selection changes by clicking on an item's cells */
        SftTree_SetFlyby(g_hwndTree, TRUE);  /* Flyby highlighting */
        SftTree_SetUpdateCaretExpandCollapse(g_hwndTree, FALSE);/* don't update caret location when expand/collapse button clicked */
        SftTree_SetScrollTips(g_hwndTree, TRUE);/* Show Scrolltips */
        SftTree_SetInheritBgColor(g_hwndTree, TRUE);/* Inherit background color of first cell */
        SftTree_SetReorderColumns(g_hwndTree, TRUE);/* Column reordering */
        SftTree_EnableSortIndicators(g_hwndTree, TRUE, TRUE);/* Automatic sort indicators - application must implement sorting */
        SftTree_SetOpenEnded(g_hwndTree, TRUE);/* Last column width */
        SftTree_SetShowHeaderButtons(g_hwndTree, TRUE);/* Show column header as buttons */

        /* Define control attributes */
        {
            SFTTREE_CONTROL CtrlInfo;
            memset(&CtrlInfo, 0, sizeof(SFTTREE_CONTROL));
            CtrlInfo.cbSize = sizeof(SFTTREE_CONTROL);
            if (!SftTree_GetControlInfo(g_hwndTree, &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 (!SftTree_SetControlInfo(g_hwndTree, &CtrlInfo))/* Save new settings */
                ; /* Error handling goes here */
        }

        /* Define columns */
        {
            SFTTREE_COLUMN_EX aCol[3] = {
              { 0, 0,                        /* Reserved */
                221,                         /* Width (in pixels) */
                ES_LEFT | SFTTREE_TOOLTIP,   /* Cell alignment */
                ES_LEFT | SFTTREE_HEADER_UP | SFTTREE_HEADER_FILTER,/* Title style */
                TEXT("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 */
                253,                         /* Width (in pixels) */
                ES_LEFT | SFTTREE_TOOLTIP,   /* Cell alignment */
                ES_LEFT | SFTTREE_HEADER_UP | SFTTREE_HEADER_FILTER,/* Title style */
                TEXT("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 */
                100,                         /* Width (in pixels) */
                ES_LEFT | SFTTREE_TOOLTIP,   /* Cell alignment */
                ES_LEFT | SFTTREE_HEADER_UP | SFTTREE_HEADER_FILTER,/* Title style */
                TEXT("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 */
              }
            };
            SftTree_SetColumnsEx(g_hwndTree, 3, aCol);/* Set column attributes */
        }

        SftTree_SetShowRowHeader(g_hwndTree, SFTTREE_ROWSTYLE_BUTTONCOUNT1);/* Row style */
        SftTree_SetRowColHeaderText(g_hwndTree, TEXT("?"));/* Row/column header text */
        SftTree_SetRowColHeaderStyle(g_hwndTree, ES_LEFT | SFTTREE_HEADER_UP);/* Row/column header style */
        SftTree_SetCharSearchMode(g_hwndTree, SFTTREE_CHARSEARCH_ALLCHARS, -1);/* Consider all characters typed */
        /* Change the default colors */
        {
            SFTTREE_COLORS Colors;
            SftTree_GetCtlColors(g_hwndTree, &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) */
            Colors.selectionInnerBorder = RGB(173,216,230);/* Selection inner border color */
            Colors.selectionFlybyInnerBorder = RGB(190,224,235);/* Selection highlight inner border color */
            Colors.nofocusInnerBorder = RGB(173,216,230);/* Selection inner border color (without input focus) */
            Colors.flybyInnerBorder = RGB(207,233,233);/* Flyby highlight inner border color */
            SftTree_SetCtlColors(g_hwndTree, &Colors);/* Set new colors */
        }


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

        {
            int index;

            index = SftTree_AddString(g_hwndTree, TEXT("In this sample, all items offer a context menu"));/* Add an item */
            index = SftTree_AddString(g_hwndTree, TEXT("The column headers also offer a context menu"));/* Add another item */
            SftTree_SetTextCol(g_hwndTree, index, 1, TEXT("2nd Column"));/* Set text in next column */
            SftTree_SetTextCol(g_hwndTree, index, 2, TEXT("3nd Column"));/* Set text in next column */

            index = SftTree_AddString(g_hwndTree, TEXT("A third item"));/* Add another item */
            SftTree_SetTextCol(g_hwndTree, index, 1, TEXT("2nd Column"));/* Set text in next column */
            SftTree_SetTextCol(g_hwndTree, index, 2, TEXT("3nd Column"));/* Set text in next column */
            index = SftTree_AddString(g_hwndTree, TEXT("The last item"));/* Add another item */
            SftTree_SetTextCol(g_hwndTree, index, 1, TEXT("2nd Column"));/* Set text in next column */
            SftTree_SetTextCol(g_hwndTree, index, 2, TEXT("3nd Column"));/* Set text in next column */

            index = SftTree_AddString(g_hwndTree, TEXT("Item A"));/* Add an item */
            index = SftTree_AddString(g_hwndTree, TEXT("Item B"));/* Add an item */
            index = SftTree_AddString(g_hwndTree, TEXT("Item C"));/* Add an 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.                           */
        SftTree_MakeColumnOptimal(g_hwndTree, -1);/* Make column widths optimal */

        /* Make row header width optimal, so text and pictures are */
        /* not clipped horizontally.                               */
        SftTree_MakeRowHeaderOptimal(g_hwndTree);/* Make row header width optimal */

        SftTree_RecalcHorizontalExtent(g_hwndTree);/* Update horizontal scroll bar */

        /* select the first item */
        SftTree_SetCurSel(g_hwndTree, 0);
        SftTree_SetCaretIndex(g_hwndTree, 0);

        return 0;
     }
    case WM_DESTROY:
        DeleteObject(m_aThreeItemPictures[0].Picture.hBitmap);/* Default item pictures */
        DeleteObject(m_aThreeItemPictures[1].Picture.hBitmap);
        DeleteObject(m_aThreeItemPictures[2].Picture.hBitmap);
        //DeleteObject(m_OtherItemPicture.Picture.hBitmap);/* Another item picture */

        if (g_hPopupMenu)
            DestroyMenu(g_hPopupMenu);

        if (g_hwndTree)
            DestroyWindow(g_hwndTree);
        PostQuitMessage(0);
        break;

    case WM_CONTEXTMENU: /* the user right-clicks on the tree control */
        HandleContextMenu(hwnd, g_hwndTree, LOWORD(lParam), HIWORD(lParam));
        break;

    case WM_SIZE: {
        int cx = LOWORD(lParam);
        int cy = HIWORD(lParam);
        SetWindowPos(g_hwndTree, NULL, 0, 0, cx, cy, SWP_NOACTIVATE | SWP_NOZORDER);
        return 0;
     }

    case WM_SETFOCUS:
        if (g_hwndTree)
            SetFocus(g_hwndTree);
        break;

    case WM_COMMAND: {
        HWND hwndCtl = (HWND) lParam;
        int id = LOWORD(wParam);
        int code = HIWORD(wParam);

        if (id >= IDM_COLUMN_ENABLE && id < IDM_COLUMN_ENABLE+50 ) {
            OnColumnEnable(g_hwndTree, id);
        } else {
            switch (id) {
            case IDC_TREE:
                switch(code) {
                case SFTTREEN_LBUTTONDBLCLK_TEXT:
                case SFTTREEN_LBUTTONDOWN_BUTTON:
                case SFTTREEN_LBUTTONDBLCLK_BUTTON: {
                    int index;
                    BOOL fExpand, fControl;
                    /* Get current position */
                    index = SftTree_GetExpandCollapseIndex(hwndCtl);/* Get caret location */
                    /* Check if item is expanded */
                    fExpand = SftTree_GetItemExpand(hwndCtl, index);
                    /* If the CONTROL key is pressed, expand all dependent levels */
                    fControl = (BOOL)(GetKeyState(VK_CONTROL)&0x8000);
                    if (fExpand)
                        SftTree_Collapse(hwndCtl, index, TRUE);
                    else
                        SftTree_Expand(hwndCtl, index, TRUE, fControl);
                    break;
                 }
                case SFTTREEN_EXPANDALL: { // expand all
                    int index;
                    index = SftTree_GetExpandCollapseIndex(hwndCtl);/* Get item to expand/collapse */
                    SftTree_Expand(hwndCtl, index, TRUE, TRUE);
                    break;
                 }
                case SFTTREEN_LBUTTONDBLCLK_COLUMNRES: {
                    /* Resize column optimally */
                    int realCol = SftTree_GetResizeColumn(g_hwndTree);
                    if (realCol >= 0) {
                        SftTree_MakeColumnOptimal(g_hwndTree, realCol);/* Make column width optimal */
                        SftTree_RecalcHorizontalExtent(g_hwndTree);/* Update horizontal scroll bar */
                    }
                    break;
                  }
                case SFTTREEN_LBUTTONDOWN_COLUMN_HEADER:
                case SFTTREEN_LBUTTONDBLCLK_COLUMN_HEADER: {
                    /* The user clicked/double-clicked the header */
                    int sortCol, sortStyle;
                    if (SftTree_GetSortColumn1(g_hwndTree, &sortCol, &sortStyle)) {/* Retrieve the current sort column */
                        BOOL ascending = (sortStyle == SFTTREE_SORT_ASC);
                        SftTree_SortColDependentsEx(g_hwndTree, -1, sortCol,
                            ascending ? Tree_SortCallbackExAscending : Tree_SortCallbackExDescending);/* Sort level 0 items using the column and order specified */
                    }
                    break;
                  }
                case SFTTREEN_LBUTTONDOWN_COLUMN_HEADERDD:
                case SFTTREEN_LBUTTONDBLCLK_COLUMN_HEADERDD: {
                    /* The user clicked/double-clicked the header dropdown/filter */
                    int col = SftTree_GetHeaderButton(g_hwndTree);
                    if (col >= 0) {
                        RECT rect;
                        if (SftTree_GetDisplayHeaderDropDownRect(g_hwndTree, col, &rect)) {
                            MapWindowPoints(g_hwndTree, GetDesktopWindow(), (LPPOINT)&rect, 2);
                            ShowHeaderMenu(hwnd, g_hwndTree, rect.left, rect.bottom);
                        }
                    }
                    break;
                  }
                }
                break;

            case IDM_COLUMN_ENABLE_ALL:
                OnColumnEnableAll(g_hwndTree);
                break;
            case ID_POPUP_ITEM:
            case ID_POPUP_EDIT:
            case ID_POPUP_INSERT:
            case ID_POPUP_APPEND:
            case ID_POPUP_DELETE:
                MessageBox(NULL, TEXT("This sample doesn't implement any actions for the item menu."),
                            TEXT("SftTree/DLL Sample"), MB_OK|MB_TASKMODAL);
                break;

            case IDM_EXIT:                  // Menu command, Exit
                DestroyWindow(hwnd);
                break;
            }
        }
        break;
     }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

/**********************************************************************/
/*                              WinMain                               */
/**********************************************************************/

int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int cmdShow)
{
    MSG msg;
    HWND hwndMain;

    // Initialize
    g_hInst = hinst;

    if (!hinstPrev) {
        WNDCLASS cls;

        cls.hCursor         = LoadCursor(NULL, IDC_ARROW);
        cls.hIcon           = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON1));
        cls.lpszMenuName    = MAKEINTRESOURCE(IDR_MAINMENU);
        cls.hInstance       = g_hInst;
        cls.lpszClassName   = TEXT("SoftelSampleFrame");
        cls.hbrBackground   = (HBRUSH)(COLOR_WINDOW+1);
        cls.lpfnWndProc     = (WNDPROC) SDI_WndProc;
        cls.style           = CS_DBLCLKS;
        cls.cbWndExtra      = 0;
        cls.cbClsExtra      = 0;
        if (!RegisterClass(&cls))
            return 0;
    }

    SftTree_RegisterApp(hinst);   /* Register with SftTree/DLL */

    // Initialize, run, and terminate the application
    hwndMain = CreateWindowEx(
            0L,
            TEXT("SoftelSampleFrame"),
            TEXT("Softel vdm, Inc. - ContextMenu Sample"),
            WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
            CW_USEDEFAULT, CW_USEDEFAULT,
            CW_USEDEFAULT, CW_USEDEFAULT,
            NULL,
            NULL,
            g_hInst,
            NULL);
    if (!hwndMain)
        return 0;

    ShowWindow(hwndMain, cmdShow);
    UpdateWindow(hwndMain);

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    SftTree_UnregisterApp(hinst); /* Unregister from SftTree/DLL */

    return (int) msg.wParam;
}