Multi Window Interfaces using EasyGUI.
Ok, EasyGUI is not as powerful as other engines, such as MUI or BGUI, but it is small, fast and friendly.
One of the major feature is that you can use it at different "levels": the easy one and the complex one. Here we will describe one complex method to create multi window interfaces using low-level EasyGUI functions.
The following code opens one single interface with two buttons. The first opens another interface, and the second writes a message on the Shell. The second interface, is a single button interface, which writes another message on the Shell.
Please, note that this code is meant for explanation only.
Amiga is a multitasking machine. Due to this fact, you can have a lot of windows working together on the same screen and everyone sending messages to its own application. One single application can have more than one window sending messages at the same time. From one point of view, this is a problem, because the programmer has to handle all different events correctly, but on the other side, it is one great feature. The programmer can split program functions into different windows and the user can find easily what he/she needs.
Exec, Amiga heart of multitasking, offers different ways to wait for a window event (also to other kind of events, but here we will talk only about window events). The way we use is to wait for a signal using the Wait() function. See autodocs on Exec/Wait() command.
/***************** AMIGA E PROGRAM STARTS HERE ****************************/
MODULE 'tools/EasyGUI', 'tools/exceptions'
/*
First of all, we have to define our GUI handles (for this example, they are
global... hmmm it is not always a good idea to have global vars.)
*/
DEF firstgui:PTR TO guihandle -> The GUI handle of the main gui
DEF secndgui:PTR TO guihandle -> The GUI handle of the second gui we will open
/*
** This is the main proc. All it does is to init the first interface and
** then to begin to handle events.
** Please note the HANDLE keyword: we use exceptions handling!
*/
PROC main() HANDLE
firstgui := egui('Main Window',
[BEVELR,
[EQROWS,
[SBUTTON, {second}, 'Second GUI'],
[SBUTTON, {msg1}, 'Message']
]
]
)
handleevents() -> Here we handle events
EXCEPT DO
closeall() -> Here we close all interfaces
report_exception() -> In case an exception arrives, we show it!
CleanUp(0) -> Just to keep things clean
ENDPROC
/* This is my 'custom' version of guiinit.
** It just try to open the interface and, with the exceptions handler
** we trace possible errors.
*/
PROC egui(wtitle, gui) HANDLE
DEF gh:PTR TO guihandle
gh := guiinit(wtitle, gui) -> Here we init the gui
RETURN gh -> If everything went fine, we just return the guihandler pointer
EXCEPT -> If it does not work properely...
cleangui(gh) -> We clean the gui
ReThrow() -> And ReThrow() the exceptions.
ENDPROC
/*
** Here there is the most important routine.
** We will try to explain it line-by-line
*/
PROC handleevents() HANDLE
DEF res=-1 -> Here we will store messages from the guimessage() function
DEF signal -> Here we store all the ORed sigbits
DEF sig
WHILE (res<0)
IF (secndgui) -> If the user has opened the second gui
-> We create the signal with both first and secnd gui
signal := firstgui.sig OR secndgui.sig
ELSE
-> Else, only first gui is present.
signal := firstgui.sig
ENDIF
sig := Wait(signal) -> Here we wait for
/* Here is the handling heart. We check for sig with both guis.
** The process is this. Sig will contain a sigbit of the
** window which has produced the event.
** All we have to do is to check it with an AND operation
*/
IF sig AND firstgui.sig -> Here we check for the first window
res := guimessage(firstgui) -> And we handle first window event
ELSEIF sig AND secndgui.sig -> Here we check for the second window
res := guimessage(secndgui) -> And we handle second window event
IF res>0 -> If res>0, the user has closed the window, but we do
-> NOT WANT to end the program.
res := -1 -> So we set res to -1 (so WHILE...ENDWHILE will continue)
cleangui(secndgui) -> We close second window gui
secndgui := NIL -> And set secndgui handle to NIL
ENDIF
ENDIF
ENDWHILE
EXCEPT
closeall()
ReThrow()
ENDPROC
/* This proc closes all guis */
PROC closeall()
IF secndgui
cleangui(secndgui)
secndgui := NIL
ENDIF
IF firstgui
cleangui(firstgui)
firstgui := NIL
ENDIF
ENDPROC
/* This proc opens the second GUI
** Note the HANDLE command.
*/
PROC second(i) HANDLE
IF secndgui THEN RETURN
secndgui := egui('Second Window',
[BEVELR,
[SBUTTON, {msg2}, 'Second Message']
]
)
EXCEPT
ReThrow()
ENDPROC
PROC msg1(i)
WriteF('This message comes from window 1!!!\n')
ENDPROC
PROC msg2(i)
WriteF('This message comes from window 2!!!\n')
ENDPROC
/******************** AMIGA E PROGRAMS ENDS HERE **************************/