home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright (c) 1993 by Barking Spider Software, Inc. All rights reserved.
-
- Filename...: listdem2.c
-
- Version,,,,: 1.0
-
- Language...: Microsoft C/C++ 7.0
-
- Model......: Small
-
- Environment: Microsoft Windows 3.1
-
- Description: This source module demonstrates the BSS List Control as part
- of a dialog template. The dialog box template in listdem2.dlg
- was created with the Dialog Editor. The Dialog Editor
- is shipped with the Windows 3.1 SDK. Since the BSS List
- Control has custom control support built in, all that was
- required to use the tree control in the Dialog Editor was to
- select the File menu item, then select Open Custom, type in
- the path for treectrl.dll and hit return. Select New under
- the File menu item to get an empty dialog box frame.
- The Dialog Editor Toolbox will then contain a button
- representing the tree/list control. Select this button, drag
- the mouse over the new dialog box frame and stretch the
- custom tree/list control into the desired place.
-
- In the sample code below, a simple top level overlapped
- window is created with a couple of menu items. From these
- menu items, the user can create a modal dialog box or the
- user can exit the application. If the user selects the
- menu item List Dialog, a modal dialog box will appear that
- contains a BSS List Control.
-
- The List Control is populated with list items that
- display an icon and text. The icon is the infamous BSS
- Spider icon.
-
- When the user decides to quit the dialog box, hitting the
- Enter key, Esc key, or clicking on push button will exit the
- dialog box.
- Notes......:
-
- History....:
-
- Author.....: Peter J. Kaufman
- */
-
- #include <windows.h>
- #include "listdem2.h" // Listdem2 function prototypes.
- #include "..\bscore.h" // BSS List Control structures, notification messages,
- // error codes...
- #include "..\bslist.h" // BSS List Control function prototypes for the
- // exported APIs.
- #include <string.h>
- #include <stdlib.h>
- #include "spider.h" // Static array of strings used to create list items.
-
- static char szAppName[] = "ListDem2";
-
- HANDLE hInst ;
-
-
- /*****************************************************************************
- int PASCAL WinMain ( HANDLE hInstance,
- HANDLE hPrevInstance,
- LPSTR lpszCmdLine,
- int nCmdShow);
-
- *****************************************************************************/
-
- int PASCAL WinMain ( HANDLE hInstance,
- HANDLE hPrevInstance,
- LPSTR lpszCmd,
- int nCmdShow)
- {
- HWND hwnd ;
- MSG msg ;
- WNDCLASS wndclass ;
-
- hInst = hInstance ;
-
- if (!hPrevInstance)
- {
- wndclass.style = CS_HREDRAW | CS_VREDRAW ;
- wndclass.lpfnWndProc = ListDemo2WndProc ;
- wndclass.cbClsExtra = 0 ;
- wndclass.cbWndExtra = 0 ;
- wndclass.hInstance = hInst;
- wndclass.hIcon = LoadIcon (hInst,
- MAKEINTRESOURCE(IDR_LISTDEMO_ICON)) ;
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
- wndclass.hbrBackground = COLOR_APPWORKSPACE + 1;
- wndclass.lpszMenuName = szAppName;
- wndclass.lpszClassName = szAppName;
-
- RegisterClass (&wndclass) ;
- }
-
- hwnd = CreateWindow (szAppName,
- "Barking Spider Software, Inc. List Demo 2 - Dialog",
- WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- hInstance,
- NULL);
-
- ShowWindow (hwnd, nCmdShow) ;
- UpdateWindow (hwnd) ;
-
- while (GetMessage (&msg, NULL, 0, 0))
- {
- TranslateMessage (&msg) ;
- DispatchMessage (&msg) ;
- }
- return msg.wParam ;
- }
-
-
-
- /*****************************************************************************
- long FAR PASCAL _export ListDemo2WndProc ( HWND hwnd,
- UINT message,
- UINT wParam,
- LONG lParam)
-
- This is the window procedure for the top level window of this application.
- When the user selects the menu item List Dialog, a modal dialog box based on
- the dialog box template in listdem2.dlg will be created.
- *****************************************************************************/
-
-
- long FAR PASCAL _export ListDemo2WndProc ( HWND hwnd,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- static FARPROC lpfnListDlgProc ;
- static HANDLE hInstance ;
-
- switch (message)
- {
- case WM_CREATE:
- hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
- lpfnListDlgProc = MakeProcInstance ((FARPROC) ListDlgProc,
- hInstance) ;
- return 0 ;
-
- case WM_COMMAND:
- switch (wParam)
- {
- case IDM_LIST_DIALOG:
- DialogBox (hInstance,
- MAKEINTRESOURCE(IDD_DIALOG),
- hwnd,
- lpfnListDlgProc);
- return 0;
-
- case IDM_EXIT:
- SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
- return 0;
- }
- break ;
-
- case WM_DESTROY :
- PostQuitMessage (0) ;
- return 0 ;
- }
- return DefWindowProc (hwnd, message, wParam, lParam) ;
- }
-
-
-
-
- /*****************************************************************************
- BOOL FAR PASCAL _export ListDlgProc ( HWND hwnd,
- UINT message,
- UINT wParam,
- LONG lParam);
-
-
- This is the dialog box procedure for the dialog box template defined in
- listdem2.dlg. It manages the tree control, the edit controls, and the
- push button. The dialog boxes two primary functions are:
-
- 1) Demonstrate the list control in a dialog box.
- 2) Allow the user to "play" with the list control.
-
- In WM_INITDIALOG, the BSS Spider icon is loaded, the bitmap spaces are
- defined, the space between the text and the bitmap is defined, and the
- list items are added to the list.
-
- When the user is tire of playing with the list control, pressing the push
- button will end the fun.
- ******************************************************************************/
-
- HWND hwndList; // Tree control handle
- HICON hSpiderIcon;
-
- #define MAX_LIST_ITEMS (sizeof(szSpider)/sizeof(char *))
-
- #define SPACE_BEFORE_TEXT 4
-
-
- BOOL FAR PASCAL _export ListDlgProc ( HWND hwnd,
- UINT message,
- UINT wParam,
- LONG lParam)
- {
- LP_TREE_NODE_DEF lpTreeNodeDef; // Pointer to list node definition
- LP_TREE_NODE_DEF lpTreeNodeDef2;
- LP_SELECT_NOTIF lpSelectNotif; // Pointer to the notification struct.
- WORD i;
- WORD wErrCode;
- WORD wMaxListItems;
-
- switch (message)
- {
- case WM_INITDIALOG:
-
- // Get the handle of the list control
- hwndList = GetDlgItem (hwnd, IDC_LIST);
-
-
- BSL_SetXSpaceBeforeText( hwndList, SPACE_BEFORE_TEXT );
-
- // Bitmaps spaces are regions where bitmaps are displayed for the
- // list item. Bitmap spaces encompass the bitmaps or icons.
- // The bitmap spaces are placed left of the text.
-
- // From left to right the left most bitmap space has an index
- // value of 0, the next bitmap space has an index value of 1,
- // and so on.
- // When a bitmap space is defined, it is defined for the entire
- // list, for all list items. For example, if the left most bitmap
- // space is defined to have a width of 30 pixels and a height of
- // 20 pixels, then all the bitmaps placed in this bitmap space
- // for all the list items will have to fit into these dimensions.
- // The reasoning behind this, is that it forces column alignment
- // of the bitmaps for a given bitmap space and offers a
- // consistency in hit testing. Hit testing is performed on the
- // bitmap space, not just on the bitmap.
-
- // Below, the left most bitmap space is defined. The max width
- // and height are defined. The first argument is the BSS List
- // Control handle, the second is the bitmap space identifier or
- // index. The third and fourth arguments are the width and
- // height respectively. The last argument signals to the BSS List
- // Control whether to center or left justify the currently
- // assigned bitmap in this bitmap space. TRUE means center,
- // FALSE means left justify.
-
- // Instead of hard code values for the width and height, another
- // could be taken. If the item to be assigned to the below
- // bitmap space is a bitmap, then a call to
- // GetObject (hBitmap, sizeof(BITMAP), (LPSTR) &bm);
- // could be called and the dimensions of the bitmap could be
- // used along with some padding to define the width and height
- // of the bitmap space.
-
- // If the item to be assigned to the below bitmap space is an
- // icon, then the values from the calls to
- // GetSystemMetrics (SM_CXICON) and GetSystemMetrics (SM_CYICON)
- // could be used along with some padding to define the width
- // and height of the bitmap space. Since the Windows GDI
- // call DrawIcon ( ) is used to draw the icon by the tree
- // control, if a bitmap space is to contain an icon then the
- // width and height must be defined by the described method above.
- // The required height and width are a result of the Windows API,
- // DrawIcon(), displaying the whole ICON and not offering any
- // clipping functionality. The application can determine
- // the minimum height and width bitmap space needed by the List
- // Control, by calling the Windows API, GetSystemMetrics().
- // Calling GetSystemMetrics() with SM_CXICON will return the width
- // of an ICON and calling GetSystemMetrics() with SM_CYICON will
- // return the height of an ICON. After this is accomplished, the
- // application can place additional margins on the height and
- // width of the bitmap space for visuals.
-
- // The advantages of using ICONs instead of bitmaps are:
- // 1) Icon editors are readily available and offer flexibility to
- // the presentation of the image.
- // 2) MORICONS.DLL offer an array of icons to use as templates
- // for original images. MORICONS.DLL is shipped with Windows 3.1.
- // 3) DrawIcon()s will respect the image created by the developer in
- // the sense of background masking, etc.
- // One major disadvantage is that the size of the ICON is fixed
- // where bitmaps can be any size and clipped to fit in a smaller
- // bitmap space.
-
- BSL_SetBitmapSpace( hwndList,
- 0,
- GetSystemMetrics (SM_CXICON) + 4,
- GetSystemMetrics (SM_CYICON) + 4,
- TRUE);
-
- hSpiderIcon = LoadIcon ( hInst, MAKEINTRESOURCE(IDR_LISTDEMO_ICON));
-
- // Now, the fun part... Defining list items.
-
- // In this example, all of the list items are defined in one
- // call to BSL_AddListItems ( ), even though several calls to
- // BSL_AddListItems ( ) could have been made instead. Making
- // several calls instead of one offer the application
- // multitasking and low memory usage. Since the list we are
- // creating is not very large, one call will be enough.
-
- // The first thing, allocate MAX_LIST_ITEMS worth of
- // TREE_NODE_DEF structures, one for each list item to be added
- // to the BSS List Control. It is best if this memory is
- // initialize to zero. Any members of the TREE_NODE_DEF structure
- // that are not defined must be initialized with zero. The
- // definition structure, TREE_NODE_DEF, is the vehicle that the
- // application uses to define list items to the BSS List Control.
- // This memory is the property of the application. It's contents
- // are copied to the list control. Once the node is defined, this
- // memory can be freed.
-
- // Note. GlobalAlloc ( ) returns the segment and not the handle
- // of the allocated memory since the GMEM_FIXED flag is applied
- // which requests that the memory block is fixed in memory. Also,
- // since the GMEM_ZEROINIT flag is applied, the memory is zeroed.
- // MAKEP ( ) macro converts this segment into a long
- // pointer (segment:0). The GMEM_SHARE flag is used since
- // the pointer is passed to the list control in the process
- // of defining new list items.
-
- wMaxListItems = MAX_LIST_ITEMS;
-
- lpTreeNodeDef = (LP_TREE_NODE_DEF) MAKEP( GlobalAlloc (
- GMEM_FIXED|GMEM_ZEROINIT|GMEM_SHARE,
- MAKELONG(sizeof(TREE_NODE_DEF)*
- wMaxListItems ,0)),0);
-
- if( lpTreeNodeDef ) // If the above memory allocation is success...
- {
- lpTreeNodeDef2 = lpTreeNodeDef;
- for (i = 0;
- i < wMaxListItems;
- i++, lpTreeNodeDef2++)
- {
- // Assign the text that will be displayed for the list item.
-
- // Normally, the list control will allocate wTextLength + 1
- // worth of memory to store a copy of the string pointed to
- // by lpszText when the list item is created since the
- // supplied pointer can become invalid if the string it
- // points to is moved or deleted in the future.
-
- lpTreeNodeDef2->lpszText = szSpider [i];
-
- // Assign the length of the above text to the wTextLength
- // member. This tells the list control, how many characters
- // to display.
-
- // Note. If the sign bit of the wTextLength member is set to
- // 1 by the application then this signals the list control
- // NOT to allocate memory for the string pointed to by
- // lpszText, above, but just store and use the supplied
- // string pointer directly to display the tree node's text.
- // This would work in the case of the string which was
- // assigned to the lpszText member, above, because it is a
- // constant and is guaranteed to be in the application's
- // data segment for the life of the application. It will
- // not be applied here though, since this is suppose to be
- // a simple demo. The advantage of this technique is that
- // no allocation of memory for the string is needed thus
- // conserving resources and increasing speed.
-
- lpTreeNodeDef2->wTextLength
- = lstrlen(lpTreeNodeDef2->lpszText);
-
- // Now it's time to assign bitmap handles created earlier to
- // the first bitmap space which was defined earlier as well.
- // Currently, there are three bitmap spaces allowed to be
- // defined per item. If more are needed, then the source
- // can be purchased and the number of bitmap spaces can be
- // increased. In most case only two bitmaps are good
- // enough.
-
- // If any of the bitmap spaces are not used or the
- // corresponding bitmap/icon handle will be defined later,
- // then make sure that all unused hBitmap[] and
- // hActiveBitmap[] array elements are set to NULL. The
- // tree control does not check the validity of a
- // bitmap/icon handle.
-
- // Bitmap/icon handles can be assigned to bitmap spaces, at
- // a later time by calling BSL_SetBitmap ( ) and/or
- // BSL_SetIcon ( ).
-
- lpTreeNodeDef2->hBitmap[0] = hSpiderIcon;
- lpTreeNodeDef2->chBitmapTypeBits = 0x0001;
- lpTreeNodeDef2->hActiveBitmap[0] = NULL;
-
- // Notice that the hActiveBitmap[] counterparts are not
- // set to NULL. The tree control will NOT reference
- // their associated hActiveBitmap[] if hBitmap[] is
- // set to NULL.
-
- lpTreeNodeDef2->hBitmap[1] = NULL;
- lpTreeNodeDef2->hBitmap[2] = NULL;
-
- // No user-defined data associated with the node.
- lpTreeNodeDef2->lpUserData = NULL;
- lpTreeNodeDef2->wUserDataSize = 0;
- }
-
- // Add the list items to the list. Now the list is complete
- // and the user will now be able to play, play, play.
-
- wErrCode = BSL_AddListItems( hwndList,
- wMaxListItems,
- lpTreeNodeDef);
-
- HandleAddChildrenError( hwnd, wErrCode);
-
- FREEP(lpTreeNodeDef);
-
- // Set focus to the tree control, show it, and let
- // the user knock herself or himself out.
-
- SetFocus (hwndList);
- ShowWindow (hwndList, SW_SHOW);
- }
- else
- {
- MessageBox (hwnd, "Out of memory.", "WM_CREATE",MB_OK);
- }
- SetFocus (hwndList);
- return FALSE;
-
-
- // This is not used in the example but I thought you would like to
- // have a starting piece of code to handle double clicks on the
- // list items.
-
- case WM_BST_SELECT_NOTIF_DBLCLK:
-
- // WM_BST_SELECT_NOTIF_DBLCLK is a notification message sent to
- // the application when the user:
- // 1) double clicks on a list item,
- // 2) hits the carriage return (acts as if the currently highlighted
- // list item was double clicked on.),
- // lParam is a pointer to a SELECT_NOTIF notification structure which
- // is owned by the list control. DO NOT FREE THIS MEMORY OR ALL
- // HELL WILL BREAK LOOSE. The members of the SELECT_NOTIF structure
- // consist of the pointer to the list item that was selected and a
- // flags member that describes what region of the list item which
- // was clicked.
-
- lpSelectNotif = (LP_SELECT_NOTIF) lParam;
-
- return 0;
-
-
- case WM_SYSCOLORCHANGE:
-
- // Sad but true... The WM_SYSCOLORCHANGE notification has be sent
- // to the list control since only top level windows get this
- // notification.
-
- if(hwndList)
- SendMessage (hwndList, message, wParam, lParam);
- return TRUE;
-
- case WM_COMMAND:
- switch (wParam)
- {
- case IDOK:
- if(GetFocus () != GetDlgItem (hwnd, IDOK))
- break;
-
- case IDCANCEL:
- // Delete all list items in the list and free icon resources.
- BSL_ResetList( hwndList);
- DestroyIcon(hSpiderIcon);
- EndDialog (hwnd, TRUE) ;
- return TRUE ;
- }
- break ;
- }
- return FALSE ;
- }
-
-
-
- char * npszAddChildrenErrors [] =
- {
- "Memory allocation failure.",
- "Level limit exceeded.",
- "The number of nodes supported has been exeeded.",
- "Only on root per tree.",
- "Given parent node is invalid.",
- "Invalid error code"
- };
-
- WORD HandleAddChildrenError( HWND hwnd, WORD wErrCode)
- {
- WORD i;
-
- switch (wErrCode)
- {
- case BST_NO_ERROR:
- i = 0;
- break;
-
- case BST_ERR_MEMORY_ALLOC_FAILED:
- i = 1;
- break;
-
- case BST_ERR_LEVEL_LIMIT_EXCEEDED:
- i = 2;
- break;
-
- case BST_ERR_TOO_MANY_NODES:
- i = 3;
- break;
-
- case BST_ERR_ONLY_ONE_ROOT_ALLOWED:
- i = 4;
- break;
-
- case BST_ERR_INVALID_PARENT_FOR_INSERTION:
- i = 5;
- break;
-
- default:
- i = 6;
- break;
- }
- if ( i != 0)
- {
- MessageBox ( hwnd,
- npszAddChildrenErrors[i-1],
- "BST_AddChildrenToParent",
- MB_OK);
- }
- return i;
- }
-
- /*--------------------------------- EOF -----------------------------------*/
-
-