Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: More Macintosh Toolbox /
Chapter 4 - List Manager / Using the List Manager


Manipulating List Cells

In addition to the LSetCell procedure, the List Manager provides four procedures, LAddToCell, LClrCell, LGetCellDataLocation, and LGetCell, that allow you to manipulate cell item data. You can use the LAddToCell procedure to append data to list items and the LClrCell procedure to remove all data from a list item. The LGetCellDataLocation procedure indicates the location of the beginning of a cell's data within the cells field of the list record as well as the length of that data, and the LGetCell procedure copies a cell's data to a buffer that your application specifies.

Listing 4-11 illustrates the use of LClrCell to clear the data from all cells in a list.

Listing 4-11 Clearing all cell data

PROCEDURE MyClearAllCellData (myList: ListHandle);
VAR
   aCell: Cell;
BEGIN
   SetPt(aCell, 0, 0);
   REPEAT
      LClrCell(aCell, myList);
   UNTIL NOT LNextCell(TRUE, TRUE, aCell, myList);
END;
Because LClrCell simply does nothing if passed a cell not in the list, the MyClearAllCellData procedure defined in Listing 4-11 will not crash when attempting to clear the first cell even if there are no cells in the list.

Listing 4-12 uses the LGetCell procedure to return the data of a specific cell.

Listing 4-12 Getting a copy of the data of a cell

PROCEDURE MyGetCellData (dataPtr: Ptr; VAR dataLen: Integer;
                         aCell: Cell; myList: ListHandle);
BEGIN
   LGetCell(dataPtr, dataLen, aCell, myList);
END;
The LGetCell procedure copies cell data to memory beginning at the location specified by dataPtr. It copies only the number of bytes specified by the value passed in the dataLen parameter; it returns in that parameter the number of bytes actually copied.

Because the LGetCell procedure duplicates existing bytes of memory, if your application needs to access a cell's data but does not need to manipulate the data, then it should use the LGetCellDataLocation procedure to access cell data directly.
Listing 4-13 uses the LGetCellDataLocation procedure to get a cell's data.

Listing 4-13 Directly accessing a cell's data

PROCEDURE MyGetDirectAccessToCellData
                  (VAR offset: Integer; VAR len: Integer;
                   aCell: Cell; myList: ListHandle);
BEGIN
   LGetCellDataLocation(offset, len, aCell, myList);
END;
The LGetCellDataLocation procedure simply returns in the offset and len parameters the offset and length of the appropriate cell's data within the cells field of the list record.

Listing 4-14 shows an application-defined procedure that uses LGetCellDataLocation in conjunction with the LSetCell procedure
and the LAddRow function to add a new string to a one-column, alphabetical text-only list. To compare two strings, the procedure uses the Text Utilities CompareText function, which requires that data be specified by a pointer and length, thus making LGetCellDataLocation perfect for this purpose. For more information on the CompareText function, see Inside Macintosh: Text.

Listing 4-14 Adding an item to a one-column, alphabetical text list

PROCEDURE MyAddItemAlphabetically (myList: ListHandle; myString: Str255);
VAR
   found:      Boolean;                      {flag variable}
   myRows:     Integer;                      {number of rows in list}
   currentRow: Integer;                      {row being examined}
   cellDataOffset, cellDataLength: Integer;  {data being compared to string}
   aCell:      Cell;                         {cell coordinates}
BEGIN
   found := FALSE;                           {initialize flag variable}
   WITH myList^^.dataBounds DO
      myRows := bottom - top;                {compute number of rows}
   currentRow := -1;                         {start before first row}
   WHILE NOT found DO
   BEGIN                                     {try to insert before next row}
      currentRow := currentRow + 1;          {move to next row}
      IF currentRow = myRows THEN            {past the end of the list?}
         found := TRUE                       {insert string at this row}
      ELSE
      BEGIN
         SetPt(aCell, 0, currentRow);        {prepare to check cell data}
                                             {find location of data}
         LGetCellDataLocation(cellDataOffset, cellDataLength, aCell, myList);
         HLockHi(Handle(myList^^.cells));    {lock list data in memory}
         IF CompareText(@myString[1],        {skip length byte of string}
                        Ptr(ORD4(myList^^.cells^) + cellDataOffset),
                        Length(myString), cellDataLength, gitl2Hdl) = -1 THEN
            found := TRUE;                   {new string should precede }
                                             { this row's string}
         HUnlock(Handle(myList^^.cells));    {unlock list data}
      END;
   END;
                                             {add new row for string}
   currentRow := LAddRow(1, currentRow, myList);
   SetPt(aCell, 0, currentRow);              {prepare to set cell data}
                                             {set data}
   LSetCell(@myString[1], Length(myString), aCell, myList);
END;
The MyAddItemAlphabetically procedure defined in Listing 4-14 simply compares a string to the text in each row of a list, until the string follows the row text alphabetically or until there are no more rows, that is, the row number (which is 0-based) is equal to the number of rows, in which case the string is appended to the end of the list.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
6 JUL 1996