/****************************************************************************/
/* SftTree/DLL 7.0 - Tree Control for C/C++ */
/* SftTree/DLL 7.0 - Itanium Edition */
/* SftTree/DLL 7.0 - x64 Edition */
/* SftTree/DLL 7.0 - Windows Mobile Edition */
/* Copyright (C) 1995, 2012 Softel vdm, Inc. All Rights Reserved. */
/****************************************************************************/
#include
#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
SftTree_GetHeaderRect(hwndTree, -1, &rect);
if (PtInRect(&rect, pt)) {
// in header
ShowHeaderMenu(hwndParent, hwndTree, x, y);
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;
}
}
/**********************************************************************/
/* 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_SetOpenEnded(g_hwndTree, TRUE);/* Last column width */
SftTree_SetShowHeaderButtons(g_hwndTree, TRUE);/* Show column header as buttons */
/* 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, /* Title style */
TEXT("First Column"), /* 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 */
},
{ 0, 0, /* Reserved */
253, /* Width (in pixels) */
ES_LEFT | SFTTREE_TOOLTIP, /* Cell alignment */
ES_LEFT | SFTTREE_HEADER_UP, /* Title style */
TEXT("Second Column"), /* 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) */
0, /* Column flag */
0, /* Minimum column width */
},
{ 0, 0, /* Reserved */
100, /* Width (in pixels) */
ES_LEFT | SFTTREE_TOOLTIP, /* Cell alignment */
ES_LEFT | SFTTREE_HEADER_UP, /* Title style */
TEXT("Third Column"), /* 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) */
2, /* Display column number (display position) */
0, /* Column flag */
0, /* Minimum column width */
}
};
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) */
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_SetItemLevel(g_hwndTree, index, 1);/* change level */
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_SetItemLevel(g_hwndTree, index, 2);/* change level */
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_SetItemLevel(g_hwndTree, index, 1);/* change level */
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 */
}
/*------------------------------------------------------------------------------*/
/* 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 */
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:
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;
}
}
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. Try the column headers instead."),
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;
}
sample_c_contextmenu.htmlSftTreeDLL70_sample_c_contextmenu.htmlFeedback / comments / error reports for this topic
© 2015 - Softel vdm, Inc. - www.softelvdm.com