Alan Kennington wrote:
> FldNewField
> returns a pointer to Field, which, if used straight away,
> gives no problems, e.g. in FldSetTextPtr(...).
>
> But if I save the field-pointer and try to use it later,
> very nasty things happen. Obviously it has been moved
> around in memory, I suppose. The FrmGetObjectPtr(...)
> function returns a different pointer at a later time.
You are calling FldNewField (or other "Dynamic UI" function) in the
meantime, right? Those functions do (generally) cause the form object
to relocate because it is being expanded. The form's objects are
embedded inside the form chunk so they move along with it.
(This is mentioned on p.176 of Part I of the 3.0 SDK book.)
> But I wonder if the return pointer from the FldNewField(...)
> function was really supposed to return the address of _locked_
> memory.
It does, but any subsequent call to FldNewField (et al) can unlock,
move, and relock the form chunk. Note that the FormPtr is passed as an
in/out parameter so your code will receive the new pointer after the
form has been relocated.
(Keep in mind that this Dynamic UI stuff is a rather obscure area of
Palm programming that most people never use, so the docs probably don't
cover every "gotcha" like this everywhere they could.)
> The fact that fields in a form do not seem to be lockable
> seems to imply that I can't just save an array of pointers
> to my 66 fields which I create dynamically.
If you are creating all 66 at the same time before using any of them,
just loop to fetch all 66 at the end of the creation process. But if
you are creating them at various times during the life of the form, then
you do need to re-fetch them.
> Can anyone confirm that programmers really are expected to
> call FrmGetObjectIndex(...) and FrmGetObjectPtr(...)
> every time they want to read/write them?
No, it's common (for non-dynamic Constructor or PilRC forms) to fetch
all needed object pointers into global variables during the frmOpen
event handler, and then just use them directly later.
> It seems like any create/delete/resize action on the fields of
> a form could result in the fields moving around.
> So if I fetch a field-pointer, and then do something
> else with the form, then an access to the field-pointer could
> be invalid.
Not "anything else". This relocation happens _only_ when you use the
API's to dynamically add and remove whole objects in the form. All the
other API's for working with field contents, handling lists, setting
attributes, hiding, drawing, enabling, etc., don't cause the form or its
objects to move.
But note that while a field _object_ stays fixed, its _text_ is stored
in a separately allocated heap chunk that does grow and shrink and move
around as the user edits text, but that's a different issue.
> Under what circumstances can I assume that a field-pointer
> will _not_ change, and therefore is safe to use?
When the form is finished being constructed. For non-dynamic UI, the
form is fully constructed by the FrmInitForm API which returns a locked
FormPtr you can safely use. But as soon as you call a dynamic UI
function on a FormPtr to construct more objects, it invalidates any
pointers that previously referred to any of its objects.
(You put 66 fields on one form? Sounds like a 6x11 table. Did a
regular table object not work in this case?)
-slj-