home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / windows / c / bsscdemo / treedem2 / treedem2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-25  |  30.8 KB  |  764 lines

  1. /*
  2.    Copyright (c) 1993 by Barking Spider Software, Inc.  All rights reserved
  3.                                                                            
  4.    Filename...:  treedem2.c
  5.    
  6.    Version,,,,:  1.0
  7.    
  8.    Language...:  Microsoft C/C++ 7.0
  9.    
  10.    Model......:  Small
  11.    
  12.    Environment:  Microsoft Windows 3.1
  13.                                                                            
  14.    Description:  This source module demonstrates the BSS Tree Control as part 
  15.                  of a dialog template.  The dialog box template in treedem2.dlg
  16.                  was created with the Dialog Editor.   The Dialog Editor
  17.                  is shipped with the Windows 3.1 SDK.  Since the BSS Tree
  18.                  Control has custom control support built in, all that was
  19.                  required to use the tree control in the Dialog Editor was to
  20.                  select the File menu item, then select Open Custom, type in
  21.                  the path for treectrl.dll and hit return.  Select New under
  22.                  the File menu item to get an empty dialog box frame.
  23.                  The Dialog Editor Toolbox will then contain a button
  24.                  representing the tree control.  Select this button, drag
  25.                  the mouse over the new dialog box frame and stretch the 
  26.                  custom tree control into the desired place.
  27.                  
  28.                  In the sample code below, a simple top level overlapped
  29.                  window is created with a couple of menu items.  From these
  30.                  menu items, the user can create a modal dialog box or the
  31.                  user can exit the application.  If the user selects the
  32.                  menu item Tree Dialog, a modal dialog box will appear that
  33.                  contains a BSS Tree Control, two edit controls, and a  
  34.                  push button.  In the tree control will be a root tree node.
  35.                  In the edit controls will be initial values.  The first
  36.                  edit control is used for entering strings that will be text
  37.                  for future tree nodes.  The second edit control excepts any
  38.                  3 digit base 10 value.  This directs how many tree nodes to
  39.                  create with the text in the first edit control when a 
  40.                  user double clicks on a tree node with a closed folder.
  41.                  
  42.                  Each node displays a bitmap, an icon, and text.  The bitmap
  43.                  is a folder and the icon is the infamous BSS Spider icon.
  44.                  These items demonstrate the ability of the BSS Tree Control
  45.                  to display bitmaps, icons, and text.
  46.                  
  47.                  When the user decides to quit the dialog box, hitting the 
  48.                  Enter key, Esc key, or clicking on push button will exit the
  49.                  dialog box.
  50.                  
  51.    Notes......:             
  52.                                                                            
  53.    History....:  
  54.                                                                               
  55.    Author.....:  Peter J. Kaufman
  56. */    
  57.  
  58. #include <windows.h>
  59. #include "treedem2.h"
  60. #include "..\bscore.h"
  61. #include "..\bstree.h"
  62. #include <string.h>
  63. #include <stdlib.h>
  64.  
  65. static char szAppName[] = "TreeDem2";
  66.  
  67. HANDLE hInst ;
  68.  
  69.  
  70. /*****************************************************************************
  71. int PASCAL WinMain ( HANDLE hInstance,
  72.                      HANDLE hPrevInstance,
  73.                      LPSTR lpszCmdLine,
  74.                      int nCmdShow);
  75.                      
  76. *****************************************************************************/
  77.  
  78. int PASCAL WinMain ( HANDLE hInstance,
  79.                      HANDLE hPrevInstance,
  80.                      LPSTR lpszCmd,
  81.                      int nCmdShow)
  82. {
  83.    HWND       hwnd ;
  84.    MSG        msg ;
  85.    WNDCLASS   wndclass ;
  86.  
  87.    hInst = hInstance ;
  88.  
  89.    if (!hPrevInstance)
  90.    {
  91.       wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  92.       wndclass.lpfnWndProc   = TreeDemo2WndProc ;
  93.       wndclass.cbClsExtra    = 0 ;
  94.       wndclass.cbWndExtra    = 0 ;
  95.       wndclass.hInstance     = hInst;
  96.       wndclass.hIcon         = LoadIcon (hInst,
  97.                                          MAKEINTRESOURCE(IDR_TREEDEMO_ICON)) ;
  98.       wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  99.       wndclass.hbrBackground = COLOR_APPWORKSPACE + 1;
  100.       wndclass.lpszMenuName  = szAppName;
  101.       wndclass.lpszClassName = szAppName;
  102.  
  103.       RegisterClass (&wndclass) ;
  104.    }
  105.  
  106.    hwnd = CreateWindow (szAppName,
  107.                         "Barking Spider Software, Inc. Tree Demo 2 - Dialog",
  108.                         WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  109.                         CW_USEDEFAULT,
  110.                         CW_USEDEFAULT,
  111.                         CW_USEDEFAULT,
  112.                         CW_USEDEFAULT,
  113.                         NULL,
  114.                         NULL,
  115.                         hInstance,
  116.                         NULL);
  117.  
  118.    ShowWindow (hwnd, nCmdShow) ;
  119.    UpdateWindow (hwnd) ;
  120.  
  121.    while (GetMessage (&msg, NULL, 0, 0))
  122.    {
  123.       TranslateMessage (&msg) ;
  124.       DispatchMessage (&msg) ;
  125.    }
  126.    return msg.wParam ;
  127. }
  128.  
  129.  
  130.  
  131. /*****************************************************************************
  132. long FAR PASCAL _export TreeDemo2WndProc ( HWND hwnd,
  133.                                            UINT message,
  134.                                            UINT wParam,
  135.                                            LONG lParam)
  136.                      
  137.  This is the window procedure for the top level window of this application.
  138.  When the user selects the menu item Tree Dialog, a modal dialog box based on
  139.  the dialog box template in treedem2.dlg will be created. 
  140. *****************************************************************************/
  141.  
  142. long FAR PASCAL _export TreeDemo2WndProc ( HWND hwnd,
  143.                                            UINT message,
  144.                                            UINT wParam,
  145.                                            LONG lParam)
  146. {                                                          
  147.    static FARPROC lpfnTreeDlgProc ;
  148.    static HANDLE  hInstance ;
  149.  
  150.    switch (message)
  151.    {
  152.       case WM_CREATE:
  153.          hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
  154.          lpfnTreeDlgProc = MakeProcInstance ((FARPROC) TreeDlgProc,
  155.                                                        hInstance) ;
  156.          return 0 ;
  157.  
  158.       case WM_COMMAND:
  159.          switch (wParam)
  160.          {
  161.             case IDM_TREE_DIALOG:
  162.                DialogBox (hInstance, 
  163.                           MAKEINTRESOURCE(IDD_DIALOG),
  164.                           hwnd,
  165.                           lpfnTreeDlgProc);
  166.                return 0;
  167.                
  168.             case IDM_EXIT:
  169.                SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
  170.                return 0;
  171.          }
  172.          break ;
  173.  
  174.       case WM_DESTROY :
  175.          PostQuitMessage (0) ;
  176.          return 0 ;
  177.    }
  178.    return DefWindowProc (hwnd, message, wParam, lParam) ;
  179. }
  180.     
  181.  
  182.  
  183.  
  184. /*****************************************************************************
  185. BOOL FAR PASCAL _export TreeDlgProc ( HWND hwnd,
  186.                                       UINT message,
  187.                                       UINT wParam,
  188.                                       LONG lParam);
  189.                                       
  190.  
  191.   This is the dialog box procedure for the dialog box template defined in 
  192.   treedem2.dlg.  It manages the tree control, the edit controls, and the
  193.   push button.  The dialog boxes two primary functions are:
  194.   
  195.     1) Demonstrate the tree control in a dialog box.
  196.     2) Allow the user to "play" with the tree control.
  197.   
  198.   In WM_INITDIALOG, folder bitmaps are created, the BSS Spider icon is
  199.   loaded, the root node of the tree control is created and inserted,
  200.   and the edit controls are initialize with valid strings and limitations.  
  201.   
  202.   When a user double clicks on a node that has a closed folder 
  203.   bitmap, this dialog box procedure reads the strings in from the two
  204.   edit controls.  One string is the desired tree node text of future nodes
  205.   and the other string represents the number of nodes to be added to the 
  206.   selected node as children.
  207.   
  208.   When the user is tire of playing with the tree control, pressing the push
  209.   button will end the fun."
  210. ******************************************************************************/
  211. #define MAX_TEXT_LENGTH     2048  // Max number of characters to be used 
  212.                                   // in the tree node text.  Can be increased.
  213. #define MAX_COUNT_DIGITS    3     // Max number of digits in the count value.
  214.  
  215. char    szTextBuffer [ MAX_TEXT_LENGTH + 1];  // Node text storage
  216. char    szCountBuffer [ MAX_COUNT_DIGITS + 1]; // Node count storage
  217.  
  218. HWND    hwndTree;    // Tree control handle
  219. HWND    hwndCount;   // Count edit control.
  220. HWND    hwndText;    // Node text edit control.
  221.  
  222. // folder bitmaps
  223.  
  224. HBITMAP hbmClosedActive;
  225. HBITMAP hbmClosed;
  226. HBITMAP hbmOpenActive;
  227. HBITMAP hbmOpen;
  228. HICON   hSpiderIcon;
  229.                     
  230. BOOL FAR PASCAL _export TreeDlgProc ( HWND hwnd,
  231.                                       UINT message,
  232.                                       UINT wParam,
  233.                                       LONG lParam)
  234. {
  235.    LP_TREE_NODE       lpParentTreeNode;// Pointer to tree node
  236.    LP_TREE_NODE_DEF   lpTreeNodeDef;   // Pointer to tree node definition
  237.    LP_TREE_NODE_DEF   lpTreeNodeDef2;
  238.    LP_SELECT_NOTIF    lpSelectNotif;   // Pointer to tree notification struct.
  239.    WORD               i,j;
  240.    WORD               wCount;
  241.    char               szBuffer[6];
  242.    WORD               wErrCode;
  243.    
  244.    switch (message)
  245.    {
  246.       case WM_INITDIALOG:  // Create the root node, the folder bitmap, and
  247.                            // initialize the node text and count edit controls.
  248.          // Get the handle of the tree control
  249.          hwndTree = GetDlgItem (hwnd, IDC_TREE);
  250.          
  251.          // CreateBackgroundMatchedBitmap() is NOT an exported BSS
  252.          // Tree Control API!  It is supplied as a tool for developers to 
  253.          // mask the background of an irregular shaped bitmap to the 
  254.          // windows background color.  This routine only handles 16 color
  255.          // bit bitmaps.
  256.          
  257.          // CreateBackgroundMatchedBitmap creates the folders used in 
  258.          // the BSS Tree Control.  CreateBackgroundMatchedBitmap  does what
  259.          // it says.  It loads the initial folder bitmap from the resource,
  260.          // and converts the bitmap's background color to match the system 
  261.          // window color.  This is done for the closed and open
  262.          // folder bitmaps. 
  263.          
  264.          // Notice that this procedure is also done for the COLOR_HIGHLIGHT
  265.          // color.  COLOR_HIGHLIGHT is the color used to show the current
  266.          // selection (active node).  Feel free to include this and any other
  267.          // routine in your application.
  268.  
  269.          hbmClosed = CreateBackgroundMatchedBitmap (
  270.                                                   GetSysColor (COLOR_WINDOW),
  271.                                                   IDR_CLOSED_FOLDER);
  272.  
  273.          hbmClosedActive = CreateBackgroundMatchedBitmap (
  274.                                                 GetSysColor (COLOR_HIGHLIGHT),
  275.                                                 IDR_CLOSED_FOLDER);
  276.  
  277.          hbmOpen = CreateBackgroundMatchedBitmap (
  278.                                                   GetSysColor (COLOR_WINDOW),
  279.                                                   IDR_OPEN_FOLDER);
  280.          
  281.          hbmOpenActive = CreateBackgroundMatchedBitmap (
  282.                                                 GetSysColor (COLOR_HIGHLIGHT),
  283.                                                 IDR_OPEN_FOLDER);
  284.                                                 
  285.          // Bitmaps spaces are where bitmaps are placed in a tree node.  The
  286.          // bitmap spaces are placed left of the text.  Below, one bitmap
  287.          // space is defined.  The max width and height are defined.  The
  288.          // first argument is the BSS Tree Control handle, the second is the
  289.          // bitmap space identifier (which bitmap space is being defined).  The
  290.          // third and fourth arguments are the width and height respectively.
  291.          // The last argument signals the BSS Tree Control whether to center
  292.          // or left justify the currently assigned bitmap in this bitmap space.
  293.          // TRUE means center, FALSE means left justify.
  294.          
  295.          // This defines the first bitmap space globally for every tree node.
  296.          // This keeps column alignment per level.
  297.  
  298.          BST_SetBitmapSpace( hwndTree, 0, 23, 17, TRUE);
  299.  
  300.          // For the second bitmap space, the application must specify a 
  301.          // height and a width at least large enough to hold an ICON since
  302.          // the application will defined an icon to be placed in the second
  303.          // bitmap space.  The required height and width are a result of the
  304.          // Windows API, DrawIcon(), displaying the whole ICON and not
  305.          // offering any clipping functionality.  The application can determine
  306.          // the minimum height and width bitmap space needed by the BSS Tree
  307.          // Control, by calling the Windows API, GetSystemMetrics().
  308.          // Calling GetSystemMetrics() with SM_CXICON will return the width
  309.          // of an ICON and calling GetSystemMetrics() with SM_CYICON will
  310.          // return the height of an ICON.  After this is accomplished, the
  311.          // application can place additional margins on the height and width
  312.          // of the bitmap space for appearences.
  313.          
  314.          // The advantages of using ICONs instead of bitmaps is:
  315.          //  1) Icon editors are readily available and offer flexiblity to
  316.          //     the presentation of the image.
  317.          //  2) MORICONS.DLL offer an array of icons to use as templates
  318.          //     for original images.  MORICONS.DLL is shipped with Windows 3.1.
  319.          //  3) DrawIcon()s will repect the image created by the developer in
  320.          //     the sense of background masking, etc.
  321.          //  One major disadvantage is that the size of the ICON is fixed
  322.          //  where bitmaps can be any size and clipped to fit in a smaller
  323.          //  bitmap space.
  324.          
  325.          BST_SetBitmapSpace( hwndTree, 
  326.                              1,
  327.                              GetSystemMetrics (SM_CXICON) + 4,
  328.                              GetSystemMetrics (SM_CYICON) + 4,
  329.                              TRUE);
  330.           
  331.          hSpiderIcon = LoadIcon ( hInst, MAKEINTRESOURCE(IDR_TREEDEMO_ICON));
  332.          
  333.          // Now, the fun part...  Defining tree nodes.
  334.          
  335.          // First... define the root!
  336.          
  337.          // Allocate 1 tree node definition space for the root. It
  338.          // is best if this memory is initialize to zero.  The tree node
  339.          // definition structure is the vehicle that the application uses
  340.          // to define tree nodes to the BSS Tree Control.  This memory is 
  341.          // the property of the application.  It's contents are copied to 
  342.          // the tree control.  Once the node is defined, this memory can
  343.          // be freed.
  344.  
  345.          lpTreeNodeDef = (LP_TREE_NODE_DEF)
  346.                        MAKEP( GlobalAlloc (GPTR|GMEM_SHARE, 
  347.                                      MAKELONG(sizeof(TREE_NODE_DEF)*1,0)),0);
  348.                
  349.          if(lpTreeNodeDef)
  350.          {                            
  351.             // Assign the text that will be displayed for the tree node.
  352.    
  353.             lpTreeNodeDef->lpszText = "You cannot have a tree without a root.";
  354.             
  355.             // Length of the above text.
  356.    
  357.             lpTreeNodeDef->wTextLength = lstrlen(lpTreeNodeDef->lpszText);
  358.             
  359.             // Assign bitmaps created earlier to the first bitmap space which
  360.             // was defined earlier.  PS.  The active bitmap is the bitmap that
  361.             // is displayed when the tree node is highlighted.  Currently, there
  362.             // are two bitmap spaces defined per node.  If more is needed, then
  363.             // the source can be purchased and the number of bitmap spaces can
  364.             // be increased.  In most case only two bitmaps are good enough.
  365.             // If any of the bitmap spaces are not used, then make sure that a
  366.             // NULL handle is assigned to the bitmap space.
  367.             
  368.             lpTreeNodeDef->hBitmap[0] = hbmClosed;
  369.    
  370.             lpTreeNodeDef->hActiveBitmap[0] = hbmClosedActive;
  371.    
  372.             lpTreeNodeDef->chBitmapTypeBits = 0x0002;
  373.             lpTreeNodeDef->hBitmap[1] = hSpiderIcon;
  374.             lpTreeNodeDef->hBitmap[2] = NULL;
  375.             
  376.             // No user-defined data associated with the node.
  377.             lpTreeNodeDef->lpUserData = NULL;
  378.             lpTreeNodeDef->wUserDataSize = 0;            
  379.    
  380.             // Since the tree node definition structure is defined then call
  381.             // the BST_AddChildrenToParent API.  Notice the 0L value.  This
  382.             // is the indicator that this node is the root.  The tree can
  383.             // only have one root.  If the root is NOT defined then calling
  384.             // any other API will cause havoc.
  385.    
  386.             BST_AddChildrenToParent(hwndTree, 0L, 1,lpTreeNodeDef);
  387.             
  388.             // The lpTreeNode member is an important animal.  When 
  389.             // BST_AddChildrenToParent is called with the tree node definitions,
  390.             // the tree control internally allocates the memory to store the
  391.             // tree node definition information, and assigns the pointer to this
  392.             // memory to the tree node definition member 'lpTreeNode'.  Remember,
  393.             // the tree node definition structure is shared memory between the
  394.             // application and the tree control.  The application will use the
  395.             // 'lpTreeNode' value for future references to the new node such as 
  396.             // adding nodes as children.
  397.             
  398.             FREEP(lpTreeNodeDef);
  399.          }
  400.          else
  401.          {
  402.             MessageBox (hwnd, "Out of memory.", "WM_INITDIALOG", MB_OK);
  403.          }
  404.          SetFocus (hwndTree);
  405.          
  406.          // Setup the two edit controls.
  407.          hwndText = GetDlgItem (hwnd, IDC_NODE_TEXT);
  408.          
  409.          SendMessage(hwndText, EM_LIMITTEXT, MAX_TEXT_LENGTH, 0L);
  410.          strcpy( szTextBuffer, "Barking Spider Software, Inc.");
  411.          SendMessage(hwndText, WM_SETTEXT, 0, (LONG)((LPSTR)szTextBuffer)); 
  412.          
  413.          hwndCount = GetDlgItem (hwnd, IDC_COUNT);
  414.          
  415.          SendMessage(hwndCount, EM_LIMITTEXT, 3, 0L);  
  416.          SendMessage(hwndCount, WM_SETTEXT, 0, (LONG)((LPSTR)"8")); 
  417.        
  418.          return FALSE;
  419.  
  420.  
  421.       case WM_BST_SELECT_NOTIF_DBLCLK:
  422.       
  423.       
  424.          // WM_BST_SELECT_NOTIF_DBLCLK is a notification message sent to
  425.          // the application when the user double clicks on a tree node.
  426.          // lParam is a pointer to a notification structure which is owned by
  427.          // the tree control.  DO NOT FREE THIS MEMORY OR ALL HELL WILL 
  428.          // BREAK LOOSE.  The members of the SELECT_NOTIF structure consist
  429.          // of the pointer to the tree node that was selected and a flags
  430.          // member that describes what region of the tree node which was
  431.          // clicked and if the tree node had children or not (OPEN or
  432.          // CLOSED).
  433.  
  434.          lpSelectNotif = (LP_SELECT_NOTIF) lParam;
  435.  
  436.          lpParentTreeNode = lpSelectNotif->lpTreeNode;
  437.          
  438.          // Is the selected tree node OPENED?                 
  439.  
  440.          if(lpSelectNotif->wFlags & NODE_OPENED)
  441.          {
  442.             // Yes... then delete the children
  443.  
  444.             BST_DeleteChildrenOfParent( (HWND)wParam, lpParentTreeNode );
  445.  
  446.             // Close the folder. wParam is the handle of the tree control.
  447.             BST_SetBitmapAndActiveBitmap( wParam,
  448.                                           0,
  449.                                           lpParentTreeNode ,
  450.                                           hbmClosed,
  451.                                           hbmClosedActive);
  452.             }
  453.          else
  454.          {
  455.             // No... then open it and add children if this tree node gots them.
  456.          
  457.             // Get the number of new nodes to be added to the tree as 
  458.             // children of the given parent node.
  459.             GetWindowText ( hwndCount, szCountBuffer, MAX_COUNT_DIGITS + 1);
  460.             wCount = atoi (szCountBuffer);
  461.          
  462.             if(wCount)  // Must have something to add.
  463.             {
  464.                // Get the tree node text and the length.  Add a fudge factor
  465.                // to this length.
  466.                j = GetWindowText ( hwndText, szTextBuffer, MAX_TEXT_LENGTH + 1);
  467.                j += 10;  // 3 digits, terminating 0, space, period, etc
  468.                            
  469.             
  470.                // Define the children as in WM_CREATE: but use the 
  471.                // tree node pointer defined in the SELECT_NOTIF structure 
  472.                // (lParam) as the parent.
  473.  
  474.                lpTreeNodeDef = (LP_TREE_NODE_DEF)
  475.                      MAKEP( GlobalAlloc (GPTR|GMEM_SHARE, 
  476.                       MAKELONG(sizeof(TREE_NODE_DEF)* wCount ,0)),0);
  477.               
  478.                if(lpTreeNodeDef)
  479.                {
  480.                   lpTreeNodeDef2 = lpTreeNodeDef;
  481.                   
  482.                   for (i = 0;
  483.                        i < wCount;
  484.                        i++, lpTreeNodeDef2++)
  485.                   { 
  486.                       if((lpTreeNodeDef2->lpszText = 
  487.                            MAKEP(GlobalAlloc(GPTR|GMEM_SHARE, j),0)) != NULL)
  488.                       { 
  489.                       
  490.                          szBuffer [0] = ' ';                   
  491.                          _itoa (i, &(szBuffer[1]), 10);
  492.                       
  493.                          lstrcpy (lpTreeNodeDef2->lpszText, (LPSTR) szTextBuffer);
  494.                          lstrcat (lpTreeNodeDef2->lpszText, szBuffer);
  495.                       
  496.                          lpTreeNodeDef2->wTextLength =
  497.                                                 lstrlen(lpTreeNodeDef2->lpszText);
  498.    
  499.                          lpTreeNodeDef2->hBitmap[0] = hbmClosed;
  500.                          lpTreeNodeDef2->hActiveBitmap[0] = hbmClosedActive;
  501.                          lpTreeNodeDef2->chBitmapTypeBits = 0x0002;                     
  502.                          lpTreeNodeDef2->hBitmap[1] = hSpiderIcon;
  503.                          lpTreeNodeDef2->hBitmap[2] = NULL;
  504.                          
  505.                          // No user-defined data associated with the node.
  506.                          lpTreeNodeDef2->lpUserData = NULL;
  507.                          lpTreeNodeDef2->wUserDataSize = 0;                         
  508.                      }
  509.                      else
  510.                      {
  511.                         wCount = i;
  512.                         MessageBox ( hwnd, 
  513.                                      "Out of string memory.", 
  514.                                      "WM_BST_SELECT_NOTIF_DBLCLK",
  515.                                      MB_OK);                        
  516.                      }
  517.                   }
  518.                   // Add 'em ...
  519.                   wErrCode = BST_AddChildrenToParent( wParam,
  520.                                                       lpParentTreeNode,
  521.                                                       wCount,
  522.                                                       lpTreeNodeDef); 
  523.                                                       
  524.                   if(HandleAddChildrenError( hwnd, wErrCode) == 0)
  525.                      // Open the folder
  526.                      BST_SetBitmapAndActiveBitmap( wParam,
  527.                                                    0,
  528.                                                    lpParentTreeNode,
  529.                                                    hbmOpen,
  530.                                                    hbmOpenActive);                
  531.                                                       
  532.                  
  533.                   lpTreeNodeDef2 = lpTreeNodeDef;
  534.                                         
  535.                   for (i = 0;
  536.                        i < wCount;
  537.                        i++, lpTreeNodeDef2++)
  538.                   {
  539.                      FREEP(lpTreeNodeDef2->lpszText);
  540.                   }
  541.                   FREEP(lpTreeNodeDef);
  542.                }
  543.                else
  544.                {
  545.                   MessageBox ( hwnd, 
  546.                                "Out of TREE_NODE_DEF memory.", 
  547.                                "WM_BST_SELECT_NOTIF_DBLCLK",
  548.                                MB_OK);
  549.                }               
  550.             }
  551.          }
  552.          return 0;
  553.  
  554.  
  555.       case WM_SYSCOLORCHANGE:
  556.  
  557.          // Sad but true...  The WM_SYSCOLORCHANGE notification has be sent
  558.          // to the tree control since only top level windows get this
  559.          // notification.  Since the colors are going to change in the 
  560.          // tree control, better make sure that the background color of
  561.          // the bitmaps is correct.
  562.     
  563.          // CreateBackgroundMatchedBitmap() is NOT an exported BSS
  564.          // Tree Control API!  It is supplied as a tool for developers to 
  565.          // mask the background of an irregular shaped bitmap to the 
  566.          // windows background color.  This routine only handles 16 color
  567.          // bit bitmaps.
  568.  
  569.  
  570.          if(hwndTree)
  571.          {
  572.             ChangeBitmapToMatchBackground ( GetSysColor (COLOR_WINDOW),
  573.                                             hbmClosed,
  574.                                             IDR_CLOSED_FOLDER);
  575.             ChangeBitmapToMatchBackground ( GetSysColor (COLOR_WINDOW),
  576.                                             hbmOpen,
  577.                                             IDR_OPEN_FOLDER);
  578.             ChangeBitmapToMatchBackground ( GetSysColor (COLOR_HIGHLIGHT),
  579.                                             hbmClosedActive,
  580.                                             IDR_CLOSED_FOLDER);
  581.             ChangeBitmapToMatchBackground ( GetSysColor (COLOR_HIGHLIGHT),
  582.                                             hbmOpenActive,
  583.                                             IDR_OPEN_FOLDER);
  584.             SendMessage (hwndTree, message, wParam, lParam);
  585.          }
  586.          return TRUE;       
  587.  
  588.       case WM_COMMAND:
  589.          switch (wParam)
  590.          {
  591.             case IDOK:
  592.                if(GetFocus () != GetDlgItem (hwnd, IDOK))
  593.                   break;
  594.                   
  595.             case IDCANCEL:
  596.                // Delete all nodes in the tree and free bitmap resources.
  597.                BST_EraseTree( hwndTree);
  598.                DeleteObject(hbmClosed);
  599.                DeleteObject(hbmClosedActive);
  600.                DeleteObject(hbmOpen);
  601.                DeleteObject(hbmOpenActive);                  
  602.                DestroyIcon(hSpiderIcon);
  603.                EndDialog (hwnd, TRUE) ;
  604.                return TRUE ;
  605.          }
  606.          break ;
  607.    }
  608.    return FALSE ;
  609. }
  610.  
  611.  
  612.  
  613. char * npszAddChildrenErrors [] =
  614. {
  615. "Memory allocation failure.",
  616. "Level limit exceeded.",
  617. "The number of nodes supported has been exeeded.",
  618. "Only on root per tree.",
  619. "Given parent node is invalid.",
  620. "Invalid error code"
  621. };                     
  622.  
  623. WORD HandleAddChildrenError( HWND hwnd, WORD wErrCode)
  624. {
  625.    WORD i;
  626.      
  627.    switch (wErrCode)
  628.    {
  629.       case BST_NO_ERROR:
  630.          i = 0;
  631.          break;
  632.  
  633.       case BST_ERR_MEMORY_ALLOC_FAILED:
  634.          i = 1;
  635.          break;
  636.                      
  637.       case BST_ERR_LEVEL_LIMIT_EXCEEDED:
  638.          i = 2;
  639.          break;
  640.                      
  641.       case BST_ERR_TOO_MANY_NODES:
  642.          i = 3;
  643.          break;
  644.                  
  645.       case BST_ERR_ONLY_ONE_ROOT_ALLOWED: 
  646.          i = 4;
  647.          break;
  648.                      
  649.       case BST_ERR_INVALID_PARENT_FOR_INSERTION:
  650.          i = 5;
  651.          break;
  652.                
  653.       default:
  654.         i = 6;
  655.         break;
  656.    }
  657.    if ( i != 0)
  658.    {
  659.       MessageBox ( hwnd, 
  660.                    npszAddChildrenErrors[i-1],
  661.                    "BST_AddChildrenToParent",
  662.                     MB_OK);
  663.    }
  664.    return i;   
  665. }
  666.  
  667.  
  668. /***************************************************************************/
  669. /* Below are support routines for the 16 color bitmaps used in the tree */
  670. // Enjoy!
  671.  
  672. HBITMAP CreateBackgroundMatchedBitmap (DWORD dwrgbBackground, int nBitmapResouce)
  673. {
  674.    HANDLE             hBitmap;
  675.    HANDLE             hRes;
  676.    HANDLE             hResMem;
  677.    LPBITMAPINFOHEADER lpbi;
  678.    DWORD FAR *        lpColorTable;
  679.    LPSTR              lpBits;
  680.    int                bc;
  681.    HDC                hdc;
  682.       
  683.    hRes = FindResource ( hInst,
  684.                          MAKEINTRESOURCE (nBitmapResouce),
  685.                          RT_BITMAP);
  686.                               
  687.    hResMem = LoadResource (hInst, hRes);
  688.    lpbi = (LPBITMAPINFOHEADER) LockResource (hResMem);
  689.          
  690.    lpColorTable = (DWORD FAR *)(lpbi + 1);
  691.    lpBits = (LPSTR) (lpColorTable + 16);
  692.          
  693.    bc = (lpBits[0] & 0xF0) >> 4;
  694.          
  695.    lpColorTable [bc] = RGB( GetBValue (dwrgbBackground),
  696.                             GetGValue (dwrgbBackground),
  697.                             GetRValue (dwrgbBackground));
  698.    hdc = GetDC(NULL);
  699.    hBitmap =  CreateDIBitmap ( hdc,
  700.                                lpbi,
  701.                                (DWORD) CBM_INIT,
  702.                                lpBits,
  703.                                (LPBITMAPINFO) lpbi,
  704.                                DIB_RGB_COLORS);
  705.    ReleaseDC(NULL, hdc);
  706.    UnlockResource (hResMem);
  707.    FreeResource(hResMem);
  708.    return hBitmap;
  709. }
  710.  
  711.  
  712. char   rgchBits [2048];
  713.  
  714. short ChangeBitmapToMatchBackground ( DWORD dwrgbBackground,
  715.                                       HANDLE hBitmap,
  716.                                       int nBitmapResouce)
  717. {
  718.    int                bc;
  719.    HDC                hdc;
  720.    LPBITMAPINFO       lpbi;
  721.    HANDLE             hRes;
  722.    HANDLE             hResMem;
  723.  
  724.    hRes = FindResource ( hInst,
  725.                          MAKEINTRESOURCE (nBitmapResouce),
  726.                          RT_BITMAP);
  727.                               
  728.    hResMem = LoadResource (hInst, hRes);
  729.    lpbi = ( LPBITMAPINFO ) LockResource (hResMem);
  730.    
  731.    hdc = GetDC (NULL);
  732.    
  733.    GetDIBits ( hdc,
  734.                hBitmap,
  735.                0,
  736.                LOWORD(lpbi->bmiHeader.biHeight),
  737.                rgchBits,
  738.                lpbi,
  739.                DIB_RGB_COLORS);
  740.  
  741.    bc = (rgchBits[0] & 0xF0) >> 4;
  742.          
  743.    lpbi->bmiColors[bc].rgbBlue = GetBValue (dwrgbBackground);
  744.    lpbi->bmiColors[bc].rgbGreen = GetGValue (dwrgbBackground);
  745.    lpbi->bmiColors[bc].rgbRed =  GetRValue (dwrgbBackground);
  746.    lpbi->bmiColors[bc].rgbReserved = 0;
  747.  
  748.    SetDIBits(hdc,
  749.              hBitmap,
  750.              0,
  751.              LOWORD(lpbi->bmiHeader.biHeight),
  752.              rgchBits,
  753.              lpbi,
  754.              DIB_RGB_COLORS);
  755.  
  756.    ReleaseDC(NULL, hdc );
  757.    UnlockResource (hResMem);
  758.    FreeResource(hResMem);
  759.    return 0;
  760. }
  761.  
  762. /*--------------------------------- EOF -----------------------------------*/
  763.  
  764.