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 **************************/