Introducció al desenvolupament d'aplicacions per a Palm OS (5a part).

Amb la col·laboració de http://www.dactil.info/cosespalm

Gestionant els events.

Per diverses raons el llenguatge de programació C ha esdevingut el més utilitzat alhora de desenvolupar aplicacions per Palm OS, per tant utilitzarem el C per mostrar els mecanismes bàsics de la gestió d'events. En propers capítols d'aquesta serie ja presentarem altres alternatives la llenguatge C.

Per altre banda el que veurem a continuació és un exemple de la relativa facilitat amb que gestionem els events i desenvolupem el cor de la nostra aplicació, no obstant per començar a crear una aplicació en C, necessitarem encara algunes coses més que veurem en el proper capítol, on ja ens podrem posar amb la part pràctica del desenvolupament.

Com ja vaig comentar en el capítol anterior: "La nostra aplicació estarà funcionant però no reaccionarà fins que rebi un event concret. D'aquesta manera l'aplicació està pendent de quan l'usuari la comença a utilitzar"

Per tal de que això sigui possible, totes les aplicacions Palm OS, han d'utilitzar unes funcions concretes que s'encarreguen de la tasca d'escoltar events i inicialitzar recursos bàsics de l'aplicació. Això significa que tindrem sempre un mateix conjunt de funcions que seran el cor de la nostra aplicació, i que utilitzarem de la mateixa manera en qualsevol altre aplicació que desenvolupem.

Dit d'un altre manera, ens podem crear el que s'anomena un esquelet de codi, que reciclem i adaptem d'una aplicació a una altre.

Aquest esquelet, amb els canvis necessaris, esdevindrà el fitxer principal de l'aplicació i és per tant on habitualment situarem el codi que gestiona els events.

La principal funció, és PilotMain que fa tasques similars a la main() tradicional del C
UInt32 PilotMain(UInt16 launchCode, MemPtr cmdPBP, UInt16 launchFlags)
{
      Err err = 0;
      if (launchCode == sysAppLaunchCmdNormalLaunch) {
             if ((err = StartApplication()) == 0) {
                    EventLoop();
                    StopApplication();
             }
      }
      return err;
}
Podem observar que utilitzem tres funcions més:

- StartApplication()
Encarregada de gestionar les tasques necessàries en el moment que s'engega l'aplicació
- StopApplication()
Encarregada de gestionar les tasques de quan es tanca l'aplicació. Es a dir quan l'usuari salta a un altre aplicació o torna al menú inicial d'aplicacions del Palm. Per exemple si volem assegurar que abans de tancar l'aplicació es guarden les dades que l'usuari ha estat utilitzant, en aquesta funció posariem el codi encarregat de fer-ho.

- EventLoop()
La funció encarregada directament de la gestió d'events i per tant la que ens interessa ara.

Podeu observar que utilitzo noms de les funcions en angles, bé això és així per costum i herència, però les podem escriure perfectament en català.
L'important no és el nom si no el que fan. El que no podem canviar és el nom de la funció principal PilotMain.

El codi d'abans podria ser perfectament:
UInt32 PilotMain(UInt16 launchCode, MemPtr cmdPBP, UInt16 launchFlags)
{
      Err err = 0;
      if (launchCode == sysAppLaunchCmdNormalLaunch) {
             if ((err = IniciAplicacio()) == 0) {
                    GestioEvents();
                    FinalAplicacio();
             }
      }
      return err;
}
Ens centrem ara en la funció de gestió d'events anomenada EventLoop(), en el meu exemple

static void EventLoop()
{
      EventType event;
      UInt16 error;
      do {
             EvtGetEvent(&event, evtWaitForever);
             if (!SysHandleEvent(&event)) {
                    if (!MenuHandleEvent(0, &event, &error)) {
                           if (!ApplicationEventHandler(&event)) {
                                  FrmDispatchEvent(&event);
                           }
                    }
              }
      }
      while (event.eType != appStopEvent);
}
Aquesta funció utilitza funcions pròpies de Palm OS com EvtGetEvent i MenuHandleEvent encarregades de rebre el fluxe d'events. De totes elles la que ens interessa ara en concret és ApplicationEventHandler() que és la nostra funció per gestionar només els events que ens interessen.

Aquesta funció tindrà l'aspecte següent:
static Boolean ApplicationEventHandler(EventPtr event)
{
      Boolean handled = false;
      switch (event->eType) {
             case frmLoadEvent: {
                    FormPtr pForm = FrmInitForm(event->data.frmLoad.formID);
                    FrmSetActiveForm(pForm);
                    FrmSetEventHandler(pForm, MostraFontsEventHandler);
                    handled = true;
                    break;
             }
             case menuEvent:
                    switch (event->data.menu.itemID) {
                           case Tipo0:
                                  CanviFont(stdFont);
                                  break;
                           case Tipo1:
                                  CanviFont(boldFont);
                                  break;
                           case Tipo2:
                                  CanviFont(largeFont);
                                  break;
                           case Tipo7:
                                  CanviFont(largeBoldFont);
                                  break;
                           case HelpMenuAbout:
                                  FrmAlert(AboutAlert);
                                  break;
                           }
                           handled = true;
                           break;
                    default:
                           break;
             }
      return handled;
}
Hi ha molts tipus d'events per això el tractament també és una mica diferent entre ells. En la nostra funció ApplicationEventHandler() Podeu observar que s'utilitza l'estructura switch/case propia de C, per bifurcar entre events de menú menuEvent i altres events frmLoadEvent (recordeu que els noms d'events estant definits en el SDK de Palm OS i es poden consultar en els manuals de referencia).

Com també podeu observar en el event menuEvent tornem a utilitzar un switch/case per esbrinar quina opció de menú ha escollit l'usuari.

Això és possible fer-ho d'aquesta manera tant senzilla ja que els events a més a més de notificar-nos una acció concreta de l'usuari, sovint també porten dades de l'acció realitzada.

En concret el event menuEvent ve acompanyat del identificador de l'opció del menú escollida. Per accedir-hi utilitzem event->data.menu.itemID dins un switch.

A partir d'aquí ja posem les funcions i codi necessari per tal de que es realitzi una tasca concreta.

En aquest exemple esteu veient codi de l'aplicació mostrafonts.prc, on gestionem un menú de quatre opcions que permet canviar el tipus de tipografia. També gestionem el HelpMenuAbout que és l'identificador de l'opció de menú que mostra la pantalla de crédits de l'aplicació.

Quan l'usuari selecciona una opció del menú de mostrafonts.prc, Palm OS envia un event que finalment arriba a aquesta funció on es determina que s'ha de fer d'acord a l'opció escollida per l'usuari.

En el proper capítol aprofundirem una mica més en les parts essencials de la funció ApplicationEventHandler(), i ens preparem ja per desenvolupar de manera pràctica, la nostra primera aplicació Palm OS.

Següent: Introducció al desenvolupament d'aplicacions per a Palm OS (6a part).
Anterior: Introducció al desenvolupament d'aplicacions per a Palm OS (4a part)

Comentaris

  1. Per a quines versions del sistema operatiu i per a quins compiladors serveix aquest exemple?
    Per altra banda, suposo que per afer servir funcions en catal�, aquestes funcions s'hauran de definir en algun lloc, si �s aix�, creus que valdria la pena fer una llista de les principals funcions, traduir-les per a tots els programadors catalans, i preparar un arxiu de definicions estandar?

    ResponElimina

Publica un comentari a l'entrada

Entrades populars d'aquest blog

Els camins del paradís perdut - Llorenç Riber

Ens hem traslladat a palmcat.tiddlyspot.com

Conversió de text a parla en català