There was some discussion here a few weeks ago about breaking out of a
lengthy calculation if the user presses a button.  It turns out I needed
to write just such a thing yesterday, so I created some simple wrapper
functions to do this.  I'm posting them here in case others find them
useful.

Also, I'd like to hear any comments on this implementation.  I know it
was stated that there are subtleties and potential incompatibilities
with future OSes in writing code like this.  My code seems pretty simple
and straightforward and it seems to work, so if I'm missing anything, or
if you see any problems in it, I'd appreciate hearing your thoughts.

BTW, although this code works fine on the device, it doesn't seem to
work on POSE (version 2.1d26).  The log shows I don't get any
penDownEvents while I'm executing my loop.  Anyone know why this might
be?

The usage is: you call StartUserCancel(), then enter your loop, then
call EndUserCancel().  Within the loop, call UserCancel() periodically,
and if it returns true, break out of the loop.  The code waits
USER_CANCEL_DELAY tenths of a second after StartUserCancel, then puts up
a message (thus if the calculation is short, you don't see a message
flash up and immediately disappear).  If the user touches the screen
while the message is up, the next call to UserCancel returns true.
--Mark



static FormPtr     g_UserCancelWorkingForm;
static WinHandle   g_UserCancelWindow;
static Boolean     g_UserCancelled;
static ULong       g_UserCancelDrawTime;

void StartUserCancel(void)
{
    g_UserCancelled = false;
    g_UserCancelWorkingForm = NULL;
    g_UserCancelDrawTime = TimGetTicks() +
            ((USER_CANCEL_DELAY * SysTicksPerSecond()) / 10);
}

void EndUserCancel(void)
{
    if (g_UserCancelWorkingForm != NULL)
    {
        FrmEraseForm(g_UserCancelWorkingForm);
        FrmDeleteForm(g_UserCancelWorkingForm);
        WinSetDrawWindow(g_UserCancelWindow);
    }
}

Boolean UserCancel(void)
{
    if (g_UserCancelled)
        return true;
    if (g_UserCancelWorkingForm == NULL &&
        TimGetTicks() >= g_UserCancelDrawTime)
    {
        g_UserCancelWindow = WinGetDrawWindow();
        g_UserCancelWorkingForm = FrmInitForm(ID_FORM_WORKING);
        FrmDrawForm(g_UserCancelWorkingForm);
    }
    if (EvtEventAvail())
    {
        EventType event;
        EvtGetEvent(&event, 0);
        if (event.eType == penDownEvent)
        {
            g_UserCancelled = true;
            return true;
        }
        SysHandleEvent(&event);
    }
    return false;
}

Reply via email to