|
|
|
|
|
|
|
|
Playing the field (continued)
There is a field attribute that says "numeric only." When that attribute is set, the field's default handler prevents non-numeric characters from being entered. This is easier than using keyDownEvent processing, unless you want some additional characters to be allowed. It's also more reliable, since the keyboard respects this attribute and won't put non-numeric characters into the field. However, it only works on Palm OS 2 and 3 (PalmPilots and PalmIIIs) -- it doesn't work on Palm OS 1, so Pilot 1000s and 5000s will put non-numeric characters into the field.
Processing after the field changes
Infield displays a running count of the number of characters in the field's text buffer. We want to update this count after the field has changed. Unfortunately, we don't get an event to tell us that the field has changed. There is a fldChangedEvent, but that only happens when the field scrolls due to dragging and selecting text; we don't get that when entering or deleting characters.
When there are no other events in the event queue, we can ask EvtGetEvent (in our event loop) to give us a nilEvent. So Infield does its post-field-change processing when a nilEvent comes in. To trigger the nilEvents, the keyDownEvent processing sets a boolean flag, fUpdateScreen. When EventLoop calls EvtGetEvent, it uses fUpdateScreen to select how long to wait for an event -- either forever (if fUpdateScreen is not set) or 0 (zero) ticks (if fUpdateScreen is set). Once the event queue is empty, and after the timeout occurs (immediately in the case of 0), EvtGetEvent will return a nilEvent. So immediately after processing all the events to put a character into the field, EvtGetEvent will give us the nilEvent, so we update the character count.
In actuality, there's a side-effect of being in a field -- your application gets constant nilEvents. So I could've skipped all the handling with fUpdateScreen and setting the EvtGetEvent timeout. However, there's a delay before that nilEvent comes in; the character-count doesn't update immediately, so I kept the fUpdateScreen flag to trigger a 0-length timeout in EvtGetEvent. I prefer things happening because I said to do them and not counting on undocumented features like the nilEvents in fields. It also shows how to do something like this, just in case you have a similar need in some other application.
Originally, I used the fUpdateScreen flag in a conditional block so we wouldn't keep updating the screen with the same character count. However, if you enter characters using the on-screen keyboard, fUpdateScreen never got set, so the count wasn't updated after using the keyboard. So I left it doing the character count calculation with each nilEvent, but I only update the screen when the count changes.
This routine also demonstrates getting text from the field. In this case, we get a pointer to the text and just get the text's length. However, we could just as easily copy that text into a data record, or do other processing with it.
|
|
|
|
|
|
|
|
|
|
|