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 owner-draw cells and column headers.
The source code is located at C:\Program Files (x86)\Softelvdm\SftTree DLL 7.5\Samples\C\OwnerDraw\OwnerDraw.c or C:\Program Files\Softelvdm\SftTree DLL 7.5\Samples\C\OwnerDraw\OwnerDraw.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> // If the following cause compile errors, you will have to update your // Microsoft Windows Platform SDK, as these files are fairly recent for // Windows Themes support. // If you're using an older version you may have to use #include <vssym32.h> instead of #include <tmschema.h> #include <uxtheme.h> //#include <tmschema.h> /* Theme support - XP */ #include <vssym32.h> /* Theme support */ #pragma comment(lib, "uxtheme.lib") #include "SftTree.h" /* SftTree/DLL Header File */ #include "resource.h" // resource IDs /**********************************************************************/ /* Globals */ /**********************************************************************/ #define IDC_TREE 100 /* Tree control ID */ HINSTANCE g_hInst; // App Instance Handle HWND g_hwndTree; /* Tree control */ HFONT g_hFontVertical; /* Vertical font */ HBITMAP g_hBitmap; /* Sample bitmap */ // 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 */ BOOL CALLBACK Tree_OwnerDrawCallback(HWND hwnd, LPSFTTREE_OWNERDRAW lpInfo, SFTTREE_DWORD_PTR UserData); /**********************************************************************/ /* 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_VARIABLE | /* Variable height items */ 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 or invisible 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_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("Vertical Titles"), /* 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_SetRowColHeaderPictureStyle(g_hwndTree, SFTTREE_BMP_RIGHT);/* Row/column picture alignment */ SftTree_SetCharSearchMode(g_hwndTree, SFTTREE_CHARSEARCH_ALLCHARS, -1);/* Consider all characters typed */ /* Use an ownerdraw callback routine */ { SFTTREE_OWNERDRAWPARM Parm; /* Parameter list */ Parm.lpfnOwnerDrawProc = (LPFNSFTTREE_OWNERDRAWPROC) Tree_OwnerDrawCallback;/* User supplied drawing routine */ Parm.OwnerDrawUserData = (SFTTREE_DWORD_PTR)0;/* User supplied data */ SftTree_SetOwnerDrawCallback(g_hwndTree, &Parm); } /* 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. */ /*------------------------------------------------------------------------------*/ 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("3nd Column"));/* Set text in next column */ index = SftTree_AddString(g_hwndTree, TEXT("Another 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 */ /* Set an item's row header text using: */ SftTree_SetRowText(g_hwndTree, index, TEXT("?"));/* Row header text */ 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("A fourth 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, 4); // select the 4th item SftTree_SetCaretIndex(g_hwndTree, 4); // and make it current SftTree_SetTopIndex(g_hwndTree, 0); // show the first item 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_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; } } break; case 1000: // 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; } // create a vertical font { LOGFONT lf; HFONT hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT); GetObject(hFont, sizeof(LOGFONT), &lf); lf.lfEscapement = 900; lf.lfOutPrecision = OUT_TT_ONLY_PRECIS; lf.lfCharSet = DEFAULT_CHARSET; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = FF_DONTCARE; lstrcpy(lf.lfFaceName, TEXT("Arial")); g_hFontVertical = CreateFontIndirect(&lf); } // load sample bitmap g_hBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_LOGO)); SftTree_RegisterApp(hinst); /* Register with SftTree/DLL */ // Initialize, run, and terminate the application hwndMain = CreateWindowEx( 0L, TEXT("SoftelSampleFrame"), TEXT("Softel vdm, Inc. - OwnerDraw 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); } DeleteObject(g_hBitmap); DeleteObject(g_hFontVertical); SftTree_UnregisterApp(hinst); /* Unregister from SftTree/DLL */ return (int) msg.wParam; } /**********************************************************************/ /* Ownerdraw Callback */ /**********************************************************************/ static void OwnerDraw_Column_Header(HWND hwndTree, LPSFTTREE_OWNERDRAW lpInfo, SFTTREE_DWORD_PTR UserData) { // This function paints the column header using a vertical font // it even takes themes into consideration, so it's a bit more complicated // than the average application. // get general information about tree control and columns LPSFTTREE_COLUMN_EX lpCol; int nCols = SftTree_GetColumnsEx(hwndTree, &lpCol);/* Get column attributes */ // calculate the text size RECT rect, textRect; int len = lstrlen(lpCol[lpInfo->col].lpszTitle); // column title COLORREF clrFg = SetTextColor(lpInfo->hDC, GetSysColor(COLOR_BTNTEXT)); int mode = SetBkMode(lpInfo->hDC, TRANSPARENT); HFONT hOldFont = (HFONT) SelectObject(lpInfo->hDC, g_hFontVertical); SetRectEmpty(&rect); DrawText(lpInfo->hDC, lpCol[lpInfo->col].lpszTitle, len, &rect, DT_CALCRECT|DT_LEFT); SetRect(&textRect, rect.top, rect.left, rect.bottom, rect.right); if (lpInfo->style == SFTTREE_OD_CALC) { // we need to return just the size of the header we want to paint rect = textRect; if (lpInfo->fThemed) { // Windows themes are used RECT extentRect; GetThemeBackgroundExtent(lpInfo->hThemeHeader, lpInfo->hDC, HP_HEADERITEM, HIS_NORMAL, &rect, &extentRect); rect = extentRect; InflateRect(&rect, 3, 6); // leave a slight gap } else { // No windows themes InflateRect(&rect, 4, 4); // leave a slight gap } lpInfo->DrawRect.bottom = rect.bottom-rect.top; lpInfo->DrawRect.right = rect.right-rect.left; } else { // we need to paint the header int xOffs, yOffs; if (lpInfo->fThemed) { // Windows themes are used int iPartId = HP_HEADERITEM; int iStateId = HIS_NORMAL; if (lpInfo->fSelected) iStateId = HIS_PRESSED; if (lpInfo->fFlyby) iStateId = HIS_HOT; DrawThemeBackground(lpInfo->hThemeHeader, lpInfo->hDC, iPartId, iStateId, &lpInfo->DrawRect, &lpInfo->DrawRect); GetThemeBackgroundContentRect(lpInfo->hThemeHeader, lpInfo->hDC, iPartId, iStateId, &lpInfo->DrawRect, &rect); } else { // No windows themes DrawFrameControl(lpInfo->hDC, &lpInfo->DrawRect, DFC_BUTTON, DFCS_BUTTONPUSH | (lpInfo->fSelected ? DFCS_PUSHED : 0)); rect = lpInfo->DrawRect; } xOffs = max(0, ((lpInfo->DrawRect.right-lpInfo->DrawRect.left) - (textRect.right-textRect.left))/2); yOffs = max(0, ((lpInfo->DrawRect.bottom-lpInfo->DrawRect.top) - (textRect.bottom-textRect.top))/2); if (lpInfo->fSelected) { xOffs++; yOffs--; } ExtTextOut(lpInfo->hDC, lpInfo->DrawRect.left+xOffs, lpInfo->DrawRect.bottom-yOffs, 0, &lpInfo->DrawRect, lpCol[lpInfo->col].lpszTitle, len, NULL); } SelectObject(lpInfo->hDC, hOldFont); SetBkMode(lpInfo->hDC, mode); SetTextColor(lpInfo->hDC, clrFg); } static void OwnerDraw_Cell_Bitmap(HWND hwndTree, LPSFTTREE_OWNERDRAW lpInfo, SFTTREE_DWORD_PTR UserData) { RECT rect; BITMAP bm; HDC hDCTemp = CreateCompatibleDC(lpInfo->hDC); HBITMAP hOldBitmap = (HBITMAP) SelectObject(hDCTemp, g_hBitmap); // Select the bitmap GetObject(g_hBitmap, sizeof(BITMAP), &bm); SetRect(&rect, 0, 0, bm.bmWidth, bm.bmHeight); if (lpInfo->style == SFTTREE_OD_CALC) { // we need to return just the size of the cell we want to paint lpInfo->DrawRect = rect; } else { // we need to paint the cell FillRect(lpInfo->hDC, &lpInfo->DrawRect, (HBRUSH) (COLOR_WINDOW+1)); BitBlt(lpInfo->hDC, lpInfo->DrawRect.left, lpInfo->DrawRect.top, lpInfo->DrawRect.right-lpInfo->DrawRect.left, lpInfo->DrawRect.bottom-lpInfo->DrawRect.top, hDCTemp, 0, 0, SRCCOPY); } SelectObject(hDCTemp, hOldBitmap); DeleteDC(hDCTemp); } static void OwnerDraw_Cell_Text(HWND hwndTree, LPSFTTREE_OWNERDRAW lpInfo, SFTTREE_DWORD_PTR UserData) { TCHAR szText[1000]; HFONT hFont, hOldFont; hFont = (HFONT) SendMessage(lpInfo->hwndCtl, WM_GETFONT, 0, 0); hOldFont = (HFONT) SelectObject(lpInfo->hDC, hFont); SftTree_GetTextCol(lpInfo->hwndCtl, lpInfo->index, lpInfo->col, szText); // retrieve the cell text if (lpInfo->style == SFTTREE_OD_CALC) { // we need to return just the size of the cell we want to paint RECT r; SetRectEmpty(&r); DrawText(lpInfo->hDC, szText, -1, &r, DT_CALCRECT | DT_LEFT | DT_SINGLELINE); InflateRect(&r, lpInfo->gap/2, 0); lpInfo->DrawRect = r; } else { // we need to paint the cell RECT r; FillRect(lpInfo->hDC, &lpInfo->DrawRect, (HBRUSH) (COLOR_3DFACE+1)); if (lpInfo->fSelected) SftTree_DrawSelectionOutline(lpInfo->hwndCtl, lpInfo->hDC, &lpInfo->DrawRect, RGB(128,0,0), RGB(255,100,100), RGB(255,255,255), RGB(255,0,0)); r = lpInfo->DrawRect; InflateRect(&r, -lpInfo->gap/2, 0); DrawText(lpInfo->hDC, szText, -1, &r, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); } SelectObject(lpInfo->hDC, hOldFont); } BOOL CALLBACK Tree_OwnerDrawCallback(HWND hwnd, LPSFTTREE_OWNERDRAW lpInfo, SFTTREE_DWORD_PTR UserData) { if (lpInfo->itemType == SFTTREE_OD_COLHEADER) { OwnerDraw_Column_Header(hwnd, lpInfo, UserData); return TRUE; } if ((lpInfo->itemType == SFTTREE_OD_CELL || lpInfo->itemType == SFTTREE_OD_CELLTOOLTIP) && lpInfo->col == 1) { if ((lpInfo->index % 5) == 0) { OwnerDraw_Cell_Bitmap(hwnd, lpInfo, UserData); return TRUE; } else if ((lpInfo->index % 4) == 0) { OwnerDraw_Cell_Text(hwnd, lpInfo, UserData); return TRUE; } } return FALSE; }