> >I can move to
> >next and previous records OK but if I go the the last record and then
move
> >from there all manner of weirdness ensues.
>
> Without more specific details, I doubt anyone will be able to help you
much.
>
> Regards,
> Steve Mann
>
> --
I hope this is not too much specific information.
The CodeWarrior error message I am getting is "MemoryMgrNew.c Line 4177 Free
Handle".
This error occurs during record navigation and display. If I have only 2
records then I can move Next, then Prev but clicking Next again with
generate the error. If I have say 10 records I can move next through all 10
but upon going Prev the error is generated again.
Below is the 'boilerplateless' code used for generating and navigating
records.
I am using DmQueryRecord as this seemed to the be the only working way of
getting access to a record.
There are static declarations for
DmOpenRef gDB;
UInt gIndex = 0;
FormPtr frm;
FieldPtr fld;
Handle prevTxtHand;
UInt NoRecs;
(Some of these, esp. form and field ptrs, could be declared locally but when
debugging local variables seemed to produce wayward results when looking at
the top right of the debug IDE in CodeWarrior)
//FIRST THE CODE FOR EACH OF THE THREE BUTTONS ADD, NEXT AND PREV
case ctlSelectEvent:
{
switch (event->data.ctlEnter.controlID)
{
case Basic1802AddButton://GET ANY TEXT AND DISPLAY IN A MSGBOX
{
frm = FrmGetActiveForm();
fld = (FieldPtr) FrmGetObjectPtr(frm, FrmGetObjectIndex(frm,
Basic1802TxtField));
char *txt = FldGetTextPtr(fld);//FIRST GET A POINTER TO THE
TEXT THEY MAY HAVE WRITTEN
if (txt == NULL)
{
FrmCustomAlert(MsgBoxAlert, "No text entered", NULL, NULL);
}
else
{
if (AddRec(txt))
{
FrmCustomAlert(MsgBoxAlert, "Record Added", NULL,
NULL);//ALERT THAT RECORD SAVED
}
else
{
FrmCustomAlert(MsgBoxAlert, "Record failed to save",
NULL, NULL);
}
}
handled = true;
break;
} //END OF ADD BUTTON CASE
case Basic1802PrevButton:
{
if (gIndex > 0)
{
gIndex--;
DisplayRec();
}
else
{
FrmCustomAlert(MsgBoxAlert, "Min.Record", NULL, NULL);
}
break;
}
case Basic1802NextButton:
{
NoRecs = DmNumRecords(gDB);
gIndex++;
if (gIndex >= (NoRecs))
{
FrmCustomAlert(MsgBoxAlert, "Max.Record", NULL, NULL);
gIndex = NoRecs -1;
break;
}
DisplayRec();
break;
}
}
//CODE FOR ADDREC
static Boolean AddRec(char *txt)
{
VoidHand hRec;
Err err;
gIndex = 0;
NameRec Person;
StrCopy(Person.Name, txt);
hRec = DmNewRecord(gDB, &gIndex, sizeof(Person) + 1);
if (hRec)
{
Ptr p;
p = (Ptr)MemHandleLock(hRec);
err = DmWrite(p, 0, &Person, sizeof(Person) + 1);
MemPtrUnlock(p);
return true;
}
else
{
return false;
}
}
//IF NEXT OR PREV PRESSED AND THE GLOBAL gIndex IS VALID THEN DISPLAY REC IS
CALLED
static void DisplayRec()
{
VoidHand recH;
if (gDB)
{
NoRecs = DmNumRecords(gDB);
if (NoRecs != 0)
{
recH = DmQueryRecord(gDB, gIndex);
SetText((Handle) recH);
}
else
{
FrmCustomAlert(MsgBoxAlert, "There are no Records", NULL,
NULL);
}
}
else
{
FrmCustomAlert(MsgBoxAlert, "DmOpenRef no good", NULL, NULL);
}
}
//IF THERE IS A RECORD TO DISPLAY THEN SETTEXT IS CALLED
//I DECIDED TO MAKE THIS A SEPERATE FUNCTION GIVEN THE DIFFICULTIES
SURROUNDING FIELDS AND THE NEED TO RELEASE THE PREVIOUS HANDLE. I HAD
PLANNED TO EXTEND THIS FUNCTION SO YOU WOULD PASS WHICH FIELD AS WELL AS
WHAT TEXT
static void SetText(Handle hText)
{
frm = FrmGetActiveForm();//GET FORM PTR
fld = (FieldPtr) FrmGetObjectPtr(frm, FrmGetObjectIndex(frm,
Basic1802TxtField));//GET FIELD PTR
prevTxtHand = FldGetTextHandle(fld);//STORE A HANDLE TO THE PREV HANDLE
FOR USE LATER
FldSetTextHandle(fld, hText);
FldDrawField(fld);
if (prevTxtHand)
{
MemHandleFree(prevTxtHand);
}
}
//AND THAT'S IT!!
If it's easier I can attach the code rather than making great long messages.
Many thanks
Bearfoot
--
For information on using the Palm Developer Forums, or to unsubscribe, please see
http://www.palmos.com/dev/support/forums/