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 a tree control in virtual mode, used to display a list with 1 million items.
The source code is located at C:\Program Files (x86)\Softelvdm\SftTree DLL 7.5\Samples\C\Virtual\Virtual.c or C:\Program Files\Softelvdm\SftTree DLL 7.5\Samples\C\Virtual\Virtual.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 */ /**********************************************************************/ HINSTANCE g_hInst; // App Instance Handle HWND g_hwndTree; /* Tree control */ #define IDC_TREE 100 /* Tree control ID */ // Miscellaneous bitmaps HBITMAP m_hItem; HBITMAP m_hBgBitmap; /* Background bitmap */ 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 */ HBITMAP m_hRowBitmap; /* Row header bitmap */ SFT_PICTURE m_RowColHeaderPicture; /* Row/column picture */ /**********************************************************************/ /* ToolTips Callback */ /**********************************************************************/ // Callback of type SFTTREE_TOOLTIPSPROC void CALLBACK Tree_ToolTipsCallback(HWND hwnd, LPTSTR lpszBuffer, int type, int index, int column, SFTTREE_DWORD_PTR UserData, BOOL FAR* fInPlace) { switch (type) { case SFTTREE_TOOLTIP_VSCROLL: /* Vertical scrolling */ wsprintf(lpszBuffer, TEXT("Item %d is on top"), index); break; case SFTTREE_TOOLTIP_CELL: /* Cell tooltip */ // If lpszBuffer is left as-is, the cell tooltip will be displayed, otherwise // the text in lpszBuffer will be shown as an explanatory tooltip. // we don't modify lpszBuffer, so we get the default in-place tooltip //wsprintf(lpszBuffer, TEXT("An explanatory tooltip for cell %d/%d"), index, column); break; case SFTTREE_TOOLTIP_COLUMN_HEADER: /* Column header tooltip */ wsprintf(lpszBuffer, TEXT("A tooltip for column %d"), column); break; default: /* unhandled type (future expansion) */ return; } } /*------------------------------------------------------------------------------*/ /* This sample code implements the virtual data source member functions to */ /* retrieve/release data from an external data source. */ /*------------------------------------------------------------------------------*/ // Callback of type LPFNSFTTREE_VGETITEM void CALLBACK Tree_VirtualStorageGetItemCallback(HWND hwnd, SFTTREE_DWORD_PTR UserData, int totCols, LONG index, LPSFTTREE_ITEM FAR* lplpItem) { // All item information (including all strings) MUST remain valid until VirtualStorageReleaseItem // is called. For this reason, the strings must be allocated using "calloc/malloc" or be static and CANNOT be // objects located on the stack (i.e., NO local variables). int col; static SFTTREE_ITEM m_WorkingItem; static TCHAR aText[3][80]; /* Cell text */ static LPTSTR aCellText[3]; static SFTTREE_CELL aCells[3]; static SFTTREE_ROW rowInfo; /* Initialize */ memset(&m_WorkingItem, 0, sizeof(m_WorkingItem)); memset(&aCells, 0, sizeof(aCells)); memset(&aCellText, 0, sizeof(aCellText)); memset(&rowInfo, 0, sizeof(rowInfo)); /* Basic item information */ m_WorkingItem.level = 0; // Provide the level number (must be 0) m_WorkingItem.fShown = TRUE; // Must be shown (it's a flat list) m_WorkingItem.fEnabled = TRUE; // Item is enabled (visually) m_WorkingItem.dwdData = 0; // Userdata for this item (can be 0) m_WorkingItem.lpszRowHeader = NULL; // Row header text (can be NULL) if ((index % 6) == 0) /* Randomly change item bitmap */ Sft_SetPictureBitmap(&m_WorkingItem.ItemPicture, m_hItem); /* Cell text */ aCellText[0] = aText[0]; wsprintf(aCellText[0], TEXT("Item %09ld"), index); for (col = 1 ; col < totCols ; ++col) { aCellText[col] = aText[col]; wsprintf(aCellText[col], TEXT("Column %d(%d)"), col, index); } m_WorkingItem.alpszString = aCellText;/* Cell text array */ // (Optional) Initialize cells m_WorkingItem.aCells = aCells; for (col = 0 ; col < totCols ; ++col) { LPSFTTREE_CELL lpCell = &m_WorkingItem.aCells[col]; lpCell->colorBg = lpCell->colorFg = /* Cell colors */ lpCell->colorBgSel = lpCell->colorFgSel = SFTTREE_NOCOLOR; lpCell->hFont = NULL; /* Cell font */ lpCell->flag = SFTTREE_BMP_LEFT; /* Cell bitmap alignment */ if ((index % 5) == 0 && col == 1) {/* Randomly add bitmaps */ Sft_SetPictureBitmap(&lpCell->CellPicture1, m_hCellBitmap);/* Cell picture */ lpCell->flag |= SFTTREE_BMP_RIGHT;/* Cell picture alignment */ } if (col == 2 && (index % 5) == 0) {/* Randomly change colors */ lpCell->colorBg = 0x80000000 | COLOR_BTNFACE; lpCell->colorFg = 0x80000000 | COLOR_BTNTEXT; } } // (Optional) Create row header information m_WorkingItem.lpszRowHeader = NULL; /* Row header text (can be NULL) */ m_WorkingItem.lpRow = &rowInfo; /* Row header information (can be NULL) */ rowInfo.colorBg = rowInfo.colorFg = /* Row header colors */ rowInfo.colorBgSel = rowInfo.colorFgSel = SFTTREE_NOCOLOR; if ((index % 8) == 0) {/*randomly add bitmaps */ Sft_SetPictureBitmap(&rowInfo.RowPicture1, m_hRowBitmap);/* Row header picture */ rowInfo.flag = SFTTREE_BMP_LEFT; /* Row header picture alignment */ } *lplpItem = &m_WorkingItem; } // Callback of type LPFNSFTTREE_VRELEASEITEM void CALLBACK Tree_VirtualStorageReleaseItemCallback(HWND hwnd, SFTTREE_DWORD_PTR UserData, int totCols, LONG index, LPSFTTREE_ITEM lpItem) { // free storage allocated during previous Tree_VirtualStorageGetItemCallback call } /**********************************************************************/ /* Frame Window Proc */ /**********************************************************************/ LRESULT CALLBACK SDI_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_CREATE: { RECT rect; GetClientRect(hwnd, &rect); g_hwndTree = CreateWindowEx( WS_EX_CLIENTEDGE, TEXT(SFTTREESPLIT_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 */ SFTTREESTYLE_DISABLENOSCROLL | /* Disable scrollbars instead of hiding */ WS_HSCROLL | WS_VSCROLL | /* Vertical and horizontal scrollbars */ WS_VISIBLE | WS_CHILD, /* Visible, child window */ rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,/* Location */ hwnd, /* Parent window */ (HMENU) IDC_TREE, /* Tree control ID */ g_hInst, /* Application instance */ NULL); if (!g_hwndTree) return -1; m_hItem = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_ITEM));/* Another item bitmap */ /* 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. */ /* Initialize "virtual" data callback routines. The */ /* routines used are defined below. */ { SFTTREE_VIRTUALDEF virt = { SFTTREE_VERSION_700, 0, Tree_VirtualStorageGetItemCallback, Tree_VirtualStorageReleaseItemCallback, }; if (!SftTreeSplit_VirtualInitialize(g_hwndTree, &virt)) ; /* error handling goes here */ /* Set current number of items in the control. */ if (!SftTreeSplit_VirtualCount(g_hwndTree, 1000000L, 1000000L, 0)) ; /* error handling goes here */ } SftTreeSplit_SetShowHeader(g_hwndTree, TRUE);/* Show column headers */ /* Define the background bitmap. */ m_hBgBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BACKGROUND));/* Load a background bitmap */ SftTreeSplit_SetBackgroundBitmap(g_hwndTree, 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 */ SftTreeSplit_SetPictures(g_hwndTree, m_aThreeItemPictures);/* Use item picture */ SftTreeSplit_SetItemBitmapAlign(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); SftTreeSplit_SetCellInfo(g_hwndTree, &CellInfo);/* Register use of cell pictures */ } SftTreeSplit_SetTreeLineStyle(g_hwndTree, SFTTREE_TREELINE_NONE);/* No tree lines */ SftTreeSplit_SetShowButtons(g_hwndTree, FALSE);/* No expand/collapse buttons */ SftTreeSplit_SetShowGrid(g_hwndTree, TRUE);/* Show grid */ SftTreeSplit_SetGridStyle(g_hwndTree, SFTTREE_GRID_BOTH_DOT);/* Dotted grid lines */ SftTreeSplit_SetShowTruncated(g_hwndTree, TRUE);/* Show ... if truncated */ SftTreeSplit_SetSelectionStyle(g_hwndTree, SFTTREE_SELECTION_CELL1);/* Select first cell only */ SftTreeSplit_SetSelectionArea(g_hwndTree, SFTTREE_SELECTIONAREA_ALL);/* Selection changes by clicking anywhere on an item */ SftTreeSplit_SetFlyby(g_hwndTree, TRUE);/* Flyby highlighting */ SftTreeSplit_SetScrollTips(g_hwndTree, TRUE);/* Show Scrolltips */ SftTreeSplit_SetReorderColumns(g_hwndTree, TRUE);/* Column reordering */ SftTreeSplit_SetOpenEnded(g_hwndTree, TRUE, TRUE);/* Left tree open ended*/ SftTreeSplit_SetOpenEnded(g_hwndTree, TRUE, FALSE);/* Right tree open ended */ SftTreeSplit_SetShowHeaderButtons(g_hwndTree, TRUE);/* Show column header as buttons */ /* Define columns */ { SFTTREE_COLUMN_EX aCol[3] = { { 0, 0, /* Reserved */ 116, /* 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, /* 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) */ SFTTREE_COL_MERGE | /* Column can merge with next */ SFTTREE_COL_MERGEINTO | /* Previous column can merge into this column */ 0, /* Column flag */ 30, /* Minimum column width */ }, { 0, 0, /* Reserved */ 131, /* 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, /* 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) */ 1, /* Display column number (display position) */ SFTTREE_COL_MERGE | /* Column can merge with next */ SFTTREE_COL_MERGEINTO | /* Previous column can merge into this column */ 0, /* Column flag */ 30, /* Minimum column width */ }, { 0, 0, /* Reserved */ 131, /* 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, /* 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) */ 2, /* Display column number (display position) */ 0, /* Column flag */ 30, /* Minimum column width */ } }; SftTreeSplit_SetColumnsEx(g_hwndTree, 3, aCol);/* Set column attributes */ SftTreeSplit_SetSplitColumn(g_hwndTree, 1);/* Column split position */ } SftTreeSplit_SetShowRowHeader(g_hwndTree, SFTTREE_ROWSTYLE_BUTTONCOUNT0);/* Row style */ /* Register the row header picture size. All row header */ /* pictures used must be the same size. Only one picture */ /* needs to be registered, even if several are used. */ { SFTTREE_ROWINFOPARM RowInfo; RowInfo.version = 7; RowInfo.index = -1; m_hRowBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_ROW));/* Row header picture */ Sft_InitPicture(&RowInfo.Row.RowPicture1); Sft_SetPictureBitmap(&RowInfo.Row.RowPicture1, m_hRowBitmap); SftTreeSplit_SetRowInfo(g_hwndTree, &RowInfo); } SftTreeSplit_SetRowColHeaderText(g_hwndTree, TEXT("?"));/* Row/column header text */ SftTreeSplit_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 */ SftTreeSplit_SetRowColHeaderPicture(g_hwndTree, &m_RowColHeaderPicture);/* Row/column picture */ SftTreeSplit_SetRowColHeaderPictureStyle(g_hwndTree, SFTTREE_BMP_RIGHT);/* Row/column picture alignment */ SftTreeSplit_SetCalcVisibleOnly(g_hwndTree, TRUE);/* Visible items only (for calculations) */ SftTreeSplit_SetCharSearchMode(g_hwndTree, SFTTREE_CHARSEARCH_NONE, -1);/* Ignore typed characters */ /* Use a ToolTips callback routine */ { SFTTREE_TOOLTIPSPARM Parm; /* Parameter list */ Parm.lpfnToolTips = (SFTTREE_TOOLTIPSPROC) Tree_ToolTipsCallback;/* User supplied routine */ Parm.UserData = (SFTTREE_DWORD_PTR)0;/* User supplied data */ SftTreeSplit_SetToolTipsCallback(g_hwndTree, &Parm); } /* Change the default colors */ { SFTTREE_COLORS Colors; SftTreeSplit_GetCtlColors(g_hwndTree, &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) */ SftTreeSplit_SetCtlColors(g_hwndTree, &Colors);/* Set new colors */ } // In our example, we use SetCalcLimit(50) which will only consider 50 items when // MakeColumnOptimal, MakeRowHeaderOptimal or MakeSplitterOptimal is used. Because our sample // data is wider at the end of the list, we'll change the TopIndex to the very last few items. // That way the last 50 items are analyzed. In a typical application this is not necessary. SftTreeSplit_SetTopIndex(g_hwndTree, SftTreeSplit_GetCount(g_hwndTree) - 50); /* Make all column widths optimal, so text and pictures */ /* are not clipped horizontally. */ SftTreeSplit_SetCalcLimit(g_hwndTree, 50);/* Evaluate up to 50 items */ SftTreeSplit_MakeColumnOptimal(g_hwndTree, -1);/* Make column widths optimal */ /* Make row header width optimal, so text and pictures are */ /* not clipped horizontally. */ SftTreeSplit_SetCalcLimit(g_hwndTree, 50);/* Evaluate up to 50 items */ SftTreeSplit_MakeRowHeaderOptimal(g_hwndTree);/* Make row header width optimal */ SftTreeSplit_SetCalcLimit(g_hwndTree, 50);/* Evaluate up to 50 items */ SftTreeSplit_RecalcHorizontalExtent(g_hwndTree);/* Update horizontal scroll bar */ SftTreeSplit_MakeSplitterOptimal(g_hwndTree);/* Optimal splitter position */ SftTreeSplit_SetTopIndex(g_hwndTree, 0); return 0; } case WM_DESTROY: DeleteObject(m_hItem); 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); DeleteObject(m_hCellBitmap); /* A cell picture */ DeleteObject(m_hRowBitmap); /* Row header 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_CONTEXTMENU: MessageBox(NULL, TEXT("Received WM_CONTEXTMENU message from the tree control. You could bring up a context menu."), TEXT("WM_CONTEXTMENU"), MB_OK| MB_TASKMODAL); 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_COLUMNRES: { // a column resizing area has been double clicked, we'll resize the column /* Resize column optimally */ int realCol = SftTreeSplit_GetResizeColumn(g_hwndTree); if (realCol >= 0) { SftTreeSplit_SetCalcLimit(g_hwndTree, 50);/* Evaluate up to 50 items */ SftTreeSplit_MakeColumnOptimal(g_hwndTree, realCol);/* Make column width optimal */ SftTreeSplit_RecalcHorizontalExtent(g_hwndTree);/* Update horizontal scroll bar */ } else { SftTreeSplit_MakeSplitterOptimal(g_hwndTree);/* Optimal splitter position */ } break; } case SFTTREEN_LBUTTONDBLCLK_ITEM: { int index; /* Get current position */ index = SftTreeSplit_GetCaretIndex(hwndCtl);/* Get caret location */ /* User defined processing goes here */ break; } } break; case 1000: // Menu command, Exit DestroyWindow(hwnd); break; case 1001: // Menu command, Resize Splitter SftTreeSplit_EnterResizeMode(g_hwndTree); 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. - Virtual 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; }