Okay, I have been tinkering with this for quite a while and have not
"solved"
it yet.

I have a Modal Dialog that has a table (with 1 column) with a bunch of
rows.  When the modal dialog appears, I want to pre-select one of the
rows based on some criteria.  So, I am using TblSelectItem() to select
the row I want.  Problem is, the item will highlight for a brief moment
and then unhighlight.  I am thinking that when I issue the "TblSelectItem()"
command, it highlights the cell, but then later the table gets redrawn
and effectively gets unhighlighted.  I have twiddled around with placing
the TblSelectItem() call in various locations and inserting calls
to TblRedrawTable() and such and finally got it working right
on POSE.  So then I load it onto my Palm device and it is not working
there :(  Funny thing is, once I scroll the table around, the row is
properly highlighted.  The only thing the Scroll() function does is
call my Load() function and then call TblRedrawTable()


Can anyone help me out here?

Here is my code (I have put a bunch of ********** in the important areas):

---------------
This function pops up the form and starts an evenloop to process events
until an item is selected or the cancel button is pressed:
Boolean chooseLookupCode (const char * title, LookupCode * lookupCode, ULong
dbType, char *dbName,
      FormEventHandlerPtr oldHandler,
      LookupCodeSelectCB cb, void *cbd)
{
 // Create and display the form
 RectangleType r;
 FormPtr previousForm = FrmGetActiveForm();
 FormPtr frmP = FrmInitForm (CodeChooserForm);
 Word error;
 EventType event;

 callback = cb;
 callbackData = cbd;

 // Since I am not using Save Backup Bits, I need to erase part of the old
form
 FrmGetFormBounds (frmP, &r);
 WinEraseRectangle (&r, 0);
 FrmSetActiveForm (frmP);
 FrmSetEventHandler (frmP, CodeChooserFormHandleEvent);

 CodeChooserFormInit (frmP, title, lookupCode, dbType, dbName);
 FrmDrawForm (frmP);

 // ***********This call seems to make POSE highlight the row properly
***************
 TblDrawTable (FrmGetObjectPtr (frmP, FrmGetObjectIndex (frmP,
CodeChooserCodeTable)));
 // Start our own little event handler until the user presses the Cancel
 // button or selects an item.
 do {
  EvtGetEvent (&event, evtWaitForever);

  if (!SysHandleEvent (&event))
   if (!MenuHandleEvent (0, &event, &error))
    FrmDispatchEvent (&event);
 } while ((event.eType != appStopEvent) && (lcStatus == LC_NONE));
 if (event.eType == appStopEvent)
 {
  // Place this event back on the queue for our main event handler
  EvtAddEventToQueue (&event);
 }

 CodeChooserFormFinish (frmP);

 // Since I am not using Save BackupBits, I need to erase this form and
redraw the other form
 FrmEraseForm (frmP);
 FrmSetActiveForm (previousForm);
 FrmSetEventHandler (previousForm, oldHandler);
 FrmDrawForm (previousForm);
 FrmDeleteForm (frmP);

 return (lcStatus == LC_SELECTED);
}


--------------------------------
Here is my Init function so you can see how I setup the table:

static void CodeChooserFormInit(FormPtr frmP, const char * title,
        LookupCode * lookupCode, ULong dbType, char *dbName)
{
 Boolean   created;
 TablePtr  tableP;
 ListPtr   listP;
 short   s;
 unsigned int numRows;
 unsigned int i;
 CharPtr   sStr;

 lcStatus = LC_NONE;

 FrmSetTitle (frmP, (char *)title);

 // Open/Create the database
 OpenOrCreateDB (&db, dbType, appFileCreator, dmModeReadWrite, 0, dbName,
&created);
 initializeDB (created, title);

 // ******************** Here is where I define the table rows as Custom
******************
 // Define the rows/columns of the table
 tableP = FrmGetObjectPtr (frmP, FrmGetObjectIndex (frmP,
CodeChooserCodeTable));
 numRows = TblGetNumberOfRows (tableP);

 for (i = 0; i < numRows; ++i)
 {
  TblSetItemStyle (tableP, i, 0, customTableItem);
 }
 TblSetColumnUsable (tableP, 0, true);
// ********** Here I define the CustomDraw procedure ********************
 TblSetCustomDrawProcedure (tableP, 0, CodeChooserDrawCodeRecord);

 // Initialize the Category Popup
 s = 0;
 currentCategory = dmAllCategories;
 topVisibleItem = 0;
 listP = FrmGetObjectPtr (frmP, FrmGetObjectIndex (frmP,
CodeChooserCategoryList));
 LstSetSelection (listP, s);
 sStr = LstGetSelectionText (listP, s);
 CtlSetLabel (FrmGetObjectPtr (frmP, FrmGetObjectIndex (frmP,
CodeChooserCategoryPopTrigger)), sStr);

// ************* This next call identifies which row I will want to
highlight ********************
 searchForCode (frmP, tableP, lookupCode);

// ************* Load the data into the table...
 CodeChooserFormLoad (frmP);
}


------------------------------------------
This is the Load function which loads the data into the table

static void CodeChooserFormLoad (FormPtr frmP)
{
 TablePtr    tableP  = FrmGetObjectPtr (frmP, FrmGetObjectIndex (frmP,
CodeChooserCodeTable));
 Word     numRows  = TblGetNumberOfRows (tableP);
 Word     row;
 Word     recordNum = dmMaxRecordIndex;
 Word     lastRecordNum;
 VoidHand    recordH;

 // Try to show a full display of records.  Starting at the last
 // record and working backwards, find the record displayed at the
 // top of the table.  If the record is before the topVisibleItem
 // then topVisibleItem is set too far down the list of records.
 // Set topVisibleItem to the record one screen full from the end.
 DmSeekRecordInCategory (db, &recordNum, (numRows-1),
   dmSeekBackward, currentCategory);

 topVisibleItem = min (topVisibleItem, recordNum);
 recordNum = topVisibleItem;
 lastRecordNum = recordNum;

 for (row = 0; row < numRows; ++row, ++recordNum)
 {
  // Get the next record in the current category.
  recordH = DmQueryNextInCategory (db, &recordNum, currentCategory);
  // If the record was found, store the record number in the table item,
  // otherwise set the table row unusable.
  if (recordH)
  {
   TblSetItemInt (tableP, row, 0, recordNum);
   TblSetRowUsable (tableP, row, true);
   lastRecordNum = recordNum;
  }
  else
  {
   // Sometimes there are more table rows than records.
   // If this happens mark those unused table rows as
   // not usable.
   TblSetRowUsable (tableP, row, false);
  }

  // Mark the row invalid so that it will draw when we call the
  // draw routine.
  TblMarkRowInvalid (tableP, row);
 }

// ********* I call this function to unhighlight the previously selected
row, otherwise I get
// MULTIPLE ROWS SELECTED

 TblUnhighlightSelection (tableP);
 CodeChooserFormUpdateScrollers (frmP, lastRecordNum);

}


----------------------------
Here is the function that draws a row

static void CodeChooserDrawCodeRecord ( VoidPtr tableP, Word row, Word
column, RectanglePtr bounds)
{
 Handle    recHandle;
 Int     width;
 Boolean    fits;
 UInt    recordNum = 0;
 FontID     currFont;
 PackedLookupCode * packedLookupCode;
 LookupCode    lookupCode;
 Int     stringLength = 0;
 char *    text = 0;

 // Get the record number that corresponds to the table item to draw.
 // The record number is stored in the "intValue" field of the item.
 recordNum = TblGetItemInt (tableP, row, column);

 // Retrieve the record from the database and lock it down.
 recHandle = DmQueryRecord(db, recordNum);
 packedLookupCode = MemHandleLock (recHandle);

 // Unpack the patient so we can read the data in it...
 unpackLookupCode (packedLookupCode, &lookupCode);

 // Construct the string we will display from the name:
 stringLength = StrLen (lookupCode.description);
 // Set the standard font.  Save the current font.
 // It is a Pilot convention to not destroy the current font
 // but to save and restore it.
 currFont = FntSetFont (stdFont);

 // Determine the length of text that will fit within the bounds.
 width = bounds->extent.x - 2;
 FntCharsInWidth(lookupCode.description, &width, &stringLength, &fits);

 // Now draw the text from the record.
 WinDrawChars(lookupCode.description, stringLength, bounds->topLeft.x,
bounds->topLeft.y);

 // Restore the font.
 FntSetFont (currFont);

 // Unlock the handle to the record.
 MemHandleUnlock(recHandle);

 // ***********************************
 // HERE IS WHERE I TRY TO SELECT THE ROW!
 // ***********************************
 if (recordNum == selectedRecord)
 {
  TblSelectItem (tableP, row, column);
 }

}


-- 
For information on using the Palm Developer Forums, or to unsubscribe, please see 
http://www.palm.com/devzone/mailinglists.html

Reply via email to