Important: The information in this document is obsolete and should not be used for new development.
Creating a List
To create a list, you can use theLNewfunction. Listing 4-1 shows a typical use of theLNewfunction to create a vertically scrolling list in a rectangular space in a window.Listing 4-1 Creating a list with a vertical scroll bar
FUNCTION MyCreateVerticallyScrollingList (myWindow: WindowPtr; myRect: Rect; columnsInList: Integer; myLDEF: Integer): ListHandle; CONST kDoDraw = TRUE; {always draw list after changes} kNoGrow = FALSE; {don't leave room for size box} kIncludeScrollBar = TRUE; {leave room for scroll bar} kScrollBarWidth = 15; {width of vertical scroll bar} VAR myDataBounds: Rect; {initial dimensions of the list} myCellSize: Point; {size of each cell in list} BEGIN {specify dimensions of the list} {start with a list that contains no rows} SetRect(myDataBounds, 0, 0, columnsInList, 0); {let the List Manager calculate the size of a cell} SetPt(myCellSize, 0, 0); {adjust the rectangle to leave room for the scroll bar} myRect.right := myRect.right - kScrollBarWidth; {create the list} MyCreateVerticallyScrollingList := LNew(myRect, myDataBounds, myCellSize, myLDEF, myWindow, kDoDraw, kNoGrow, NOT kIncludeScrollBar, kIncludeScrollBar); END;TheLNewfunction called in the last line of Listing 4-1 takes a number of parameters that let you specify the characteristics of the list you wish to create.The first parameter to
LNewsets the rectangle for the list's visible rectangle, specified in local coordinates of the window specified in the fifth parameter toLNew. Because this rectangular area does not include room for scroll bars, theMyCreateVerticallyScrollingListfunction adjusts the right of this rectangle to leave enough room.The second parameter to
LNewspecifies the data bounds of the list. By setting thetopLeftfield of this rectangle to (0,0), you can use thebotRightfield to specify the number of columns and rows you want in the list. TheMyCreateVerticallyScrollingListfunction initially creates a list of no rows. While your application is free to preallocate rows when creating a list, it is often easier to only preallocate columns and then add rows after creating the list, as described in the next section.The third parameter is the size of a cell. By setting this parameter to (0,0), you let the List Manager compute the size automatically. The algorithm the List Manager uses to compute this size is given in the discussion of the
cellSizefield of the list record in "About the List Manager" beginning on page 4-13.To specify that you wish to use the default list definition procedure, pass 0 as the fourth parameter to
LNew. To use a custom list definition procedure, pass the resource ID of the list definition procedure. Note that the code for the appropriate list definition procedure is loaded into your application's heap; the code for the default list definition procedure is about 150 bytes in size.In the sixth parameter to
LNew, your application can specify whether the List Manager should initially enable the automatic drawing mode. When this mode is enabled, the List Manager always redraws the list after changes. Usually, your application should set this parameter toTRUE. This does not preclude your application from temporarily disabling the automatic drawing mode.The last three parameters to
LNewspecify whether the List Manager should leave room for a size box, whether it should include a horizontal scroll bar, and whether it should include a vertical scroll bar. Note that while the List Manager draws scroll bars automatically, it does not draw the grow icon in the size box. Usually, your application can draw the grow icon by calling the Window Manager'sDrawGrowIconprocedure.The
LNewfunction creates a list according your specifications and returns a handle to the list's list record. Your application uses the returned handle to refer to the list when using other List Manager routines.Lists are often used in dialog boxes. Because the Control Manager does not define a control for lists, you must define a list in a dialog item list as a user item. Listing 4-2 shows an application-defined procedure that creates a one-column, text-only list in a dialog box.
Listing 4-2 Installing a list in a dialog box
FUNCTION MyCreateTextListInDialog (myDialog: DialogPtr; myItemNumber: Integer) : ListHandle; CONST kTextLDEF = 0; {resource ID of default LDEF} VAR myUserItemRect: Rect; {enclosure of user item} myUserItemType: Integer; {for GetDialogItem} myUserItemHdl: Handle; {for GetDialogItem} BEGIN GetDialogItem(myDialog, myItemNumber, myUserItemType, myUserItemHdl, myUserItemRect); MyCreateTextListInDialog := MyCreateVerticallyScrollingList(myDialog, myUserItemRect, 1, kTextLDEF); END;TheMyCreateTextListInDialogfunction defined in Listing 4-2 calls theMyCreateVerticallyScrollingListfunction defined in Listing 4-1, after finding the rectangle in which to install the new list by using the Dialog Manager'sGetDialogItemprocedure. For more information on the Dialog Manager, see Inside Macintosh: Macintosh Toolbox Essentials.The List Manager does not automatically draw a 1-pixel border around a list. Listing 4-3 shows an application-defined procedure that draws a border around a list.
Listing 4-3 Drawing a border around a list
PROCEDURE MyDrawListBorder (myList: ListHandle); VAR myBorder: Rect; {box for list} myPenState: PenState; {current status of pen} BEGIN myBorder := myList^^.rView; {get view rectangle} GetPenState(myPenState); {store pen state} PenSize(1, 1); {set pen to 1 pixel} InsetRect(myBorder, -1, -1); {adjust rectangle for framing} FrameRect(myBorder); {draw border} SetPenState(myPenState); {restore old pen state} END;TheMyDrawListBorderprocedure defined in Listing 4-3 uses standard QuickDraw routines to save the state of the pen, set the pen size to 1 pixel, draw the border, and restore the pen state.When you are finished using a list, you should dispose of it using the
LDisposeprocedure, passing a handle to the list as the only parameter. TheLDisposeprocedure disposes of the list record, as well as the data associated with the list; however, it does not dispose of any application-specific data that you might have stored in a relocatable block specified by theuserHandlefield of the list record. Thus, if you use this field to store a handle to a relocatable block, you should dispose of the relocatable block before callingLDispose.