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