> You may be able to fix this by registering for
> sysNotifyNormalPriority - 1, ensuring that you're notified just
> after the launcher, and your SysUIAppSwitch will override the
> launcher's.

Ben, that does not make sense. According to the documentation

http://www.palmos.com/dev/support/docs/palmos/PalmOSReference/NotifyMgr.html#1024486

the "priority" argument of SysNotifyRegister is of type Int8. According to the 
include file Core/System/NotifyMgr.h, sysNotifyNormalPriority is defined as 0. 
Therefore, the expression "sysNotifyNormalPriority - 1" would evaluate to -1 or 
0xFF, depending on how it is used later by the system. That's not "just after" 
- that sounds more like either "just before" or as "as late as possible" to me 
:-). In addition, the documentation says

"In general, Palmâ recommends using a value whose least significant bits are 
0 (such as 32, 64, 96, and so on)."

Nevertheless, I tried using both "sysNotifyNormalPriority - 1" and "240" and 
the result is exactly the same - my application crashes if the notification 
arrives while the Launcher is running - due to the unexpected appStopEvent. :-(

OK, perhaps I am blind and am not seeing something terribly obvious. Here, I 
made a small illustrative application. It is supposed to allow the user to turn 
on and off the monitoring of volume insertion (with a checkbox on its main 
form). Then, if the monitoring is on and a card is inserted, the application 
displays an information form. This application behaves pretty much like the 
original I'm writing - in the sense that it crashes if the notification arrives 
while the Launcher is running and doesn't crash otherwise.

Ben, could you or anyone please look at this and see whether I am making some 
obvious mistake? Or is what I want to do impossible to do?!

Source code, Card.c:

----------8<----Cut here----->8--------
#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))

Boolean MainFormHandleEvent (EventPtr pEvent)
{
    Boolean handled;
    FormPtr pForm;
    UInt32 Monitor;
    Err err;
    UInt16 cardNo;
    LocalID dbID;

    handled = false;
    switch (pEvent->eType)
    {
        case frmOpenEvent:
            pForm = FrmGetActiveForm ();
            FrmDrawForm (pForm);
            if (FtrGet (appCreatorID, 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 ();
                    SysCurAppDatabase (&cardNo, &dbID);
                    if (FtrGet (appCreatorID, 1000, &Monitor) != errNone)
                        Monitor = false;
                    if (FrmGetControlValue (pForm, FrmGetObjectIndex (pForm, 
kMainFormMonitorVolumeMountingCheckbox)))
                    {
                        if (! Monitor)
                        {
                            Monitor = true;
                            err = SysNotifyRegister (cardNo, dbID, 
sysNotifyVolumeMountedEvent, NULL, sysNotifyNormalPriority - 1, NULL);
                        }
                    }
                    else
                    {
                        if (Monitor)
                        {
                            Monitor = false;
                            err = SysNotifyUnregister (cardNo, dbID, 
sysNotifyVolumeMountedEvent, sysNotifyNormalPriority - 1);
                        }
                    }
                    FrmSetControlValue (pForm, FrmGetObjectIndex (pForm, 
kMainFormMonitorVolumeMountingCheckbox), Monitor);
                    FtrSet (appCreatorID, 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 (appCreatorID, 1000, &Monitor) != errNone)
            Monitor = false;
        if (Monitor)
        {
            SysCurAppDatabase (&cardNo, &dbID);
            err = SysNotifyRegister (cardNo, dbID, sysNotifyVolumeMountedEvent, 
NULL, sysNotifyNormalPriority - 1, NULL);
        }
    }
}

void HandleNotification (SysNotifyParamType *np)
{
    UInt32 Monitor;

    switch (np->notifyType)
    {
        case sysNotifyVolumeMountedEvent:
            if (FtrGet (appCreatorID, 1000, &Monitor) != errNone)
                Monitor = false;
            if (Monitor)
            {
                FrmGotoForm (kInfoForm);
                AppEventLoop ();
                AppStop ();
            }
            break;
        default:
            break;
    }
}

UInt32 PilotMain (UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
{
    switch (cmd)
    {
        case sysAppLaunchCmdNormalLaunch:
            FrmGotoForm (kMainForm);
            AppEventLoop ();
            AppStop ();
            break;
        case sysAppLaunchCmdSystemReset:
        case sysAppLaunchCmdSyncNotify:
            RegisterForNotifications ();
            break;
        case sysAppLaunchCmdNotify:
            HandleNotification ((SysNotifyParamType *) cmdPBP);
            break;
        default:
            break;
    }
    return errNone;
}
----------8<----Cut here----->8--------

XRD file (Card.xrd) for the PODS Resource Editor, containing the resources. 
Instruct the Resource Editor to generate a header file CardRsc.h in the 
directory where Card.c resides.

----------8<----Cut here----->8--------
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<PALMOS_RESOURCE_FILE>

        <FILE_PREFERENCES>
                <PREFS_GENERATE_HEADER> TRUE </PREFS_GENERATE_HEADER>
                <PREFS_HEADER_FILE> "../src/CardRsc.h" </PREFS_HEADER_FILE>
                <VARIABLE_TEMPLATE> "" </VARIABLE_TEMPLATE>
        </FILE_PREFERENCES>
        <FORM_RESOURCE RESOURCE_ID="1000" LOCALE="enUS" COMMENT="Main">
                <FORM_ID> 1000 </FORM_ID>
                <BOUNDS>
                        <LEFT> 0 </LEFT>
                        <TOP> 0 </TOP>
                        <WIDTH> 160 </WIDTH>
                        <HEIGHT> 160 </HEIGHT>
                </BOUNDS>
                <USABLE> TRUE </USABLE>
                <MODAL> FALSE </MODAL>
                <SAVE_BEHIND> FALSE </SAVE_BEHIND>
                <HELP_ID> 0 </HELP_ID>
                <MENU_ID> 1000 </MENU_ID>
                <DEFAULT_BUTTON> 0 </DEFAULT_BUTTON>
                <TITLE_ICON> FALSE </TITLE_ICON>
                <TITLE_BAR_FOCUSABLE> FALSE </TITLE_BAR_FOCUSABLE>
                <FORM_OBJECTS>
                        <FORM_TITLE>
                                <TEXT> "Card" </TEXT>
                        </FORM_TITLE>
                        <FORM_CHECKBOX COMMENT="Monitor">
                                <ID> 1000 </ID>
                                <BOUNDS>
                                        <LEFT> 15 </LEFT>
                                        <TOP> 31 </TOP>
                                        <WIDTH> 126 </WIDTH>
                                        <HEIGHT> 12 </HEIGHT>
                                </BOUNDS>
                                <USABLE> TRUE </USABLE>
                                <ENABLED> TRUE </ENABLED>
                                <TEXT> "Monitor Volume Mounting" </TEXT>
                                <FONT_ID> STD_FONT </FONT_ID>
                                <GROUP_ID> 0 </GROUP_ID>
                                <SELECTED> FALSE </SELECTED>
                        </FORM_CHECKBOX>
                </FORM_OBJECTS>
        </FORM_RESOURCE>

        <FORM_RESOURCE RESOURCE_ID="1100" COMMENT="Info">
                <FORM_ID> 1100 </FORM_ID>
                <BOUNDS>
                        <LEFT> 0 </LEFT>
                        <TOP> 0 </TOP>
                        <WIDTH> 160 </WIDTH>
                        <HEIGHT> 160 </HEIGHT>
                </BOUNDS>
                <USABLE> TRUE </USABLE>
                <MODAL> FALSE </MODAL>
                <SAVE_BEHIND> FALSE </SAVE_BEHIND>
                <HELP_ID> 0 </HELP_ID>
                <MENU_ID> 0 </MENU_ID>
                <DEFAULT_BUTTON> 0 </DEFAULT_BUTTON>
                <TITLE_ICON> FALSE </TITLE_ICON>
                <TITLE_BAR_FOCUSABLE> FALSE </TITLE_BAR_FOCUSABLE>
                <FORM_OBJECTS>
                        <FORM_TITLE>
                                <TEXT> "Volume Info" </TEXT>
                        </FORM_TITLE>
                        <FORM_LABEL COMMENT="Mounted">
                                <ID> 1000 </ID>
                                <LOCATION>
                                        <X> 24 </X>
                                        <Y> 25 </Y>
                                </LOCATION>
                                <USABLE> TRUE </USABLE>
                                <FONT_ID> STD_FONT </FONT_ID>
                                <TEXT> "A volume was just mounted." </TEXT>
                        </FORM_LABEL>
                        <FORM_LABEL COMMENT="Volume Label">
                                <ID> 1001 </ID>
                                <LOCATION>
                                        <X> 52 </X>
                                        <Y> 40 </Y>
                                </LOCATION>
                                <USABLE> FALSE </USABLE>
                                <FONT_ID> STD_FONT </FONT_ID>
                                <TEXT> "Volume Label:" </TEXT>
                        </FORM_LABEL>
                        <FORM_FIELD COMMENT="Volume Label">
                                <ID> 1002 </ID>
                                <BOUNDS>
                                        <LEFT> 5 </LEFT>
                                        <TOP> 58 </TOP>
                                        <WIDTH> 150 </WIDTH>
                                        <HEIGHT> 12 </HEIGHT>
                                </BOUNDS>
                                <USABLE> FALSE </USABLE>
                                <EDITABLE> FALSE </EDITABLE>
                                <SINGLE_LINE> TRUE </SINGLE_LINE>
                                <DYNAMIC_SIZE> FALSE </DYNAMIC_SIZE>
                                <UNDERLINE> NO_UNDERLINE </UNDERLINE>
                                <JUSTIFICATION> LEFT_ALIGN </JUSTIFICATION>
                                <AUTO_SHIFT> FALSE </AUTO_SHIFT>
                                <HAS_SCROLLBAR> FALSE </HAS_SCROLLBAR>
                                <NUMERIC> FALSE </NUMERIC>
                                <MAX_CHARS> 32 </MAX_CHARS>
                                <FONT_ID> STD_FONT </FONT_ID>
                                <MAX_VISIBLE_LINES> 1 </MAX_VISIBLE_LINES>
                        </FORM_FIELD>
                </FORM_OBJECTS>
        </FORM_RESOURCE>

</PALMOS_RESOURCE_FILE>
----------8<----Cut here----->8--------

If the above two source are too manged to be useful, e-mail me and I'll send 
you the original files as attachments.

WARNING: If somebody wants to try the above on a real device, please have in 
mind that it sets a feature (ID = 'CrMn', index = 1000) and never unregisters 
it. I personally dislike programs that don't clean up after themselves but this 
is just an illustrative application and I didn't want to clutter the code that 
illustrates the problem with additional handling of buttons and forms to remove 
the feature.

Regards,
Vesselin
-- 
For information on using the Palm Developer Forums, or to unsubscribe, please 
see http://www.palmos.com/dev/support/forums/

Reply via email to