'xprf'=0
resource (symbolically named sysResTExtPrefs
) in the database and set its disableOverlays
flag. This resource is defined in UIResources.r
.
'ovly'
, and a suffix identifying the target locale is appended to its name. For example, Datebook.prc
might be overlaid with a database named Datebook_jpJP
, which indicates that this overlay is for Japan. Each overlay database has an 'ovly'
=1000 resource specifying the base database's type, the target locale, and information necessary to identify the correct version of the base database for which it was designed.
'ovly'
=1000 resource that matches the base database. If the name, suffix, and overlay resource are all correct, the overlay is opened in addition to the PRC file. When the PRC file is closed, its overlay is closed as well.
// WRONG! searches only one database.
DmOpenRef dbP = DmNextOpenResDatabase(NULL);
UInt16 resIndex = DmFindResource(dpP, strRsc,
    strRscID);
MemHandle resH = DmGetResourceIndex(dbP,
    resIndex);
dbP
is a pointer to the most recently opened database, which is typically the overlay version of the database. Passing this pointer to DmFindDatabase
means that you are searching only the overlay database for the resource. If you're searching for a non-localized resource, DmFindResource
won't be able to locate it. Instead, you should use DmGet1Resource
, which searches the most recently opened database and its overlay for a resource, or DmGetResource
, which searches all open databases and their overlays.
// Right. DmGet1Resource searches both
// databases.
MemHandle resH = DmGet1Resource(strRsc,
    strRscID);
// Or use DmGetResource to search all open
// databases.
MemHandle resH = DmGetResource(strRsc,
    strRscID);
'ovly'
resource becomes invalid, which prevents the overlay from being used at all. Thus if you change the resource database, you must also change the overlay database.
OmGetCurrentLocale
, which returns a structure identifying the locale on this device.
UInt32 intlMgrAttr;
if (FtrGet(sysFtrCreator, sysFtrNumIntlMgr,
    &intlMgrAttr) != 0)
intlMgrAttr = 0;
if (intlMgrAttr & intlMgrExists) {
    // If international manager exists, so does the
    // text manager.
// Use text manager calls.
}
NOTE:  You can still use the text manager and be compatible with earlier releases if you link your application with the PalmOSGlue library. See the section "Compatibility Information" for more information.
WChar
. WChar
is a 16-bit unsigned type that can accommodate characters of any encoding. Don't use Char
. Char
is an 8-bit variable that cannot accommodate larger character encodings. The only time you should ever use Char
is to pass a parameter to an older Palm OS function.
WChar ch; // Right. 16-bit character.
Char ch; // Wrong. 8-bit character.
keyDownEvent
, you'll receive a WChar
value. (That is, the data.keyDown.chr
field is a WChar
.)
WChar
, string variables are still declared as Char *
, even though they may contain multi-byte characters. See the section "Strings" for more information on strings.
Chars.h
contains characters that are guaranteed to be supported on all systems regardless of the encoding. Other header files exist for each supported character encoding and contain characters specific to that encoding. The character encoding-specific header files are not included in the PalmOS.h
header by default because they define characters that are not available on every system.
WChar ch = 'å'; // WRONG! Don't use.
WChar ch = chrSmall_A_RingAbove;
chrSmall_A_RingAbove
constant is defined in CharLatin.h
, which is not included by default.
TxtCharIsValid
to determine whether a character is valid or not.
WARNING!In previous versions of the Palm OS, the header fileCharAttr.h
defined character attribute macros such asIsAscii
. Using these macros on double-byte characters produces incorrect results. Use the text manager macros instead of theCharAttr.h
macros.
keyDownEvent
distinguishes a virtual character from a displayable character by setting the command bit in the event record.
TxtGlueCharIsVirtual
function defined in the PalmOSGlue library. (See "Compatibility Information" for more information on the PalmOSGlue library.)
if (TxtGlueCharIsVirtual
    (eventP->data.keyDown.modifiers,
    eventP->data.keyDown.chr)) {
    if (TxtCharIsHardKey
    (event->data.keyDown.modifiers,
    event->data.keyDown.chr)) {
    // Handle hard key virtual character.
    } else {
    // Handle standard virtual character.
    }
} else {
    // Handle regular character.
}
FtrGet
function as shown in Listing 13.3.
UInt32 encoding;
Char* encodingName;
if (FtrGet(sysFtrCreator, sysFtrNumEncoding,
    &encoding) != 0)
encoding = charEncodingPalmLatin;
    //default encoding
if (encoding == charEncodingPalmSJIS) {
    // encoding for Palm Shift-JIS
} else if (encoding == charEncodingPalmLatin) {
    // extension of ISO Latin 1
}
// The following text manager function returns the
// official name of the encoding as required by
// Internet applications.
encodingName = TxtEncodingName(encoding);
TIP: Many of the existing Palm OS functions have been modified to work with strings containing multi-byte characters. All Palm OS functions that return the length of a string, such asFldGetTextLength
andStrLen
, always return the size of the string in bytes, not the number of characters in the string.
TxtGetNextChar
retrieves the next character in a string.
TxtGetPreviousChar
retrieves the previous character in a string.
TxtSetNextChar
changes the next character in a string and can be used to fill a string buffer. Char* buffer; // assume this exists
Int16 bufLen = StrLen(buffer);
// Length of the input text.
WChar ch = 0;
UInt16 i = 0;
while ((i < bufLen) && (ch != chrAsterisk))
    i+= TxtGetNextChar(buffer, i, &ch));
UInt32* charStart, charEnd;
Char* fldTextP = FldGetTextPtr(fld);
TxtCharBounds(fldTextP, min(kMaxBytesToProcess,
    FldGetTextLength(fld)), &charStart, &charEnd);
// process only the first charStart bytes of text.
// WRONG! buffer + kMaxStrLength is not
// guaranteed to point to start of character.
buffer[kMaxStrLength] = '\0';
// Right. Truncate at a character boundary.
UInt32 charStart, charEnd;
TxtCharBounds(buffer, kMaxStrLength,
    &charStart, &charEnd);
TxtSetNextChar(buffer, charStart, chrNull);
WinDrawTruncChars
- This function draws a string within a specified width, determining automatically where to truncate the string. If it can, it draws the entire string. If the string doesn't fit in the space, it draws one less than the number of characters that fit and then ends the string with an ellipsis (...).
FntWidthToOffset
- This function returns the byte offset of the character displayed at a given pixel position. It can also return the width of the text up to that offset.
TxtCompare
and
TxtCaselessCompare
to perform comparisons of strings.
TxtCompare
and TxtCaselessCompare
can accurately match single-byte characters with their multi-byte equivalents.
TxtCompare
and TxtCaselessCompare
take two parameters in which they pass back the length of matching text in each of the two strings. See the function descriptions in the Palm OS SDK Reference for more information.
StrCompare
and StrCaselessCompare
are equivalent, but they do not pass back the length of the matching text.
TxtFindString
. As with TxtCompare
and TxtCaselessCompare
, TxtFindString
accurately matches single-byte characters with their corresponding multi-byte characters. Plus, it passes back the length of the matched text. You'll need this value to highlight the matching text when the system requests that you display the matching record.
FindStrInStr
. FindStrInStr
is not able to return the length of the matching text. Instead, it assumes that characters within the string are always one byte long.
sysAppLaunchCmdGoto
, which is the system's request that the matching record be displayed. These two listings are only code excerpts. For the complete implementation of these two functions, see the example code in your development environment.
static void Search (FindParamsPtr findParams)
{
    UInt16 recordIndex = 0;
    DmOpenRef dbP;
    UInt16 cardNo = 0;
    LocalID dbID;
    MemoDBRecordPtr memoPadRecP;
    // Open the database to be searched.
    dbP = DmOpenDatabaseByTypeCreator(memoDBType,
    sysFileCMemo, findParams->dbAccesMode);
    DmOpenDatabaseInfo(dbP, &dbID, 0, 0, &cardNo,
    0);
    // Get first record to search.
    memoRecP = GetRecordPtr(dbP, recordIndex);
    while (memoRecP != NULL) {
    Boolean done;
    Boolean match;
    UInt32 matchPos, matchLength;
    // TxtGlueFindString calls TxtFindString if it
    // exists, or else it implements the Latin
    // equivalent of it.
    match = TxtGlueFindString (&(memoRecP->note),
    findParams->strToFind, &matchPos,
    &matchLength);
   
    if (match) {
    done = FindSaveMatch (findParams,
    recordIndex, matchPos, 0, matchLength,
    cardNo, dbIDP);
    }
    MemPtrUnlock (memoRecP);
    if (done) break;
    recordIndex += 1;
    }
    DmCloseDatabase (dbP);
}
static void GoToRecord (GoToParamsPtr goToParams, Boolean launchingApp)
{
    UInt16 recordNum;
    EventType event;
    recordNum = goToParams->recordNum;
    ...
    // Send an event to goto a form and select the
    // matching text.
    MemSet (&event, sizeof(EventType), 0);
    event.eType = frmLoadEvent;
    event.data.frmLoad.formID = EditView;
    EvtAddEventToQueue (&event);
    MemSet (&event, sizeof(EventType), 0);
    event.eType = frmGotoEvent;
    event.data.frmGoto.recordNum = recordNum;
    event.data.frmGoto.matchPos =
    goToParams->matchPos;
    event.data.formGoto.matchLen =
    goToParams->matchCustom;
    event.data.frmGoto.matchFieldNum =
    goToParams->matchFieldNum;
    event.data.frmGoto.formID = EditView;
    EvtAddEventToQueue (&event);
    ...
}
TxtParamString
. TxtParamString
allows you to search for the sequence ^0, ^1, up to ^3 and replace each of these with a different string. (If you need more parameters, you can use
TxtReplaceStr
, which allows you to replace up to ^9; however, TxtReplaceStr
only allows you to replace one of these sequences at a time.) The PalmOSGlue library defines a function TxtGlueParamString
, which calls TxtParamString
if it exists or else implements the Latin equivalent of it.
Memo ^0 of ^1
static void EditViewSetTitle (void)
{
    Char* titleTemplateP;
    FormPtr frm;
    Char posStr [maxStrIToALen];
    Char totalStr [maxStrIToALen];
    UInt16 pos;
    UInt16 length;
    // Format as strings, the memo's postion within
    // its category, and the total number of memos
    // in the category.
    pos = DmPositionInCategory (MemoPadDB,
    CurrentRecord, RecordCategory);
    StrIToA (posStr, pos+1);
    if (MemosInCategory == memosInCategoryUnknown)
    MemosInCategory = DmNumRecordsInCategory
    (MemoPadDB, RecordCategory);
    StrIToA (totalStr, MemosInCategory);
    // Get the title template string. It contains
    // '^0' and '^1' chars which we replace with the
    // position of CurrentRecord within
    // CurrentCategory and with the total count of
    // records in CurrentCategory ().
    titleTemplateP = MemHandleLock (DmGetResource
    (strRsc, EditViewTitleTemplateStringString));
    EditViewTitlePtr =
    TxtGlueParamString(titleTemplateP, posStr,
    totalStr, NULL, NULL);
    // Now set the title to use the new title
    // string.
    frm = FrmGetFormPtr (MemoPadEditForm);
    FrmSetTitle (frm, EditViewTitlePtr);
    MemPtrUnlock(titleTemplateP);
}
PrefGetPreference
with one of the values listed in the second column of Table 13.1. The third column lists an enumerated type that helps you interpret the value.
DateToAscii
,
DayOfMonth
,
DayOfWeek
, and
DaysInMonth
, which allow you to work with dates independent of the user's preference settings.
PrefGetPreference
and
LocGetNumberSeparators
to retrieve information about how the number should be displayed.
Use
StrLocalizeNumber
to perform the localization.
If a user enters a number that you need to manipulate in some way, convert it to the US conventions using
StrDelocalizeNumber
.
// store numbers using US conventions.
Char *jackpot = "20,000,000.00";
Char thou; // thousand separator
Char dp; // decimal separator
// Retrieve current country's preferences.
LocGetNumberSeparators((NumberFormatType)
    PrefGetPreference(prefNumberFormat), &thou,
    &dp);
// Localize jackpot number. Converts "," to thou
// and "." to dp.
StrLocalizeNumber(jackpot, thou, dp);
// Display string.
// Assume inputString is a number user entered,
// convert it to US conventions this way. Converts
// thou to "," and dp to "."
StrDelocalizeNumber(inputNumber, thou, dp);
PalmOSGlue.lib
or libPalmOSGlue.a
). This library provides these features for versions 2.0 and 3.0.
TxtFindString
is named TxtGlueFindString
in the PalmOSGlue. (See the chapter "PalmOSGlue Library" of the Palm OS SDK Reference for a complete mapping table.) When you make a call to a glue function (TxtGlue
Func, FntGlue
Func, or WinGlue
Func), the code in PalmOSGlue either uses the text manager or international manager on the ROM or, if the managers don't exist, executes a simple Latin equivalent of the function.
keyDownEvent
structure's chr
field (which contains the input character) has been changed from a Word
to a WChar
. The chr
field may contain a multi-byte character, so you should never copy the chr
field into a Char
variable or pass it to a function using a Char
parameter. Always use WChar
.
ChrNumericSpace
and
ChrHorizEllipsis
to return the appropriate character regardless of the character map. In PalmOSGlue, these two macros are named TxtGlueGetNumericSpaceChar
and TxtGlueGetHorizEllipsisChar
, respectively.
StrChr
and
StrStr
now treat buffers as characters, not arbitrary byte arrays. If you previously used these functions to search data buffers, your code may no longer work.
ErrFatalDisplayIf
and
ErrNonFatalDisplayIf
to determine error conditions. If the error condition occurs, the system displays the file name and line number at which the error occurred along with the message that you passed to the macro. Often these messages are hard-coded strings. On Japanese systems, the Palm OS traps the messages passed to these two macros and displays a generic message explaining that an error has occurred.
ErrFatalDisplayIf
and ErrNonFatalDisplayIf
for totally unexpected errors. Do not use them for errors that you believe your end users will see. If you wish to inform your users of an error, use a localizable resource to display the error message instead of ErrFatalDisplayIf
or ErrNonFatalDisplayIf
.
Text Manager | |
---|---|
Working With Multi-Byte Characters | |
TxtCharBounds TxtPreviousCharSize TxtByteAttr |
TxtCharSize TxtNextCharSize |
Changing Text | |
TxtReplaceStr TxtGetTruncationOffset |
TxtSetNextChar TxtTransliterate |
Accessing Text | |
TxtGetNextChar TxtGetChar |
TxtGetPreviousChar TxtWordBounds |
Searching/Comparing Text | |
TxtCaselessCompare TxtFindString | TxtCompare |
Obtaining a Character's Attributes | |
TxtCharIsAlNum TxtCharIsDigit TxtCharIsLower TxtCharIsSpace TxtCharIsValid TxtCharIsCntrl TxtCharIsPunct TxtCharWidth |
TxtCharIsAlpha TxtCharIsGraph TxtCharIsPrint TxtCharIsUpper TxtCharXAttr TxtCharIsHex TxtCharAttr |
Obtaining Character Encoding information | |
TxtStrEncoding TxtMaxEncoding |
TxtEncodingName TxtCharEncoding |
Localizing Numbers | |
---|---|
StrLocalizeNumber LocGetNumberSeparators | StrDelocalizeNumber |
International Manager | |
---|---|
IntlGetRoutineAddress |
Overlay Manager | |
---|---|
OmGetCurrentLocale OmGetIndexedLocale OmGetRoutineAddress OmSetSystemLocale |
OmGetSystemLocale OmLocaleToOverlayDBName OmOverlayDBNameToLocale |
  |   |