http://www.developer.com/ws/palm/article.php/3460011/Working-with-Resources-in-Palm-OS-Applications.htm
Before diving into the Palm OS resource managemnent stuff, take a look at what you are going to manage. The following table describes the main resource types available in Palm OS: After such a smart start, you can see how rich this game is. It's odd to say that, by using resources, you make all localization issues much easier. For custom launch codes, when you can't have global variables, a resource may be an ideal solution to work around it, and so forth. If you're already convinced, the next sections will guide you through the supporting API calls. First of all, consider how to conduct a resources search. DataMgr.h defines the following functions for this purpose: These functions expose various ways to get the desired results. Usually, resources are stored in PDB on a Palm device. When you request a specific resource, the Palm OS will start from recently opened databases. The DmNextOpenResDatabase function controls which database will be searched for. The first one in the search chain will be returned, passing NULL as a parameter. Actually, it is the last loaded resource database; for example, your application. Note, that in case of using overlays, the returned pointer will reference the overlay, not the base resource. DmFindResource and DmFindResourceType run over a given database for specified resource parameters such as type, index, ID, or memory handle. In turn, DmSearchResource does its job over all open resource databases and returns a reference to the appropriate database. Although Palm OS 6 still supports a "search chain" notion for backward compatibility, new applications should not rely on this. To illustrate what was said above, take a look at the following code sample: This code snippet obtains a reference of the recent resource database (application itself in this case), searches for the string of index 1, and finally loads it by using a DmGetResourceIndex call. Here's a standard trick: First, obtain a resource index inside a database and then get it itself. Such a technique is useful when you need to enumerate some kind of resources and display them; for example, in some list. The Data Manager exposes several functions to access resources stored in database: An application gets the resources by calling either DmGetResource, DmGet1Resource, or DmGetResourceIndex. The difference between the first two APIs is that DmGetResource searches all opened databases, whereas DmGet1Resource uses the most recently opened one. As an example, the following code loads a string list from the resource and fills in some other list: This sample also gives you the internal structure of the 'tSTL' resource: So, by enumerating strings one by one, you can get them all. If you need to extract a specific string by a known index, you have another function to be called: The returned string is concatenated from the prefix and string at the given index. The next snippet gives you one more simple example of how to retrieve raw data from a resource via a DmGetResource call: DmGetResource returns the resource located in the overlay if any open overlay has a resource matching that type and ID. Otherwise, this function continues to search the resource in the base database. Finally, when the resource is no longer needed, you should call DmReleaseResource to release it. Obviously enough, the application must do it as soon as it does not need this resource any more to ease the OS's life. In this final section, you will explore a few more API calls. This kind of function handles resource creation and deletion, together with updating existing data. These functions are: As you can see, they are divided into three groups. The first group is informational and simple. The other two groups allow you to manage resources. DmAttachResource converts given memory chunk into a specified resource, so that's the way to create new resources on-the-fly. DmDetachResource removes a resource from the database and reassigns it to a memory chunk. All the rest is self-explained. I will not touch them here in details, leaving it for your own fun. That's it; you're ready to explore new resource islands. Alex Gusev started to play with mainframes at the end of the 1980s, using Pascal and REXX, but soon switched to C/C++ and Java on different platforms. When mobile PDAs seriously rose their heads in the IT market, Alex did it too. Now, he works at an international retail software company as a team leader of the Mobile R department, making programmers' lives in the mobile jungles a little bit simpler.
Working with Resources in Palm OS Applications
January 17, 2005
Resource Types
Constant
Value
Description strRsc
'tSTR'
String resource ainRsc
'tAIN'
Application Icon Name resource iconType
'tAIB'
Icon resource bitmapRsc
'Tbmp'
Bitmap resource bsBitmapRsc
'Tbsb'
Boot screen bitmap. This resource is system reserved alertRscType
'Talt'
Alert resource kbdRscType
'tkbd'
Keyboard resource. This resource is system reserved MenuRscType
'MBAR'
Menu Bar resource fontRscType
'NFNT'
Single density Font resource fontExtRscType
'nfnt'
High density Font resource verRsc
'tver'
Version resource appInfoStringsRsc
'tAIS'
Application Categories are store here. This resource can be passed to the CategoryInitialize() API fontIndexType
'fnti'
Represents the font index. This resource is system reserved midiRsc
'MIDI'
Palm MIDI compliant resource colorTableRsc
'tclt'
UI Color Table resource constantRscType
'tint'
Integer constant resource. ResLoadConstant() API can be called to load the this type of resource formRscType
'tFRM'
UI Form resource strListRscType
'tSTL'
This is a string list resource wrdListRscType
'wrdl'
List of WORD (2 bytes) values defaultCategoryRscType
'taic'
Launcher Category ID. Your application will be placed under the appropriate category on the Palm device binaryGeneralRscType
'tbin'
General binary resource. You may store any raw data here Searching Resource Databases
DmOpenRef DmNextOpenResDatabase(DmOpenRef dbP);
UInt16 DmFindResourceType(DmOpenRef dbP, DmResType resType,
UInt16 typeIndex);
UInt16 DmFindResource(DmOpenRef dbP, DmResType resType,
DmResID resID, MemHandle resH);
UInt16 DmSearchResource(DmResType resType, DmResID resID,
MemHandle resH, DmOpenRef *dbPP);
...
DmOpenRef dbP = DmNextOpenResDatabase(NULL);
UInt16 nIdx = DmFindResourceType(dbP,'tSTR',1);
MemHandle hMem = DmGetResourceIndex(dbP,nIdx);
Char *pData = (Char*)MemHandleLock(hMem);
...
MemHandleUnlock(hMem);
Getting Access to Resources
MemHandle DmGetResource(DmResType type, DmResID resID);
MemHandle DmGet1Resource(DmResType type, DmResID resID);
Err DmReleaseResource(MemHandle resourceH);
MemHandle DmResizeResource(MemHandle resourceH, UInt32 newSize);
MemHandle DmGetResourceIndex(DmOpenRef dbP, UInt16 index);
// define global containers somewhere
char **pszTestList = NULL;
UInt16 g_nNumItems = 0;
...
DmOpenRef dbP = DmNextOpenResDatabase(NULL);
MemHandle hSTL = DmGet1Resource('tSTL',StrList);
if ( hSTL )
{
Char *pSTL = (Char*)MemHandleLock(hSTL);
pSTL += StrLen(pSTL)+1;
MemMove(&g_nNumItems,pSTL,2);
pSTL += 2;
pszTestList = new Char*[g_nNumItems];
for (UInt16 wIdx = 0; wIdx < g_nNumItems; wIdx++)
{
pszTestList[wIdx] = new Char[StrLen(pSTL) + 1];
StrCopy(pszTestList[wIdx],pSTL);
pSTL += StrLen(pSTL) + 1;
}
UInt16 lstIndex = FrmGetObjectIndex(frmP, ResViewTestList);
ListType *listP = (ListType *)FrmGetObjectPtr(frmP, lstIndex);
LstSetListChoices (listP,pszTestList,g_nNumItems);
LstDrawList(listP);
MemHandleUnlock(hSTL);
DmReleaseResource(hSTL);
}
...
// and then release all allocated data at exit
static void AppStop(void)
{
/* Close all the open forms. */
FrmCloseAllForms();
for (UInt16 wIdx = 0; wIdx < g_nNumItems; wIdx++)
{
delete [] pszTestList[wIdx];
}
delete [] pszTestList;
}
Char *SysStringByIndex (UInt16 resID, UInt16 index, Char *strP,
UInt16 maxLen);
// So it is...
// the very first string is taken
Char Str[255];
if ( SysStringByIndex(StrList, 0, Str, sizeof(Str)) )
{
...
}
DmOpenRef dbP = DmNextOpenResDatabase(NULL);
MemHandle hData = DmGetResource('tbin',HexSampleRes);
Char *pHexData = (Char*)MemHandleLock(hData);
Int32 dwData;
MemMove(&dwData,pHexData,4);
MemHandleUnlock(hData);
DmReleaseResource(hData);
The Last Piece
// Resource Info
UInt16 DmNumResources(DmOpenRef dbP);
Err DmResourceInfo(DmOpenRef dbP, UInt16 index,
DmResType *resTypeP, DmResID *resIDP,
LocalID *chunkLocalIDP);
Err DmSetResourceInfo(DmOpenRef dbP, UInt16 index,
DmResType *resTypeP, DmResID *resIDP);
// Resource attaching and detaching
Err DmAttachResource(DmOpenRef dbP, MemHandle newH,
DmResType resType, DmResID resID);
Err DmDetachResource(DmOpenRef dbP, UInt16 index, MemHandle *oldHP);
// Resource creation and deletion
MemHandle DmNewResource(DmOpenRef dbP, DmResType resType,
DmResID resID, UInt32 size);
Err DmRemoveResource(DmOpenRef dbP, UInt16 index);
About the Author