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 illustrates cell editing using an edit control and a combo box, with cell navigation and restricted cells.
The source code is located at C:\Program Files (x86)\Softelvdm\SftTree DLL 7.5\Samples\C\CellEditing\CellEditing.c or C:\Program Files\Softelvdm\SftTree DLL 7.5\Samples\C\CellEditing\CellEditing.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 IDC_EDIT 101 // Control ID for the edit control #define IDC_COMBO 102 // Control ID for the edit control HINSTANCE g_hInst; // App Instance Handle HWND g_hwndTree; /* Tree control */ // 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 */ HBITMAP m_hCellBitmap; /* A cell bitmap */ SFT_PICTURE m_RowColHeaderPicture; /* Row/column picture */ /**********************************************************************/ /* Tree Edit Routines */ /**********************************************************************/ int m_editIndex; /* Index of (last) item being edited */ int m_editCol; /* Column # being edited */ HWND m_hwndEdit; /* Edit control used for editing */ HWND m_hwndCombo; /* Combo box control used for editing */ BOOL _inline CellEditing() { return m_hwndEdit || m_hwndCombo; } // returns True if we're still editing /* Start editing in response to a */ /* SFTTREEN_LBUTTONDOWN_TEXT notification. */ /* Edit a specific cell. */ static void StartEdit(int index, int col) { TCHAR szBuffer[100]; RECT rect; int height; HWND EditParent; HFONT hFont; SFTTREE_CELLINFOPARM CellInfo; /* Make the cell completely visible */ SftTree_MakeCellVisible(g_hwndTree, index, col); /* Get the location */ if (!SftTree_GetDisplayCellRect(g_hwndTree, index, col, TRUE, &rect, NULL)) return; if (SftTree_GetItemEditIgnore(g_hwndTree, index)) return; // this item can't be edited CellInfo.version = 7; CellInfo.index = index; CellInfo.iCol = col; SftTree_GetCellInfo(g_hwndTree, &CellInfo); if (CellInfo.Cell.flag2 & SFTTREECELL_EDITIGNORE) return; // this item can't be edited m_editIndex = index; /* save position */ m_editCol = col; SftTree_SetCurSel(g_hwndTree, index); // <<<< added: selection follows item being edited SftTree_SetCaretIndex(g_hwndTree, index); // <<<< added: selection follows item being edited /* Change selection style to not shown anything */ SftTree_SetNoFocusStyle(g_hwndTree, SFTTREE_NOFOCUS_NOTHING); /* Copy the text found in the tree control */ SftTree_GetTextCol(g_hwndTree, m_editIndex, m_editCol, szBuffer); SftTree_AdjustCellEditRect(g_hwndTree, m_editIndex, m_editCol, &rect); EditParent = SftTree_GetCellEditWindow(g_hwndTree, m_editIndex, m_editCol); // based on font height, get best height for the control used for cell editing hFont = (HFONT) SendMessage(g_hwndTree, WM_GETFONT, 0, 0); { int diff; TEXTMETRIC tm; HDC hDC = GetDC(NULL); hFont = (HFONT)SelectObject(hDC, hFont); GetTextMetrics(hDC, &tm); // Get Font Information hFont = SelectObject(hDC, hFont); ReleaseDC(NULL, hDC); diff = (tm.tmHeight + 5) - (rect.bottom-rect.top); InflateRect(&rect, 0, (diff+1)/2); height = rect.bottom-rect.top; } if (col != 1) { /* Create the edit control.*/ /* Based on the tree control attributes and your preference, you may */ /* have to adjust the rectangle used for the edit control. */ m_hwndEdit = CreateWindow(TEXT("EDIT"), szBuffer,/* Class, Title */ WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL, /* Styles */ rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, EditParent, /* Tree control */ (HMENU) IDC_EDIT, /* <-- provide unique ID */ g_hInst, /* <-- provide instance handle */ NULL); if (!m_hwndEdit) /* Failed */ return; /* Set some edit control attributes */ /* Set the font defined for cell editing */ SendMessage(m_hwndEdit, WM_SETFONT, (WPARAM)hFont, 0L); /* Select all text in the edit control and display it */ SendMessage(m_hwndEdit, EM_LIMITTEXT, 0, 80); SendMessage(m_hwndEdit, EM_SETSEL, 0, -1L); ShowWindow(m_hwndEdit, SW_SHOW); SetFocus(m_hwndEdit); /* Set input focus to the control */ } else { /* Create the combo box */ m_hwndCombo = CreateWindow(TEXT("COMBOBOX"), TEXT(""),/* Class, Title */ WS_CHILD|WS_BORDER|WS_VSCROLL|CBS_DROPDOWN|CBS_AUTOHSCROLL, /* Styles */ rect.left, rect.top, rect.right-rect.left, (rect.bottom-rect.top) * 8, EditParent, /* Tree control */ (HMENU) IDC_COMBO, /* <-- provide unique ID */ g_hInst, /* <-- provide instance handle */ NULL); if (!m_hwndCombo) /* Failed */ return; /* Set the font defined for cell editing */ SendMessage(m_hwndCombo, WM_SETFONT, (WPARAM)hFont, 0L); // Add possible selections SendMessage(m_hwndCombo, CB_ADDSTRING, 0, (LPARAM)TEXT("Selection 1")); SendMessage(m_hwndCombo, CB_ADDSTRING, 0, (LPARAM)TEXT("Selection 2")); SendMessage(m_hwndCombo, CB_ADDSTRING, 0, (LPARAM)TEXT("Selection 3")); SetWindowText(m_hwndCombo, szBuffer); SendMessage(m_hwndCombo, CB_LIMITTEXT, 0, 80); SendMessage(m_hwndCombo, CB_SETITEMHEIGHT, -1, rect.bottom-rect.top-5); ShowWindow(m_hwndCombo, SW_SHOW); SetFocus(m_hwndCombo); /* Set input focus to the control */ SendMessage(m_hwndCombo, CB_SHOWDROPDOWN, TRUE, 0); } // The following has been added to support key handling while cell editing // It is used to define keys to be intercepted { BYTE KeyTable[256]; SftTree_GetKeyHandling(g_hwndTree, KeyTable, NULL, NULL); KeyTable[VK_TAB] = (SFTTREE_HANDLEPURE|SFTTREE_HANDLESHIFT|SFTTREE_HANDLECTRL);// handle Tab key KeyTable[VK_RETURN] = (SFTTREE_HANDLEPURE|SFTTREE_HANDLESHIFT|SFTTREE_HANDLECTRL);// handle Return key KeyTable[VK_HOME] = (SFTTREE_HANDLECTRL);// handle Control+Home key KeyTable[VK_END] = (SFTTREE_HANDLECTRL);// handle Control+End key if (m_hwndCombo) { KeyTable[VK_UP] = 0; // don't handle Up arrow key KeyTable[VK_DOWN] = 0; // don't handle Down arrow key } else { KeyTable[VK_UP] = (SFTTREE_HANDLEPURE);// handle Up arrow key KeyTable[VK_DOWN] = (SFTTREE_HANDLEPURE);// handle Down arrow key } SftTree_SetKeyHandling(g_hwndTree, KeyTable); } UpdateWindow(g_hwndTree); } /* Quit editing in response to a SFTTREEN_QUITEDIT */ /* notification. */ static void QuitEdit(void) { /* If the control has the focus, set the focus back to the */ /* tree control after destroying the control */ BOOL fHadFocus = (GetFocus() == m_hwndEdit || GetFocus() == m_hwndCombo); if (m_hwndEdit) { DestroyWindow(m_hwndEdit); m_hwndEdit = NULL; } else if (m_hwndCombo) { DestroyWindow(m_hwndCombo); m_hwndCombo = NULL; } /* Restore nofocus display method */ SftTree_SetNoFocusStyle(g_hwndTree, SFTTREE_NOFOCUS_KEEPSEL); if (fHadFocus) SetFocus(g_hwndTree); /* Back to tree control */ } /* Validate edit data in response to a */ /* SFTTREEN_VALIDATEEDIT notification. */ static void ValidateEdit(void) { TCHAR szBuffer[100]; if (m_hwndEdit) { /* Get the text from the edit control */ GetWindowText(m_hwndEdit, szBuffer, sizeof(szBuffer)); /* Validate the data */ if (lstrcmp(TEXT(""), szBuffer) == 0) { MessageBox(NULL, TEXT("Just to demonstrate data input validation, this example rejects empty cells. Please enter some data."), TEXT("SftTree/DLL"), MB_OK|MB_TASKMODAL|MB_ICONSTOP); SetFocus(m_hwndEdit); return; } else { DestroyWindow(m_hwndEdit); m_hwndEdit = NULL; } } else { /* Get the text from the combo control */ GetWindowText(m_hwndCombo, szBuffer, sizeof(szBuffer)); /* Validate the data */ if (lstrcmp(TEXT(""), szBuffer) == 0) { MessageBox(NULL, TEXT("Just to demonstrate data input validation, this example rejects empty cells. Please enter some data."), TEXT("SftTree/DLL"), MB_OK|MB_TASKMODAL|MB_ICONSTOP); SetFocus(m_hwndCombo); return; } else { DestroyWindow(m_hwndCombo); m_hwndCombo = NULL; } } /* Save the data in the tree control */ SftTree_SetTextCol(g_hwndTree, m_editIndex, m_editCol, szBuffer); /* Restore nofocus display method */ SftTree_SetNoFocusStyle(g_hwndTree, SFTTREE_NOFOCUS_KEEPSEL); } void CellNavigation(TCHAR vKey, BYTE vMask) { // Here we handle special keys to implement cell editing with // cell navigation. Cell navigation is not automatic, but using this // sample code, a sophisticated editing scheme can be easily implemented, // even with skipped columns, hidden columns, collapsed items, etc. // Keep in mind that col is a REAL column number, but we have // to deal in DISPLAY columns as the user may have reordered the // columns. When using cell navigation, we want to move through the // displayed columns // Please note that cell merging is not supported. int index = m_editIndex, col = m_editCol; int dispCol, firstDispCol, lastDispCol; LPSFTTREE_COLUMN_EX lpCol; int nCols; int lastShown = SftTree_GetPrevShown(g_hwndTree, -1); // get general information about tree control and columns nCols = SftTree_GetColumnsEx(g_hwndTree, &lpCol);/* Get column attributes */ dispCol = SftTree_GetDisplayColumn(g_hwndTree, col); firstDispCol = SftTree_GetFirstDisplayColumn(g_hwndTree); lastDispCol = SftTree_GetLastDisplayColumn(g_hwndTree); if (vKey == VK_HOME && (vMask & SFTTREE_HANDLECTRL)) { // Control+Home index = 0; dispCol = firstDispCol; vKey = VK_RIGHT; // if index/dispCol can't be edited, search a cell in this direction: } else if (vKey == VK_END && (vMask & SFTTREE_HANDLECTRL)) { // Control+End index = SftTree_GetPrevShown(g_hwndTree, -1); dispCol = lastDispCol; vKey = VK_LEFT; // if index/dispCol can't be edited, search a cell in this direction: } else if ((vKey == VK_LEFT && (vMask & SFTTREE_HANDLEPURE)) || (vKey == VK_TAB && (vMask & SFTTREE_HANDLESHIFT))) { // Left Arrow or Shift+Tab dispCol--; vKey = VK_LEFT; // if index/dispCol can't be edited, search a cell in this direction: } else if ((vKey == VK_RIGHT || vKey == VK_TAB) && (vMask & SFTTREE_HANDLEPURE)) { // Right Arrow or Tab dispCol++; vKey = VK_RIGHT; // if index/dispCol can't be edited, search a cell in this direction: } else if (vKey == VK_RETURN && (vMask & SFTTREE_HANDLEPURE)) { // Return dispCol++; vKey = VK_RIGHT; // if index/dispCol can't be edited, search a cell in this direction: } else if (vKey == VK_UP && (vMask & SFTTREE_HANDLEPURE)) { // Up arrow index--; } else if (vKey == VK_DOWN && (vMask & SFTTREE_HANDLEPURE)) { // Down arrow index++; } else return; // this key is not handled // index, dispCol has possible cell coordinates. If this cell can't be // edited, proceed in vKey direction (VK_UP,VK_LEFT,VK_DOWN,VK_RIGHT only) // until a suitable cell is found or until we hit m_editIndex, m_editCol. for ( ; ; ) { // position to a valid cell if (dispCol < firstDispCol) { index = SftTree_GetPrevShown(g_hwndTree, index);// try previous item dispCol = lastDispCol; } if (dispCol > lastDispCol) { index = SftTree_GetNextShown(g_hwndTree, index);// try next item if (index < 0) index = 0; dispCol = firstDispCol; } if (index < 0) index = lastShown; if (index > lastShown) index = 0; col = SftTree_GetRealColumn(g_hwndTree, dispCol); // make sure the item is shown if (SftTree_GetItemShown(g_hwndTree, index)) { // make sure the column is really displayed if (lpCol[col].width > 0) { // back at m_editIndex, m_editCol? if (m_editIndex == index && m_editCol == col) { StartEdit(index, col); return; } // check if item ignored if (!SftTree_GetItemEditIgnore(g_hwndTree, index)) { // item not ignored // check if cell ignored SFTTREE_CELLINFOPARM CellInfo; CellInfo.version = 7; CellInfo.index = index; CellInfo.iCol = col; SftTree_GetCellInfo(g_hwndTree, &CellInfo); if ((CellInfo.Cell.flag2 & SFTTREECELL_EDITIGNORE) == 0) { // cell not ignored StartEdit(index, col); return; } } } } // next cell if (vKey == VK_LEFT) { --dispCol; } else if (vKey == VK_RIGHT) { ++dispCol; } else if (vKey == VK_UP) { --index; } else if (vKey == VK_DOWN) { ++index; } } } /**********************************************************************/ /* Frame Window Proc */ /**********************************************************************/ LRESULT CALLBACK SDI_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_CREATE: { int i; 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 */ /* Register the cell picture size. All cell pictures used */ /* must be the same size. Only one picture needs to be */ /* registered, even if several are used. */ { SFTTREE_CELLINFOPARM CellInfo; CellInfo.version = 7; CellInfo.index = -1; /* Registering picture size */ m_hCellBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_SMILE1));/* Cell picture */ Sft_InitPicture(&CellInfo.Cell.CellPicture1); Sft_SetPictureBitmap(&CellInfo.Cell.CellPicture1, m_hCellBitmap); SftTree_SetCellInfo(g_hwndTree, &CellInfo);/* Register use of cell pictures */ /* Set individual cell pictures using this sample code: */ // SFTTREE_CELLINFOPARM CellInfo; // CellInfo.version = 7; // CellInfo.index = cell_index_to_change; // CellInfo.iCol = column_number_to_change; // SftTree_GetCellInfo(g_hwndTree, &CellInfo); // /* m_hCellBitmap = LoadBitmap(app_instance, MAKEINTRESOURCE(IDB_your_bitmap)); *//* Cell bitmap */ // Sft_SetPictureBitmap(&CellInfo.Cell.CellPicture1, m_hCellBitmap); // CellInfo.Cell.flag = SFTTREE_BMP_RIGHT; // SftTree_SetCellInfo(g_hwndTree, &CellInfo); } 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 | SFTTREE_SELECTION_OUTLINE);/* Select first cell only using outline */ SftTree_SetSelectionArea(g_hwndTree, SFTTREE_SELECTIONAREA_ALLCELLS);/* Selection changes by clicking on an item's cells */ SftTree_SetUpdateCaretExpandCollapse(g_hwndTree, FALSE);/* don't update caret location when expand/collapse button clicked */ SftTree_SetFlyby(g_hwndTree, TRUE); /* Flyby highlighting */ 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 */ Sft_InitPicture(&m_RowColHeaderPicture); Sft_SetPictureBitmap(&m_RowColHeaderPicture, LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_SMILE1)));/* Row/column header picture */ SftTree_SetRowColHeaderPicture(g_hwndTree, &m_RowColHeaderPicture);/* Row/column picture */ SftTree_SetRowColHeaderPictureStyle(g_hwndTree, SFTTREE_BMP_RIGHT);/* Row/column picture alignment */ SftTree_SetCharSearchMode(g_hwndTree, SFTTREE_CHARSEARCH_ALLCHARSWRAP2, -1);/* Consider all characters typed, find next item, wrap around, don't expand */ /* 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("Click on a cell to edit"));/* Add an item */ SftTree_SetTextCol(g_hwndTree, index, 1, TEXT("Use Tab/Return keys"));/* Set text in next column */ SftTree_SetTextCol(g_hwndTree, index, 2, TEXT("Use arrow keys"));/* Set text in next column */ index = SftTree_AddString(g_hwndTree, TEXT("This sample supports cell navigation"));/* Add an item */ SftTree_SetTextCol(g_hwndTree, index, 1, TEXT("Ctrl+Home and Ctrl+End"));/* Set text in next column */ } for (i = 0 ; i < 50 ; ++i) { int index; index = SftTree_AddString(g_hwndTree, TEXT("An item"));/* Add an item */ SftTree_SetTextCol(g_hwndTree, index, 1, TEXT("2nd Column"));/* Set text in next column */ SftTree_SetTextCol(g_hwndTree, index, 2, TEXT("3rd Column"));/* Set text in next column */ index = SftTree_AddString(g_hwndTree, TEXT("Another 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("3rd Column"));/* Set text in next column */ SftTree_SetItemLevel(g_hwndTree, index, 1);/* change level */ index = SftTree_AddString(g_hwndTree, TEXT("This item can't be edited"));/* Add another item */ SftTree_SetItemEditIgnore(g_hwndTree, index, TRUE); SftTree_SetItemLevel(g_hwndTree, index, 2);/* change level */ SftTree_SetTextCol(g_hwndTree, index, 1, TEXT("2nd Column (can't edit this item)"));/* Set text in next column */ SftTree_SetTextCol(g_hwndTree, index, 2, TEXT("3rd Column (can't edit this item)"));/* Set text in next column */ index = SftTree_AddString(g_hwndTree, TEXT("A fourth item"));/* Add another item */ SftTree_SetItemLevel(g_hwndTree, index, 1);/* change level */ SftTree_SetTextCol(g_hwndTree, index, 1, TEXT("This cell can't be edited"));/* Set text in next column */ { SFTTREE_CELLINFOPARM CellInfo; CellInfo.version = 7; CellInfo.index = index; CellInfo.iCol = 1; SftTree_GetCellInfo(g_hwndTree, &CellInfo); CellInfo.Cell.flag2 |= SFTTREECELL_EDITIGNORE; // can't edit this column SftTree_SetCellInfo(g_hwndTree, &CellInfo); } SftTree_SetTextCol(g_hwndTree, index, 2, TEXT("3rd Column"));/* Set text in next column */ /* Set a cell bitmap */ { SFTTREE_CELLINFOPARM CellInfo; CellInfo.version = 7; CellInfo.index = index; CellInfo.iCol = 1; SftTree_GetCellInfo(g_hwndTree, &CellInfo); Sft_SetPictureBitmap(&CellInfo.Cell.CellPicture1, m_hCellBitmap); SftTree_SetCellInfo(g_hwndTree, &CellInfo); } } /*------------------------------------------------------------------------------*/ /* 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); /* select the first item */ SftTree_SetCaretIndex(g_hwndTree, 0); /* and make it current */ return 0; } case WM_DESTROY: QuitEdit(); 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 */ DeleteObject(m_hCellBitmap); /* A cell picture */ DeleteObject(m_RowColHeaderPicture.Picture.hBitmap);/* Row/column picture */ if (g_hwndTree) DestroyWindow(g_hwndTree); PostQuitMessage(0); 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); 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_TEXT: { /* Edit the current cell */ /* Get cell to edit (honors cell merging) */ int index, col; index = SftTree_GetCaretIndex(g_hwndTree);/* Get item index */ col = SftTree_GetCaretColumn(g_hwndTree);/* Get column number */ StartEdit(index, col); break; } case SFTTREEN_QUITEDIT: /* Abandon editing */ QuitEdit(); break; case SFTTREEN_VALIDATEEDIT: /* Validate input data */ ValidateEdit(); break; // The following has been added to support key handling while cell editing case SFTTREEN_KEYINTERCEPTED: { TCHAR vKey; BYTE vMask; SftTree_GetKeyHandling(g_hwndTree, NULL, &vKey, &vMask); switch (vKey) { case VK_TAB: // Tab key case VK_RETURN: // Return key case VK_UP: // Up arrow key case VK_DOWN: // Down arrow key case VK_HOME: // Home key case VK_END: // End key ValidateEdit(); // validate the contents if (CellEditing()) // we're still editing (validation failed) break; CellNavigation(vKey, vMask); break; } break; } } break; case 1000: // Menu command, Exit DestroyWindow(hwnd); break; case IDCANCEL: // ESC has hit while editing QuitEdit(); 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. - CellEditing 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; }