How to exit from the application:
Palm suggests do not exit from applications, but if you wish to do it
...
/************************************/
/* Returns to
launcher
*/
static void
Uti_Exit(void)
{
EventType event;
MemSet(&event,sizeof(event),0);
event.eType = keyDownEvent;
event.data.keyDown.chr = vchrLaunch;
event.data.keyDown.modifiers = commandKeyMask;
EvtAddEventToQueue(&event);
}
/************************************/
/* Returns to the previous
application
*/
static void
Uti_Exit(void)
{
EventType event;
MemSet(&event,sizeof(event),0);
event.eType = appStopEvent;
EvtAddEventToQueue(&event);
}
|
How to power off:
Add the
vchrPowerOff
keyDownEvent to the queue, see Uti_PowerOff();
Add the appStopEvent
event
if you want to exit from the application too, see Uti_Exit();
/************************************/
static void
Uti_PowerOff(void)
{
EventType event;
MemSet(&event,sizeof(event),0);
event.eType = keyDownEvent;
event.data.keyDown.chr = vchrPowerOff;
event.data.keyDown.keyCode = 0;
event.data.keyDown.modifiers = commandKeyMask;
EvtAddEventToQueue(&event);
}
|
How to store a
permanent value and have it back to the next run or pass it to another
application:
Use the Features to
store a UInt32 value
Store with
FtrSet(AppCreator, Feature_number, Feature_Value);
Retrive with
FtrGet(AppCreator, Feature_number, &Feature_Value);
|
How to know if the palm is powering on or is going to
sleep:
Register for some
notification and handle them as follows
Unregister with SysNotifyUnregister()
when no more needed
You can use a Feature (see How to store a
permanent value... ) to
store the program start time
/************************************/
static void RegisterForNotifications()
{
UInt16 cardNo=0;
UInt32 romVersion=0;
LocalID dbID=0;
FtrGet(sysFtrCreator,
sysFtrNumROMVersion, &romVersion);
if(romVersion < MinVersion)
return;
if(SysCurAppDatabase(&cardNo,
&dbID)!=0)
return;
// Register the
Notification you need
SysNotifyRegister(cardNo,
dbID, sysNotifyEarlyWakeupEvent, NULL, sysNotifyNormalPriority, 0);
SysNotifyRegister(cardNo,
dbID, sysNotifyLateWakeupEvent, NULL, sysNotifyNormalPriority, 0);
SysNotifyRegister(cardNo,
dbID, sysNotifySleepRequestEvent, NULL, sysNotifyNormalPriority, 0);
}
/************************************/
static void HandleNotifications(SysNotifyParamType
*np)
{
if(np->notifyType==sysNotifyEarlyWakeupEvent)
{
// Do something
}
else if(np->notifyType==sysNotifyLateWakeupEvent)
{
// Do something
}
else if(np->notifyType==sysNotifySleepRequestEvent)
{
// Do something
}
}
/************************************/
UInt32 PilotMain(UInt16 cmd,void *cmdPBP,UInt16 launchFlags)
{
switch(cmd)
{
case sysAppLaunchCmdSystemReset:
case sysAppLaunchCmdSyncNotify:
RegisterForNotifications();
break;
case sysAppLaunchCmdNotify:
case sysNotifySleepRequestEvent:
HandleNotifications((SysNotifyParamType *)cmdPBP);
break;
case sysAppLaunchCmdNormalLaunch:
... Normal code ...
|
How to create a progress bar:
/************************************/
// Clear a progress bar
/************************************/
static void ProgressBarClear(UInt16 unTop,UInt16 unLeft,UInt16 unWidth)
{
Rect.topLeft.x=unLeft;
Rect.topLeft.y=unTop;
Rect.extent.x=unWidth;
Rect.extent.y=12;
WinEraseRectangle(&Rect,0);
}
/************************************/
// Draw a progress bar
/************************************/
static void ProgressBarInit(UInt16 unTop,UInt16 unLeft,UInt16 unWidth)
{
ProgressBarClear(unTop,unLeft,unWidth);
Rect.topLeft.x=unLeft+1;
Rect.topLeft.y=unTop+1;
Rect.extent.x=unWidth-2;
Rect.extent.y=10;
newRgb.r=0x00;
newRgb.g=0x00;
newRgb.b=0x00;
WinSetForeColorRGB(&newRgb,&prevRgb);
WinDrawRectangleFrame(rectangleFrame,&Rect);
}
/*******************************************************/
// ProgressBar
// Use example:
// Init
with:
ProgressBarInit(17,2,123);
// Call several time:
ProgressBar(17,2,123,unIx,200);
// Clear
with:
ProgressBarClear(17,2,123);
/*******************************************************/
static void ProgressBar(UInt16 unTop,UInt16 unLeft,UInt16 unWidth,UInt32 unValue,UInt32 unMaxValue)
{
UInt32 ulTemp=0;
if(unMaxValue)
ulTemp=(unWidth-2)*unValue/unMaxValue;
if(ulTemp>(unWidth-2))
ulTemp=(unWidth-2);
Rect.topLeft.x=unLeft+1;
Rect.topLeft.y=unTop+1;
Rect.extent.x=ulTemp;
Rect.extent.y=10;
newRgb.r=0x00;
newRgb.g=0x00;
newRgb.b=0xFF;
WinSetForeColorRGB(&newRgb,&prevRgb);
WinDrawRectangle(&Rect,0);
}
|
How to turn IrDA On/Off:
Boolean bIrDAEnabled;
Boolean bIrDAisPresent;
UInt16 irLibRefNum;
UInt16 unLen;
Err
err;
...
// Checks if Irda is present
at program start and gets irLibRefNum
err = SysLibFind("IrDA Library", &irLibRefNum);
if(err == 0)
bIrDAisPresent=true;
else
bIrDAisPresent=false;
...
// Set the state of
bIrDAEnabled boolean
unLen=sizeof(bIrDAEnabled);
if(bIrDAisPresent)
ExgLibControl(irLibRefNum, irSetScanningMode, &bIrDAEnabled,
&unLen);
|
How to associate a file extension to a card
directory:
When you try to sync a file
to the expansion card, often, you got an error saing that there is not
a program associated to that file type
// For example to unregister
the .txt extension write this
VFSUnregisterDefaultDirectory(".txt",
expMediaType_Any);
// To associate the .txt
extension to the /PALM/Laungher directory use this
VFSRegisterDefaultDirectory(".txt",
expMediaType_Any, "/PALM/Launcher");
|
How to avoid menu overwrite:
You can avoid menu
overwrite by, for example, a WinDrawChars() managing the messages
winExitEvent and winEnterEvent to set a boolean bCanDraw that determine
if you can do the write/draw or not.
/************************************/
static Boolean
PreprocessEvent(EventPtr eventP)
{
... Your code here ....
switch(eventP->eType)
{
case winExitEvent:
if(eventP->data.winExit.exitWindow==(WinHandle)FrmGetFormPtr(MainForm))
bCanDraw=false;
if(eventP->data.winExit.exitWindow==(WinHandle)FrmGetFormPtr(AnotherForm))
bCanDraw=false;
break;
case winEnterEvent:
if(eventP->data.winEnter.enterWindow==(WinHandle)FrmGetFirstForm())
{
if(eventP->data.winEnter.enterWindow==(WinHandle)FrmGetFormPtr(MainForm))
bCanDraw=true;
if(eventP->data.winEnter.enterWindow==(WinHandle)FrmGetFormPtr(AnotherForm))
bCanDraw=true;
}
break;
... Your code continue here ....
|
How to connect the palm to your phone, PC
or other serial device through Bluetooth:
Here is a simple way to
communicate with your bluetooth serial device, this example code
is as simple as possible you have to implement the errors management.
You have to:
1) Load the Library
2) Find a device if not already known
3) Open the connection
4) Use it (Receive, Send, Flush, etc.)
5) Close the connection
/**************/
/* BT Globals
*/
/**************/
static UInt16
unPortId;
static UInt16
btLibRefNum;
static UInt8
cAddress[6];
static Err err;
static
SrmOpenConfigType config;
static
BtVdOpenParams btParams;
static
BtLibSdpUuidType sppUuid;
/************************************/
/* Pause n
milliseconds
*/
/************************************/
static void
Uti_WaitMilliSec(UInt32 ulMilliSec)
{
UInt16 unTickPerSec;
unTickPerSec=SysTicksPerSecond();
if(unTickPerSec)
SysTaskDelay(ulMilliSec*unTickPerSec/1000);
else
SysTaskDelay(ulMilliSec/10);
}
/**************************************/
/* Close a Bluetooth serial
connetion
*/
/**************************************/
static void
BT_Close()
{
if(unPortId)
{
SrmClose(unPortId);
unPortId=0;
Uti_WaitMilliSec(500);
SrmClose(unPortId); //
Retry, on some system it's hard to die
}
}
/*************************************/
/* Open a Bluetooth serial
connetion
*/
/*************************************/
static void
BT_Open()
{
BT_Close();
MemSet(&sppUuid, sizeof(sppUuid),
0);
sppUuid.size = btLibUuidSize16;
sppUuid.UUID[0] =
0x11;
sppUuid.UUID[1] =
0x01;
MemSet(&btParams, sizeof(btParams),
0);
btParams.u.client.remoteDevAddr.address[0]=cAddress[0];
btParams.u.client.remoteDevAddr.address[1]=cAddress[1];
btParams.u.client.remoteDevAddr.address[2]=cAddress[2];
btParams.u.client.remoteDevAddr.address[3]=cAddress[3];
btParams.u.client.remoteDevAddr.address[4]=cAddress[4];
btParams.u.client.remoteDevAddr.address[5]=cAddress[5];
btParams.role = btVdClient;
btParams.u.client.method = btVdUseUuidList;
btParams.u.client.u.uuidList.tab = &sppUuid;
btParams.u.client.u.uuidList.len = 1;
MemSet(&config, sizeof(config),
0);
config.function = serFncUndefined;
config.drvrDataP = (MemPtr)&btParams;
config.drvrDataSize = sizeof(btParams);
err=SrmExtOpen(sysFileCVirtRfComm,&config,sizeof(config),&unPortId);
}
/***************************/
/* Find a BT device on
air
*/
/***************************/
static void
BT_FindDevice()
{
BT_Close();
if(btLibRefNum)
{
err=BtLibOpen(btLibRefNum,false);
if(err==0)
err=BtLibDiscoverSingleDevice(btLibRefNum,NULL,NULL,0, (BtLibDeviceAddressType
*)cAddress,false,true);
BtLibClose(btLibRefNum);
}
}
/***********************/
/* Load the BT
library */
/***********************/
static void
BT_LoadLibrary()
{
btLibRefNum=0;
err=SysLibFind("Bluetooth Library",&btLibRefNum);
if(err)
err=SysLibLoad(sysFileTLibrary,sysFileCBtLib,&btLibRefNum);
}
/****************/
/* Flush BT
ser */
/****************/
static void
BT_Flush(UInt16 unTimeout)
{
if(unPortId)
err=SrmReceiveFlush(unPortId,unTimeout);
}
/****************/
/* Send BT
data */
/****************/
static void BT_Send(char * pData,UInt16 unLen)
{
if(unPortId)
SrmSend(unPortId,pData,unLen,&err);
}
/*******************/
/* Receive BT
data */
/*******************/
static UInt16
BT_Receive(char * pData,UInt16 unLen,UInt16 unTimeout)
{
UInt16 unLenRead;
if(unPortId)
unLenRead=SrmReceive(unPortId,pData,unLen,unTimeout,&err);
return(unLenRead);
}
|
How to read/write the expansion card:
See "System Management / Virtual File System Manager" on
PODS "Palm OS
Reference.pdf" for details
// Globals
Err
errVFS;
Err
err;
UInt16 unVol;
UInt32 ulIter;
UInt32 ulVFSMgrVer;
UInt32 ulBytesToWrite;
UInt32 ulBytesWritten;
UInt32 ulBytesToRead;
UInt32 ulBytesRead;
UInt32 ulOffset;
void *
cBuffer;
FileRef fRef;
//------------------
// We need the volume
reference unVol
errVFS = FtrGet(sysFileCVFSMgr, vfsFtrIDVersion, &ulVFSMgrVer);
if(errVFS==errNone) // check if VFS's present
{
ulIter = vfsIteratorStart; //Start
value
// Here we get the first
card, if you want more cards call VFSVolumeEnumerate in a loop
errVFS = VFSVolumeEnumerate(&unVol, &ulIter);
}
// Use errVFS as appropriate
//------------------
// To open for write xor ...
err=VFSFileOpen(unVol, "/PALM/Launcher/filename.txt",
vfsModeWrite|vfsModeCreate|vfsModeTruncate, &fRef);
// ... for read (choice only
one open call)
err=VFSFileOpen(unVol, "/PALM/Launcher/filename.txt",
vfsModeRead, &fRef);
//------------------
// To write data
// cBuffer points to your
data buffer
cBuffer = ...
ulBytesToWrite = ...
err=VFSFileWrite(fRef, ulBytesToWrite, cBuffer, &ulBytesWritten);
//------------------
// To read data
// cBuffer points to your
data buffer
cBuffer = ...
ulBytesToRead = ...
err=VFSFileRead(fRef, ulBytesToRead, cBuffer, &ulBytesRead);
//------------------
// To move the file pointer
somewhere
ulOffset = ...
err=VFSFileSeek(fRef, vfsOriginBeginning, ulOffset);
//------------------
// Close the file
VFSFileClose(fRef);
//------------------
// Test EOF
if(VFSFileEOF(fRef))
...
|
How to read/write
files in the internal RAM as a simple standard file (streams)
Note1: when you create the
file the backup flag is cleared, so if you need to backup it in the
HotSync operation you need to set the flag before
Note2: although you use the
file as a binary one the Palm stores it as a database, so if you
transfer it to your PC the file structure is database like not just a
plain binary
// Globals
#define
AppCreator 'you four bytes creator ID'
FileHand fHandle;
UInt32 ulOffset;
UInt32 ulNumBytes;
UInt32 ulFileLen;
UInt32 ulPosition;
Err
err;
//------------------
// To open for write xor ...
fHandle=FileOpen(0,"YourFileName",AppCreator,AppCreator,fileModeReadWrite,&err);
// ... for read
fHandle=FileOpen(0,"YourFileName",AppCreator,AppCreator,fileModeReadOnly,&err);
//------------------
// To read
pBuffer= your buffer
ulNumBytes= number of bytes to read
FileRead(fHandle,pBuffer,ulNumBytes,1,&err);
//------------------
// To write
pBuffer= your buffer
ulNumBytes= number of bytes to write
FileWrite(fHandle,pBuffer,ulNumBytes,1,&err);
//------------------
// To seek the file
err=FileSeek(fHandle,ulOffset,fileOriginBeginning);
//------------------
// To close
FileClose(fHandle);
//------------------
// To test EOF
if(FileEOF(fHandle))
...
//------------------
// To knows the file length
and/or current position
ulPosition = FileTell(fHandle,&ulFileLen,&err);
|
How to quick sort
strings in a list
When you fill a list
with strings usually you start from a compact block of strings, create
an array of pointers, lock them and pass this array to the LstSetListChoices
You can put the sort
just before to call LstSetListChoices
...
hList=SysFormPointerArrayToStrings(cItemsList, unNumOfItems);
pItemsArray=MemHandleLock(hList);
SortList(pItemsArray, unNumOfItems);
LstSetListChoices(pList,pItemsArray,unNumOfItems);
...
Naturally the following
StrCaselessCompare can be changed
with something more appropriate to your specific problem
/**************************************************/
Int16 StrComparF(void *s1, void *s2, Int32 other)
{
char * cS1;
char * cS2;
cS1=*(char **)s1;
cS2=*(char **)s2;
/* Add this if the list is a
file one and you have a double dot '..' in the top item
if(cS1[0]=='.')
return -1;
else if(cS2[0]=='.')
return 1;
*/
return
StrCaselessCompare(cS1, cS2);
}
/**************************************************/
void SortList(void *baseP, UInt16 numOfElements)
{
SysQSort(baseP, numOfElements, sizeof(MemPtr), StrComparF, 0);
}
|