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 drag & drop within and between tree controls.
The source code is located at C:\Program Files (x86)\Softelvdm\SftTree DLL 7.5\Samples\C\DragDrop\DragDrop.c or C:\Program Files\Softelvdm\SftTree DLL 7.5\Samples\C\DragDrop\DragDrop.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 <stdlib.h> #include "SftTree.h" /* SftTree/DLL Header File */ #include "resource.h" // resource IDs /**********************************************************************/ /* Globals */ /**********************************************************************/ HINSTANCE g_hInst; // App Instance Handle HWND m_hwndLeftTree; /* Tree control */ HWND m_hwndRightTree; /* Tree control */ HWND m_hwndLastTarget = NULL; /* Last drop target */ SFT_PICTURE m_aThreeItemPictures[3]; /* Three default item pictures, see SetPictures in online help */ HBITMAP m_hBgBitmap; /* Background bitmap */ /**********************************************************************/ /* Center the main dialog */ /**********************************************************************/ static void CenterWindow(HWND hwnd) { RECT rc; RECT rcOwner; int x, y; GetWindowRect(hwnd, &rc); GetWindowRect(GetDesktopWindow(), &rcOwner); // Calculate the starting x,y for the new window so that it would be centered. x = rcOwner.left + (((rcOwner.right - rcOwner.left) - (rc.right - rc.left)) / 2); y = rcOwner.top + (((rcOwner.bottom - rcOwner.top) - (rc.bottom - rc.top)) / 2); SetWindowPos(hwnd, NULL, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); } /**********************************************************************/ /* Left Tree Control Handling */ /**********************************************************************/ static void DraggingLeft() { /* Drag & drop in progress, which was started on the left side tree */ LPSFTTREE_DRAGINFO lpInfo; lpInfo = SftTree_GetDragInfo(m_hwndLeftTree); if (lpInfo->hwnd != m_hwndLeftTree) { // The target is another window // clear old drop target if (m_hwndLastTarget) { SftTree_SetDropHighlight(m_hwndLastTarget, -1, FALSE); SftTree_StopAutoExpandTimer(m_hwndLastTarget); } m_hwndLastTarget = NULL; // the target is another control, we have to set the cursor and // also update the drop target // In this example the "other" control could be the right tree control if (lpInfo->hwnd == m_hwndRightTree) { // target is right tree POINT pt; int index; // set the drop OK cursor lpInfo->fDropOK = TRUE; lpInfo->hCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_DRAG)); // update the drop target in the right tree pt = lpInfo->ptDrag; MapWindowPoints(HWND_DESKTOP, m_hwndRightTree, &pt, 1); index = SftTree_CalcIndexFromPointEx(m_hwndRightTree, &pt); SftTree_SetDropHighlight(m_hwndRightTree, index, TRUE); SftTree_StartAutoExpandTimer(m_hwndRightTree, index, FALSE, 0); // remember who is the drop target m_hwndLastTarget = m_hwndRightTree; } } else { // left side tree is the drop target // clear old drop target if different if (m_hwndLastTarget && m_hwndLastTarget != m_hwndLeftTree) { SftTree_SetDropHighlight(m_hwndLastTarget, -1, FALSE); SftTree_StopAutoExpandTimer(m_hwndLastTarget); } m_hwndLastTarget = m_hwndLeftTree; SftTree_StartAutoExpandTimer(m_hwndLastTarget, lpInfo->index, FALSE, 0); } } static void EndDragLeft() { /* The user dropped something */ LPSFTTREE_DRAGINFO lpInfo; int index; TCHAR szBuffer[80]; LPCTSTR lpszText; lpInfo = SftTree_GetDragInfo(m_hwndLeftTree); if (lpInfo->hwnd != m_hwndLeftTree) { // The target is another window // In this example the "other" control could be the right tree control if (lpInfo->hwnd == m_hwndRightTree) { // target is left tree index = SftTree_GetDropHighlight(m_hwndRightTree); lpszText = TEXT("The drop target is item %d in the right tree control"); } else { index = -1; lpszText = TEXT("There is no valid drop target"); } } else { // target is the right tree control index = SftTree_GetDropHighlight(m_hwndLeftTree); lpszText = TEXT("The drop target is item %d in the left tree control"); } // always clear drop targets. If you forget, or do it too late, // the vertical scrolling may still be active if (m_hwndLastTarget) { SftTree_SetDropHighlight(m_hwndLastTarget, -1, FALSE); SftTree_StopAutoExpandTimer(m_hwndLastTarget); } m_hwndLastTarget = NULL; wsprintf(szBuffer, lpszText, index); MessageBox(NULL, szBuffer, TEXT("SftTree/DLL"), MB_OK|MB_TASKMODAL); } /**********************************************************************/ /* Right Tree Control Handling */ /**********************************************************************/ static void DraggingRight() { /* Drag & drop in progress, which was started on the right side tree */ LPSFTTREE_DRAGINFO lpInfo; lpInfo = SftTree_GetDragInfo(m_hwndRightTree); if (lpInfo->hwnd != m_hwndRightTree) { // The target is another window // clear old drop target if (m_hwndLastTarget) { SftTree_SetDropHighlight(m_hwndLastTarget, -1, FALSE); SftTree_StopAutoExpandTimer(m_hwndLastTarget); } m_hwndLastTarget = NULL; // the target is another control, we have to set the cursor and // also update the drop target // In this example the "other" control could be the left tree control if (lpInfo->hwnd == m_hwndLeftTree) { // target is left tree POINT pt; int index; // set the drop OK cursor lpInfo->fDropOK = TRUE; lpInfo->hCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_DRAG)); // update the drop target in the left tree pt = lpInfo->ptDrag; MapWindowPoints(HWND_DESKTOP, m_hwndLeftTree, &pt, 1); index = SftTree_CalcIndexFromPointEx(m_hwndLeftTree, &pt); SftTree_SetDropHighlight(m_hwndLeftTree, index, TRUE); SftTree_StartAutoExpandTimer(m_hwndLeftTree, index, FALSE, 0); // remember who is the drop target m_hwndLastTarget = m_hwndLeftTree; } } else { // right side tree is the drop target // clear old drop target if different if (m_hwndLastTarget && m_hwndLastTarget != m_hwndRightTree) { SftTree_SetDropHighlight(m_hwndLastTarget, -1, FALSE); SftTree_StopAutoExpandTimer(m_hwndLastTarget); } m_hwndLastTarget = m_hwndRightTree; SftTree_StartAutoExpandTimer(m_hwndLastTarget, lpInfo->index, FALSE, 0); } } static void EndDragRight() { /* The user dropped something */ LPSFTTREE_DRAGINFO lpInfo; int index; TCHAR szBuffer[80]; LPCTSTR lpszText; lpInfo = SftTree_GetDragInfo(m_hwndRightTree); if (lpInfo->hwnd != m_hwndRightTree) { // The target is another window // In this example the "other" control could be the left tree control if (lpInfo->hwnd == m_hwndLeftTree) { // target is left tree index = SftTree_GetDropHighlight(m_hwndLeftTree); lpszText = TEXT("The drop target is item %d in the left tree control"); } else { index = -1; lpszText = TEXT("There is no valid drop target"); } } else { // target is the right tree control index = SftTree_GetDropHighlight(m_hwndRightTree); lpszText = TEXT("The drop target is item %d in the right tree control"); } // always clear drop targets. If you forget, or do it too late, // the vertical scrolling may still be active if (m_hwndLastTarget) { SftTree_SetDropHighlight(m_hwndLastTarget, -1, FALSE); SftTree_StopAutoExpandTimer(m_hwndLastTarget); } m_hwndLastTarget = NULL; wsprintf(szBuffer, lpszText, index); MessageBox(NULL, szBuffer, TEXT("SftTree/DLL"), MB_OK|MB_TASKMODAL); } /**********************************************************************/ /* Frame Dialog Proc */ /**********************************************************************/ BOOL CALLBACK MainDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { int index; // Center this dialog CenterWindow(hwndDlg); // Set application icon SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON1))); // LEFT SIDE TREE CONTROL m_hwndLeftTree = GetDlgItem(hwndDlg, IDC_LEFTTREE); /* Define the background bitmap. */ m_hBgBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BACKGROUND));/* Load a background bitmap */ SftTree_SetBackgroundBitmap(m_hwndLeftTree, m_hBgBitmap, 0, 0, 0);/* Define the background bitmap */ /* 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(m_hwndLeftTree, m_aThreeItemPictures);/* Use item picture */ SftTree_SetItemBitmapAlign(m_hwndLeftTree, TRUE);/* Align item bitmaps */ SftTree_SetTreeLineStyle(m_hwndLeftTree, SFTTREE_TREELINE_DOT0);/* Dotted tree lines (incl. level 0) */ SftTree_SetShowButtons(m_hwndLeftTree, TRUE);/* Expand/collapse buttons (level 1..n) */ SftTree_SetShowButton0(m_hwndLeftTree, TRUE);/* Show expand/collapse buttons (level 0) */ SftTree_SetButtons(m_hwndLeftTree, SFTTREE_BUTTON_SIMPLE);/* Button style */ SftTree_SetShowTruncated(m_hwndLeftTree, TRUE);/* Show ... if truncated */ SftTree_SetSelectionStyle(m_hwndLeftTree, SFTTREE_SELECTION_CELL1);/* Select first cell only */ SftTree_SetSelectionArea(m_hwndLeftTree, SFTTREE_SELECTIONAREA_ALL);/* Selection changes by clicking anywhere on an item */ SftTree_SetFlyby(m_hwndLeftTree, TRUE);/* Flyby highlighting */ SftTree_SetScrollTips(m_hwndLeftTree, TRUE);/* Show Scrolltips */ SftTree_SetInheritBgColor(m_hwndLeftTree, TRUE);/* Inherit background color of first cell */ SftTree_SetOpenEnded(m_hwndLeftTree, TRUE);/* Last column width */ /* Define columns */ { SFTTREE_COLUMN_EX aCol[1] = { { 0, 0, /* Reserved */ 49, /* Width (in pixels) */ ES_LEFT, /* Cell alignment */ ES_LEFT, /* Title style */ TEXT("Title"), /* Column header title */ NULL, NULL, /* Reserved field and bitmap handle */ SFTTREE_BMP_RIGHT, /* Bitmap 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 */ } }; SftTree_SetColumnsEx(m_hwndLeftTree, 1, aCol);/* Set column attributes */ } SftTree_SetShowRowHeader(m_hwndLeftTree, SFTTREE_ROWSTYLE_BUTTONCOUNT0);/* Row style */ SftTree_SetRowHeaderStyle(m_hwndLeftTree, ES_LEFT | SFTTREE_HEADER_UP);/* Row header style */ SftTree_SetDragBitmaps(m_hwndLeftTree, TRUE);/* Allow drag & drop from item, label pictures */ SftTree_SetDragType(m_hwndLeftTree, SFTTREE_DRAG_PIXELIMM);/* Select and move by a number of pixels to start drag */ SftTree_SetDropHighlightStyle(m_hwndLeftTree, SFTTREE_DROPHIGHLIGHT_BETWEEN);/* Draw line to represent drop target */ SftTree_SetCharSearchMode(m_hwndLeftTree, SFTTREE_CHARSEARCH_ALLCHARS, -1);/* Consider all characters typed */ /* Change the default colors */ { SFTTREE_COLORS Colors; SftTree_GetCtlColors(m_hwndLeftTree, &Colors);/* Get current color settings */ Colors.colorSelBgNoFocus = COLOR_BTNFACE | 0x80000000L;/* Selection background color (no input focus) */ Colors.colorSelFgNoFocus = COLOR_BTNTEXT | 0x80000000L;/* Selection foreground color (no input focus) */ SftTree_SetCtlColors(m_hwndLeftTree, &Colors);/* Set new colors */ } // Add a few items for (index = 3 ; index <= 30 ; ++index) { TCHAR szBuffer[80]; int i; wsprintf(szBuffer, TEXT("Item %d"), index-3); i = SftTree_AddString(m_hwndLeftTree, szBuffer); SftTree_SetItemLevel(m_hwndLeftTree, i, abs(3 - (index % 6))); } /* Make row header width optimal, so text and bitmaps are */ /* not clipped horizontally. */ SftTree_MakeRowHeaderOptimal(m_hwndLeftTree);/* Make row header width optimal */ SftTree_RecalcHorizontalExtent(m_hwndLeftTree);/* Update horizontal scroll bar */ // RIGHT SIDE TREE CONTROL m_hwndRightTree = GetDlgItem(hwndDlg, IDC_RIGHTTREE); SftTree_SetTreeLineStyle(m_hwndRightTree, SFTTREE_TREELINE_AUTOMATIC0);/* Dotted or invisible tree lines (incl. level 0) */ SftTree_SetShowButtons(m_hwndRightTree, TRUE);/* Expand/collapse buttons (level 1..n) */ SftTree_SetShowButton0(m_hwndRightTree, TRUE);/* Show expand/collapse buttons (level 0) */ SftTree_SetButtons(m_hwndRightTree, SFTTREE_BUTTON_AUTOMATIC3);/* Automatic button style 3 */ SftTree_SetShowTruncated(m_hwndRightTree, TRUE);/* Show ... if truncated */ SftTree_SetShowFocus(m_hwndRightTree, FALSE);/* Don't show focus rectangle (caret) */ SftTree_SetSelectionStyle(m_hwndRightTree, SFTTREE_SELECTION_CELL1 | SFTTREE_SELECTION_OUTLINE);/* Select first cell only using outline */ SftTree_SetSelectionArea(m_hwndRightTree, SFTTREE_SELECTIONAREA_ALL);/* Selection changes by clicking anywhere on an item */ SftTree_SetFlyby(m_hwndRightTree, TRUE);/* Flyby highlighting */ SftTree_SetScrollTips(m_hwndRightTree, TRUE);/* Show Scrolltips */ SftTree_SetOpenEnded(m_hwndRightTree, TRUE);/* Last column width */ /* Define columns */ { SFTTREE_COLUMN_EX aCol[1] = { { 0, 0, /* Reserved */ 100, /* Width (in pixels) */ ES_LEFT, /* Cell alignment */ ES_LEFT, /* Title style */ TEXT("Title"), /* Column header title */ NULL, NULL, /* Reserved field and bitmap handle */ SFTTREE_BMP_RIGHT, /* Bitmap 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 */ } }; SftTree_SetColumnsEx(m_hwndRightTree, 1, aCol);/* Set column attributes */ } SftTree_SetDragBitmaps(m_hwndRightTree, TRUE);/* Allow drag & drop from item, label pictures */ SftTree_SetDragType(m_hwndRightTree, SFTTREE_DRAG_PIXELIMM);/* Select and move by a number of pixels to start drag */ SftTree_SetDropHighlightStyle(m_hwndRightTree, SFTTREE_DROPHIGHLIGHT_ONTOP);/* Highlight drop target */ SftTree_SetCharSearchMode(m_hwndRightTree, SFTTREE_CHARSEARCH_ALLCHARS, -1);/* Consider all characters typed */ // Add a few items for (index = 3 ; index <= 30 ; ++index) { TCHAR szBuffer[80]; int i; wsprintf(szBuffer, TEXT("Item %d"), index-3); i = SftTree_AddString(m_hwndRightTree, szBuffer); SftTree_SetItemLevel(m_hwndRightTree, i, abs(3 - (index % 6))); } SftTree_RecalcHorizontalExtent(m_hwndRightTree);/* Update horizontal scroll bar */ return TRUE; } case WM_DESTROY: { DeleteObject(m_hBgBitmap); /* Background bitmap */ DeleteObject(m_aThreeItemPictures[0].Picture.hBitmap);/* Default item pictures */ DeleteObject(m_aThreeItemPictures[1].Picture.hBitmap); DeleteObject(m_aThreeItemPictures[2].Picture.hBitmap); break; } case WM_COMMAND: { HWND hwndCtl = (HWND) lParam; int id = LOWORD(wParam); int code = HIWORD(wParam); if (hwndCtl) { switch (id) { case IDC_LEFTTREE: 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 item to expand/collapse */ /* 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_AUTOEXPANDING: { int index; index = SftTree_GetExpandCollapseIndex(hwndCtl);/* Get item to expand/collapse */ SftTree_Expand(hwndCtl, index, TRUE, FALSE); break; } case SFTTREEN_ENDDRAG: EndDragLeft(); break; case SFTTREEN_CANCELDRAG: // always clear drop targets if (m_hwndLastTarget) { SftTree_SetDropHighlight(m_hwndLastTarget, -1, FALSE); SftTree_StopAutoExpandTimer(m_hwndLastTarget); m_hwndLastTarget = NULL; } MessageBox(NULL, TEXT("Drag & drop cancelled."), TEXT("SftTree/DLL"), MB_OK|MB_TASKMODAL); break; case SFTTREEN_BEGINDRAG: case SFTTREEN_DRAGGING: DraggingLeft(); break; } break; case IDC_RIGHTTREE: 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 item to expand/collapse */ /* 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_AUTOEXPANDING: { int index; index = SftTree_GetExpandCollapseIndex(hwndCtl);/* Get item to expand/collapse */ SftTree_Expand(hwndCtl, index, TRUE, FALSE); break; } case SFTTREEN_ENDDRAG: EndDragRight(); break; case SFTTREEN_CANCELDRAG: // always clear drop targets if (m_hwndLastTarget) { SftTree_SetDropHighlight(m_hwndLastTarget, -1, FALSE); SftTree_StopAutoExpandTimer(m_hwndLastTarget); m_hwndLastTarget = NULL; } MessageBox(NULL, TEXT("Drag & drop cancelled."), TEXT("SftTree/DLL"), MB_OK|MB_TASKMODAL); break; case SFTTREEN_BEGINDRAG: case SFTTREEN_DRAGGING: DraggingRight(); break; } break; case IDOK: case IDCANCEL: if (code == BN_CLICKED) SendMessage(hwndDlg, WM_COMMAND, id, 0); break; } } else { switch (id) { case IDOK: EndDialog(hwndDlg, TRUE); break; case IDCANCEL: EndDialog(hwndDlg, FALSE); break; } } break; } } return FALSE; } /**********************************************************************/ /* WinMain */ /**********************************************************************/ int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int cmdShow) { // Initialize g_hInst = hinst; SftTree_RegisterApp(hinst); /* Register with SftTree/DLL */ // Initialize, run, and terminate the application DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DRAGDROP_DIALOG), NULL, (DLGPROC)MainDialogProc); SftTree_UnregisterApp(hinst); /* Unregister from SftTree/DLL */ return 0; }