E per Esperti

Interfacce Multi Finestra utilizzando EasyGUI.

EasyGUI è un motore di gadget-layouting scritto da Wouter per aiutare gli sviluppatori E a creare interfacce font-sensitive e auto aggiustanti. Questo bel modulo è formato da alcuni comandi che possono aiutare chiunque a raggiungere il proprio scopo. Ok, EasyGUI non è potente come altri motori, come MUI o BGUI, ma è piccolo, veloce e facile da usare.

Una delle maggiori caratteristiche è che EasyGUI può essere utilizzato a diversi "livelli": uno semplice e uno complesso. Qui descriveremo un metodo complesso per creare interfacce multi finestra utilizzando le funzioni a basso livello di EasyGUI.

Il codice che segue apre una singola interfaccia con due bottoni. Il primo gadget apre una seconda interfaccia, mentre il secondo scrive un messaggio nella Shell. La seconda interfaccia, è formata da un singolo bottone, che scrive un altro messaggio sulla Shell.

Per favore, notate che il codice è stato scritto solo per spiegazione.


UN PICCOLO BACKGROUND TECNICO

Amiga è una macchina multitasking. A causa di questo fatto, è possibile avere molte finestre che lavorano sullo stesso schermo e ciascuna di esse che manda messaggi alla propria applicazione. Una singola applicazione può avere più di una finestra che manda messaggi contemporaneamente.

Da un certo punto di vista, questo è un problema, perchè il programmatore deve gestire correttamente tutti i segnali che giungono; ma dall'altra parte, questa è una peculiarità molto particolare. Il programmatore può suddividere le funzioni del programma in finestre differenti e l'utente può trovare facilmente quello che sta cercando.

Exec, il cuore del multitasking di Amiga, offre metodi differenti per attendere un evento di una window (anche per altri tipi di eventi, ma qui parleremo solo di eventi di finestre). Il metodo che utilizzeremo è di attendere per un segnale utilizzando il comando Wait(). Consultare gli autodocs riguardanti il comando Exec/Wait().


IL PROGRAMMA

Qui segue il programma. Per averlo completo in formato lha, clickate (attenzione, i commenti sono in inglese) qui.
/************ IL PROGRAMMA AMIGA E INIZIA QUI ************************/
MODULE 'tools/EasyGUI', 'tools/exceptions'

/*
Prima di tutto, dobbiamo definire gli handler alle nostre GUI (per questo
esempio, sono globali.... hmmm non è sempre una buona idea avere variabili
globali)
*/

DEF firstgui:PTR TO guihandle -> The GUI handle della gui principale
DEF secndgui:PTR TO guihandle -> The GUI handle della seconda gui 

/*
** Questa è la procedura main. Tutto quel che fa è inizializzare la prima
** Interfaccia e iniziare a manovrare gli eventi.
** Per favore, notate la parola chiave HANDLE: usiamo exception handling!
*/
PROC main() HANDLE
  firstgui := egui('Finestra Princ',
    [BEVELR,
      [EQROWS,
        [SBUTTON, {second}, 'Seconda GUI'],
        [SBUTTON, {msg1}, 'Messaggio']
      ]
    ]
  )

  handleevents()      -> Qui gestiamo gli eventi

EXCEPT DO
  closeall()          -> Chiudiamo le interfacce
  report_exception()  -> Nel caso sia arrivata una exception, la mostriamo.
  CleanUp(0)          -> Ripuliamo tutto.
ENDPROC

/*
** Questa è la mia versione 'custom' di guiinit.
** Prova semplicemente ad aprire l'interfacca e con l'handler di
** exceptions, trappiamo gli errori.
*/
PROC egui(wtitle, gui) HANDLE
  DEF gh:PTR TO guihandle  

  gh := guiinit(wtitle, gui)    -> Qui inizializziamo l'interfaccia.

  RETURN gh       -> Se tutto è andato bene, restituiamo il puntatore guihandle

EXCEPT            -> Se qualcosa è andato storto...
  cleangui(gh)    -> Puliamo l'interfaccia
  ReThrow()       -> e ReThrow() (rilanciamo) l'eccezione
ENDPROC

/*
** Qui c'è la routine più importante.
** Cercheremo di spiegarla linea per linea.
*/
PROC handleevents() HANDLE
  DEF res=-1      -> Qui memorizziamo i risultati di guimessage()
  DEF signal      -> Qui memorizziamo tutti i sigbit ORati
  DEF sig

  WHILE (res<0)
    IF (secndgui) -> Se l'utente ha aperto la seconda finestra
      -> Creiamo il segnale di entrambe le interfacce
      signal := firstgui.sig OR secndgui.sig
    ELSE
      -> Altrimenti, solo la prima interfaccia è stata creata
      signal := firstgui.sig
    ENDIF

    sig := Wait(signal)  -> Qui aspettiamo

    /* Questo è il cuore della gestione degli eventi. Controlliamo il sig
    ** con entrambe le interfacce. Sig conterrà il sigbit della finestra
    ** che ha prodotto l'evento. Tutto quello che dovremo fare è
    ** di controllare la finestra con una operazione di AND
    */
    IF sig AND firstgui.sig   -> Controlliamo la prima finestra
      res := guimessage(firstgui) -> E gestiamo gli eventi. 
      
    ELSEIF sig AND secndgui.sig -> Qui controlliamo la seconda finestra
      res := guimessage(secndgui) -> E gestiamo gli eventi
      IF res>0    -> Se res>0, l'utente ha chiuso la finestra,
                  -> ma NON VOGLIAMO finire il programma!
        res := -1 -> Quindi metteremo res a -1 (WHILE...ENDWHILE continuerà)
        cleangui(secndgui) -> Chiudiamo l'interfaccia
        secndgui := NIL    -> E settiamo l'handle della secndgui to NIL
      ENDIF
    ENDIF
  ENDWHILE

EXCEPT 
  closeall()
  ReThrow()
ENDPROC

/* Questa procedura chiude tutte le interfacce */
PROC closeall()
  IF secndgui 
    cleangui(secndgui)
    secndgui := NIL
  ENDIF

  IF firstgui
    cleangui(firstgui)
    firstgui := NIL
  ENDIF
ENDPROC

/*
** Questa procedura apre la seconda interfaccia
** Notate il comando HANDLE
*/
PROC second(i) HANDLE
  IF secndgui THEN RETURN

  secndgui := egui('Seconda Finestra',
    [BEVELR,
      [SBUTTON, {msg2}, 'Secondo Messaggio']
    ]
  )

EXCEPT 
  ReThrow()
ENDPROC

PROC msg1(i) 
  WriteF('Questo messaggio arriva dalla finestra 1!!!\n')
ENDPROC

PROC msg2(i)
  WriteF('Questo messaggio arriva dalla finestra 2!!!\n')
ENDPROC

/**************** FINE DEL PROGRAMMA IN AMIGA E **********************/


Pagina Principale


    Scritto da: Fabio Rotondo      e-mail: fsoft@intercom.it
                C.so Vercelli 9
                28100 Novara
                ITALY               tel:    (ITA) - (0)321 459676