Interfacce Multi Finestra utilizzando EasyGUI.
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.
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 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 **********************/
Scritto da: Fabio Rotondo e-mail: fsoft@intercom.it
C.so Vercelli 9
28100 Novara
ITALY tel: (ITA) - (0)321 459676