Arrrgh, this thing is driving me nuts. :-(((
OK, so I disable the automatic execution of start.prc and set an alarm one
second later. OK, so when I get the alarm, I display my form and enter an event
loop. OK, whent he event loop ends, I try to run start.prc manually.
Works almost fine - if there *is* a start.prc, that is. If there isn't, I'm
just shown a blank screen - until the card is removed, when everything is
restored. I even tried to enque a keypress to launch the Launcher - it still
doesn't work. :-((
Debugging the application shows that everything works as it should - the proper
notifications are received and the program does the right thing. But when it
terminates, if there wasn't a start.prc to run - blank screen. :-((( It seems
that somehow the Launcher gets screwed up again...
Can't anybody help me, folks? What am I doing wrong? Below is the current
source of the illustrative application.
Regards,
Vesselin
#include <PalmOS.h>
#include <VfsMgr.h>
#include "CardRsc.h"
#define appCreatorID 'CrMn'
#define appVersionNum 0x01
#define appPrefID 0x00
#define appPrefVersionNum 0x01
#define version40 (sysMakeROMVersion (4, 0, 0, sysROMStageRelease, 0))
#define version41 (sysMakeROMVersion (4, 1, 0, sysROMStageRelease, 0))
#define version60 (sysMakeROMVersion (6, 0, 0, sysROMStageRelease, 0))
typedef struct
{
UInt8 cmd;
UInt16 volRef;
UInt32 dbType, dbCreatorID;
} AlarmInfoType, *AlarmInfoPtr;
UInt32 GetCreatorID (void)
{
UInt32 nCreatorID;
UInt16 nCard;
LocalID LocalDB;
Err err;
err = SysCurAppDatabase (&nCard, &LocalDB);
ErrFatalDisplayIf (err, "Could not get current app database.");
err = DmDatabaseInfo (nCard, LocalDB, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, &nCreatorID);
ErrFatalDisplayIf (err, "Could not get app database info, looking for
creator ID");
return nCreatorID;
}
Boolean MainFormHandleEvent (EventPtr pEvent)
{
Boolean handled;
FormPtr pForm;
UInt32 Monitor, romVersion;
Err err;
UInt16 cardNo;
LocalID dbID;
handled = false;
switch (pEvent->eType)
{
case frmOpenEvent:
pForm = FrmGetActiveForm ();
FrmDrawForm (pForm);
if (FtrGet (GetCreatorID (), 1000, &Monitor) != errNone)
Monitor = false;
FrmSetControlValue (pForm, FrmGetObjectIndex (pForm,
kMainFormMonitorVolumeMountingCheckbox), Monitor);
handled = true;
break;
case ctlSelectEvent:
switch (pEvent->data.ctlSelect.controlID)
{
case kMainFormMonitorVolumeMountingCheckbox:
pForm = FrmGetActiveForm ();
FtrGet (sysFtrCreator, sysFtrNumROMVersion, &romVersion);
if (romVersion < version40)
{
FrmSetControlValue (pForm, FrmGetObjectIndex (pForm,
kMainFormMonitorVolumeMountingCheckbox), false);
handled = true;
break;
}
SysCurAppDatabase (&cardNo, &dbID);
if (FtrGet (GetCreatorID (), 1000, &Monitor) != errNone)
Monitor = false;
if (FrmGetControlValue (pForm, FrmGetObjectIndex (pForm,
kMainFormMonitorVolumeMountingCheckbox)))
{
if (! Monitor)
{
Monitor = true;
err = SysNotifyRegister (cardNo, dbID,
sysNotifyVolumeMountedEvent, NULL, sysNotifyNormalPriority, NULL);
err = SysNotifyRegister (cardNo, dbID,
sysNotifyVolumeUnmountedEvent, NULL, sysNotifyNormalPriority, NULL);
}
}
else
{
if (Monitor)
{
Monitor = false;
err = SysNotifyUnregister (cardNo, dbID,
sysNotifyVolumeMountedEvent, sysNotifyNormalPriority);
err = SysNotifyUnregister (cardNo, dbID,
sysNotifyVolumeUnmountedEvent, sysNotifyNormalPriority);
}
}
FrmSetControlValue (pForm, FrmGetObjectIndex (pForm,
kMainFormMonitorVolumeMountingCheckbox), Monitor);
FtrSet (GetCreatorID (), 1000, Monitor);
handled = true;
break;
default:
break;
}
break;
default:
break;
}
return handled;
}
Boolean InfoFormHandleEvent (EventPtr pEvent)
{
Boolean handled;
FormPtr pForm;
handled = false;
switch (pEvent->eType)
{
case frmOpenEvent:
pForm = FrmGetActiveForm ();
FrmDrawForm (pForm);
handled = true;
break;
default:
break;
}
return handled;
}
void AppStop (void)
{
FrmCloseAllForms ();
}
Boolean AppHandleEvent (EventPtr pEvent)
{
UInt16 formId;
FormPtr pForm;
Boolean handled;
handled = false;
if (pEvent->eType == frmLoadEvent)
{
formId = pEvent->data.frmLoad.formID;
pForm = FrmInitForm (formId);
FrmSetActiveForm (pForm);
switch (formId)
{
case kMainForm:
FrmSetEventHandler (pForm, MainFormHandleEvent);
break;
case kInfoForm:
FrmSetEventHandler (pForm, InfoFormHandleEvent);
break;
default:
break;
}
handled = true;
}
return handled;
}
void AppEventLoop (void)
{
Err error;
EventType event;
do
{
EvtGetEvent (&event, evtWaitForever);
if (SysHandleEvent (&event))
continue;
if (MenuHandleEvent (0, &event, &error))
continue;
if (AppHandleEvent (&event))
continue;
FrmDispatchEvent (&event);
}
while (event.eType != appStopEvent);
}
void RegisterForNotifications (void)
{
UInt16 cardNo;
LocalID dbID;
UInt32 romVersion;
UInt32 Monitor;
Err err;
FtrGet (sysFtrCreator, sysFtrNumROMVersion, &romVersion);
if (romVersion >= version40)
{
if (FtrGet (GetCreatorID (), 1000, &Monitor) != errNone)
Monitor = false;
if (Monitor)
{
SysCurAppDatabase (&cardNo, &dbID);
err = SysNotifyRegister (cardNo, dbID, sysNotifyVolumeMountedEvent,
NULL, sysNotifyNormalPriority, NULL);
err = SysNotifyRegister (cardNo, dbID,
sysNotifyVolumeUnmountedEvent, NULL, sysNotifyNormalPriority, NULL);
}
}
}
void HandleNotification (SysNotifyParamType *np)
{
UInt32 Monitor;
UInt16 cardNo;
LocalID dbID;
AlarmInfoPtr alarmInfo;
DmSearchStateType stateInfo;
Err err;
switch (np->notifyType)
{
case sysNotifyVolumeMountedEvent:
if (FtrGet (GetCreatorID (), 1000, &Monitor) != errNone)
Monitor = false;
if (Monitor)
{
np->handled |= vfsHandledStartPrc;
SysCurAppDatabase (&cardNo, &dbID);
alarmInfo = (AlarmInfoPtr) MemPtrNew (sizeof (AlarmInfoType));
alarmInfo->cmd = 1;
alarmInfo->volRef = ((VFSSlotMountParamType *)
np->notifyDetailsP)->vfsMountParam.volRefNum;
MemPtrSetOwner (alarmInfo, 0);
AlmSetAlarm (cardNo, dbID, (UInt32) alarmInfo, TimGetSeconds ()
+ 1, true);
}
break;
case sysNotifyVolumeUnmountedEvent:
if (FtrGet (GetCreatorID (), 1000, &Monitor) != errNone)
Monitor = false;
if (Monitor)
{
SysCurAppDatabase (&cardNo, &dbID);
err = FtrGet (GetCreatorID (), 2000, (UInt32 *) &alarmInfo);
alarmInfo->cmd = 2;
AlmSetAlarm (cardNo, dbID, (UInt32) alarmInfo, TimGetSeconds ()
+ 1, true);
}
break;
case sysNotifyAppQuittingEvent:
err = FtrGet (GetCreatorID (), 2000, (UInt32 *) &alarmInfo);
err = DmGetNextDatabaseByTypeCreator (true, &stateInfo,
alarmInfo->dbType, alarmInfo->dbCreatorID, true, &cardNo, &dbID);
err = DmDeleteDatabase (cardNo, dbID);
SysCurAppDatabase (&cardNo, &dbID);
err = SysNotifyUnregister (cardNo, dbID, sysNotifyAppQuittingEvent,
sysNotifyNormalPriority);
break;
default:
break;
}
}
UInt32 PilotMain (UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
{
Err err;
UInt16 cardNo;
UInt32 dbType, dbCreatorID, romVersion;
LocalID dbID;
AlarmInfoPtr alarmInfo;
DmSearchStateType stateInfo;
FileRef fileRef;
switch (cmd)
{
case sysAppLaunchCmdNormalLaunch:
FrmGotoForm (kMainForm);
AppEventLoop ();
AppStop ();
break;
case sysAppLaunchCmdSystemReset:
case sysAppLaunchCmdSyncNotify:
RegisterForNotifications ();
break;
case sysAppLaunchCmdNotify:
HandleNotification ((SysNotifyParamType *) cmdPBP);
break;
case sysAppLaunchCmdDisplayAlarm:
alarmInfo = (AlarmInfoPtr) ((SysDisplayAlarmParamType *)
cmdPBP)->ref;
switch (alarmInfo->cmd)
{
case 1:
// Volume mounted alarm - do your thing
FrmGotoForm (kInfoForm);
AppEventLoop ();
AppStop ();
// Start start.prc
alarmInfo->dbCreatorID = 0;
FtrSet (GetCreatorID (), 2000, (UInt32) alarmInfo);
err = VFSFileOpen (alarmInfo->volRef, "/PALM/start.prc",
vfsModeRead, &fileRef);
if (err == errNone)
{
err = VFSFileDBInfo (fileRef, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, &dbType, &dbCreatorID, NULL);
if (err == errNone)
{
err = VFSFileClose (fileRef);
err = DmGetNextDatabaseByTypeCreator (true,
&stateInfo, dbType, dbCreatorID, true, &cardNo, &dbID);
if (err != errNone)
{
err = VFSImportDatabaseFromFile
(alarmInfo->volRef, "/PALM/start.prc", &cardNo, &dbID);
alarmInfo->dbType = dbType;
alarmInfo->dbCreatorID = dbCreatorID;
}
SysUIAppSwitch (cardNo, dbID,
sysAppLaunchCmdNormalLaunch, NULL);
}
}
break;
case 2:
// Volume unmounted alarm - delete start.prc
if (alarmInfo->dbCreatorID == 0)
break;
err = DmGetNextDatabaseByTypeCreator (true, &stateInfo,
alarmInfo->dbType, alarmInfo->dbCreatorID, true, &cardNo, &dbID);
if (err == errNone)
{
err = DmDeleteDatabase (cardNo, dbID);
if (err != errNone)
{
SysCurAppDatabase (&cardNo, &dbID);
FtrGet (sysFtrCreator, sysFtrNumROMVersion,
&romVersion);
if (romVersion > version41 && romVersion <
version60)
err = SysNotifyRegister (cardNo, dbID,
sysNotifyAppQuittingEvent, NULL, sysNotifyNormalPriority, NULL);
else
AlmSetAlarm (cardNo, dbID, (UInt32) alarmInfo,
TimGetSeconds () + 1, true);
}
else
{
MemPtrFree (alarmInfo);
FtrUnregister (GetCreatorID (), 2000);
}
}
break;
default:
break;
}
break;
default:
break;
}
return errNone;
}
--
For information on using the Palm Developer Forums, or to unsubscribe, please
see http://www.palmos.com/dev/support/forums/