home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AMIGA PD 1
/
AMIGA-PD-1.iso
/
Programme_zum_Heft
/
Programmieren
/
Kurztests
/
ACE
/
Prgs
/
Library
/
OpenWindow.b
< prev
next >
Wrap
Text File
|
1994-09-18
|
14KB
|
262 lines
{*
** This program was sent to me (via John Stiwinter) from Jeff Harris.
** Thanks Jeff!
**
** Note that if one were to rewrite the following - removing comments -
** using built-in ACE commands/functions, the whole thing would take about
** half a dozen lines of code. This should give you some idea of the work
** being done by ACE internally when you issue a command like WINDOW/SCREEN.
*}
REM A very simple "Hello World" Program That Runs Under ACE to demonstrate the
REM use of system calls in ACE.
REM Ported to AmigaBasic and ACE by Jeffrey Harris from Example in Intuition
REM RKM. This program is public domain.
REM Note: This Program uses BMAPS files for the AmigaDOS 1.3 Libraries!
REM Compatibility with 2.0+ Libraries and BMAPS has not been tested and is
REM not guaranteed, although the program runs fine on AmigaDOS 3.0.
REM The program runs from a shell, or from WB, but diagnostics are only
REM printed when run from a shell window.
REM There are four ways of accessing structures for making system calls:
REM The first is to do an include from a header file (#?.h), which has the
REM structure predefined.
REM Note: the '#' on the following line is a preprocessor directive. The
REM '<' and '>' brackets around "intuition.h" tell the preprocessor to look
REM in the aceinclude: directory.
#include <intuition.h> 'include file for window and screen stuff
REM The second way to access a structure is for a programmer to define it
REM himself.
REM Define the MsgPort structure we will need using a self-made STRUCT
REM definition (this definition is actually a system structure that comes
REM from the EXEC RKM).
STRUCT MsgPort
STRING mp_Node SIZE 14 'this is actually a Node structure
BYTE mp_Flags
BYTE mp_SigBit
LONGINT mp_SigTask '* (a pointer) to a Task structure
STRING mp_MsgList SIZE 14 'this is actually a message linked list
END STRUCT 'structure
REM To access system routines, we must first open the Libraries that contain
REM them. The next four lines do that. These are the libraries we will need
REM for this program.
LIBRARY "diskfont.library"
LIBRARY "exec.library"
LIBRARY "intuition.library"
LIBRARY "graphics.library"
REM Next, we must tell ACE which system routines we want out of those
REM libraries. It is more efficient during compiling to put those routines
REM together that come from the same library.
REM initialize function calls to intuition
DECLARE FUNCTION OpenWindow&() LIBRARY
DECLARE FUNCTION OpenScreen&() LIBRARY
DECLARE FUNCTION CloseWindow() LIBRARY 'this function does not return a
REM parameter, so the trailing '&' is not necessary.
DECLARE FUNCTION CloseScreen() LIBRARY 'ditto
REM initialize function calls to Exec
DECLARE FUNCTION AllocMem&() LIBRARY
DECLARE FUNCTION FreeMem() LIBRARY 'ditto
REM since Wait() conflicts with an Amigabasic Reserved Work, the system call
REM has been renamed xWait
DECLARE FUNCTION xWait&() LIBRARY
REM initialize function calls to DiskFont Library
DECLARE FUNCTION OpenDiskFont&() LIBRARY
DECLARE FUNCTION CloseFont() LIBRARY 'does not return a parameter
REM initialize function calls to Graphics Library
DECLARE FUNCTION Text&() LIBRARY
DECLARE FUNCTION Move&() LIBRARY
REM Let's play it safe, and initialize our pointers; always a good practice!
MyMem&=0 'this will be the pointer to our allocated memory
MyScreen&=0 'this will be the pointer to our defined screen structure
rp&=0 'pointer to window's rastport (for text and graphics stuff)
TF&=0 'pointer to our TextFont structure
REM since the next two pointers directly access defined structures, we
REM DECLARE them, as shown; the '*' in front of the pointer signifies that
REM the system will allocate the memory for the structure and initialize it
REM later.
DECLARE STRUCT MsgPort *MyUP 'used to wait on a closewindow gadget click
DECLARE STRUCT WindowStruct *MyWindow 'the pointer to our window structure
REM a good programming practice is to provide a short main routine, and put
REM the job of doing various things in subroutines or subprograms, which
REM makes the program very structured, modular, and easy to follow.
REM Labels always have a trailing colon; the 'Main:' is not needed, but
REM provides clarity.
Main:
gosub GetMem 'the memory allocation subroutine
REM Note how the IF-THEN statements keep the program in check; an error
REM returned by one subroutine could cause a system crash in the next if we
REM did not provide for it.
IF MyMem&<>0 THEN GOSUB ScrnSetup 'the screen setup and display subroutine
IF MyScreen&<>0 THEN GOSUB WinSetup 'the window setup and display subroutine
IF MyWindow<>0 THEN GOSUB WaitSig 'subroutine to wait on a close-window
REM gadget mouse click
GOSUB CleanUp 'cleans up the program after an error or that mouse click
END 'terminates the program; very important! Otherwise, the program runs
REM right through the subroutines again, often with disasterous results!
GetMem:
REM 'Before' has to be a long integer because the value it returns could be
REM larger than 65,000; hence the trailing '&'
Before&=FRE(-1) 'check the total system free memory before we start
REM allocating it; used for checking that all the memory we allocated is
REM freed at the end of the program. Note that since the program has started,
REM and the system has to allocate it some memory to load, the memory
REM displayed by workbench may not be the same as displayed here.
PRINT "Memory Before Allocations is ";Before&
REM To allocate memory using AllocMem&(), we need to tell it what we need...
MemFlags&=SHL(1,16)+2 'Clear Mem Block, CHIP Mem (for INTUITION AND GRAPHICS
REM stuff) and how much. One hundred twenty bytes is sufficient for our
REM needs here. Note 120 must be represented as a long integer: 120&.
REM Now, make the system call to allocate the needed memory; note that instead,
REM we could have used the equivalent ACE Command: MyMem&=Alloc(120,3)
MyMem&=AllocMem&(120&,MemFlags&) 'Allocate 120 Bytes of Memory
REM AllocMem&() returns the pointer to our memory, or zero if it could not
REM allocate any memory.
IF MyMem&=0 THEN
PRINT "Insufficient Memory"
ELSE
PRINT "My memory is located at ";MyMem&
REM now determine how much memory is free, and show; difference should equal
REM what we asked for.
After&=FRE(-1)
PRINT "Memory After is Allocation is ";After&
PRINT "Memory Has Been Reduced by ";After& - Before&
END IF
RETURN 'completed what we need to in this routine; go back to calling routine
ScrnSetup:
REM First thing we want to do (but optional) is to select the screen font;
REM to do that, we set up TextAttr Structure using the third method of
REM creating a structure: using an array, which we must DIMension before use
DIM TextAttr&(1) 'use long words for array; it is important that we align the
REM infomation properly; the '(1)' signifies that we need only two array
REM elements.
Myfont$="garnet.font" 'decide on a font; needs to be in fonts: directory
REM The first variable in the structure is a pointer to the string with the
REM font name; we pass that address using the SADD function for strings.
TextAttr&(0)=SADD(Myfont$) 'pointer to our Font in TextAttr Structure
REM the second variable are the flags that tell us about the font: point size
REM is a word-sized variable, which resides in the upper word of the long word
REM TextAttr&(1); got that? Next comes style attributes in the next byte, and
REM finally any flags in the lowest byte of that long word. Graphically:
REM bit: 0 (LSB) 7 15 23 31(MSB)
REM point size style flags
REM <------- increasing memory address
TextAttr&(1)=SHL(9,16)+66 'flags for font - designed (not scalable),
REM diskbased (that's the 66 part), normal attributes (for style = 0),
REM 9 Point font.
REM Note that it is not really necessary to actually open the font, as the
REM screen statement sets the default font by using the TextAttr structure
REM directly.
REM However, with the OpenDiskFont call, we could have set up another
REM TextAttr structure, called OpenDiskFont() and SetFont() and changed to a
REM different font for our window text.
TF&=OpenDiskFont&(@TextAttr&(0)) 'Open the normal attribute, 9 point Garnet Font
IF TF&<>0 THEN
PRINT "Address for TextFont is ";TF&
ELSE
PRINT "Requested Font Open Failed"
REM will fail if font is not in Fonts: or Diskfont.library is not in
REM libs:
END IF
REM Set Up Screen Structure
REM The fourth way of setting up a structure in memory is to allocate some
REM memory, as we have done, and poke the data into that allocated memory.
REM WARNING! Make sure you know what you are doing! Poking into unallocated
REM memory, or beyond what you have allocated, can cause a system crash, as
REM can putting inappropriate values in memory for a particular structure
REM element, or placing them inappropriately (ie, wrong memory location, or
REM wrong offset within a word or longword).
REM To set up a screen structure, poke the required information into the
REM memory locations as shown. This information comes from the Intuition RKM;
REM the 2.0 autodoc manual shows structure offsets, which makes doing this
REM MUCH easier. Some values are byte or word length, and so must be shifted
REM 8, 16, or 24 bits to put them in the right location. Memory mapping for
REM byte and word values (16 bits) is the same as for arrays discussed above.
REM What each value represents is shown in a comment after each line.
POKEL MyMem&,SHL(20,16)+20 'left edge, top edge
POKEL MyMem&+4,SHL(320,16)+200 'width, height
POKEW MyMem&+8,4 'depth; note that poking a byte (POKE) or word (POKEW) can
REM save having to make an offset, but takes more POKEs overall.
POKEW MyMem&+10,SHL(21,8)+14 'Detail,block Pen (No View Modes Set)
POKEW MyMem&+14,15 'Custom Screen
POKEL MyMem&+16,@TextAttr&(0) 'Default Font; note how we pass the address of
REM our TextAttr structure?
Title$="A Simple Screen"
POKEL MyMem&+20,SADD(Title$) 'Default Title for This Screen
REM all the data for our screen is defined; now make the call to open it
MyScreen&=OpenScreen&(MyMem&) 'open the screen
IF MyScreen&=0 THEN 'MyScreen& will remain 0 if screen couldn't be opened
PRINT "Open Screen Failed"
ELSE 'otherwise we will see a screen pop open before our very eyes!
PRINT "Screen Pointer is ";MyScreen& 'address to Screen structure
END IF
RETURN 'finished playing with the screen
WinSetup:
REM Time to set up a NewWindow Structure.
REM In general, we follow the same procedure as setting up a new screen, but
REM some of the parameters are different.
POKEL MyMem&+60,SHL(20,16)+20 'left edge,top edge
POKEL MyMem&+64,SHL(300,16)+100 'Width,height
POKEW MyMem&+68,SHL(23,8)+5 'Detail,block Pen
POKEL MyMem&+70,SHL(1,9) 'IDCMP Flags; in this case, notify us user clicks the
REM CloseWindow gadget.
POKEL MyMem&+74,SHL(1,12)+10 'Window Flags and Settings - Smart_Refresh,
REM Activate Window, give us a Dragbar and CloseWindow Gadget, please!
Title$="A Simple Window"
POKEL MyMem&+86,SADD(Title$) 'Pointer to Window Title
POKEL MyMem&+90,MyScreen& 'Pointer to screen for this window (this is only
REM needed for a custom screen, as we are using in this example).
POKEW MyMem&+106,15 'Value for a Screen Type that Corresponds to our screen -
REM in this case, a custom screen (as opposed to the Workbench screen).
REM Now, since we previously defined the Window Structure by #including
REM intuition.h, and DECLARED MyWindow to be a pointer to a window structure,
REM we can now link a specific address to that pointer by using it as the
REM return value for our open window call; NOTE that the address passed to
REM the OpenWindow call is the STARTING address of where we started POKING
REM the NewWindow data into our allocated memory (this is true for any
REM structure):
MyWindow=OpenWindow&(MyMem&+60)
IF MyWindow=0 THEN 'MyWindow will remain 0 if window couldn't be opened
PRINT "Open Failed"
ELSE 'otherwise, a new window will pop open on the screen before our eyes!
PRINT "Window Pointer is ";MyWindow
END IF
REM Now PRINT Some Text to demonstrate what we can do.
Tx1$="Hello World!" 'The text to print.
REM since we have explicitly used a structure, we can access it's elements
REM directly as follows; in this case, we want the address of the RastPort.
rp&=MyWindow->RPort 'beats rp&=PEEKL(MyWindow+50&), doesn't it?
CALL Move(rp&,100&,60&) 'Move the Cursor within the window to position 100
REM pixels to the left of the current position, and 60 pixels down.
ER1=Text&(rp&,SADD(Tx1$),LEN(Tx1$)) 'Put our text in the window
RETURN 'finished with window and text stuff
WaitSig: 'Here's we we sleep until the User clicks on the close gadget
REM the next two lines can be translated as "wait until a special signal
REM (mp_SigBit) arrives in the msgport (UserPort) of the window (MyWindow)"
MyUP = MyWindow->UserPort 'need to access the address of our MsgPort for the
REM window; note how again, we make use of an explicit structure.
REM NOTE: In general, one would have to check not only the bit, but also the
REM specific msg that arrived in the MsgPort, since ANY message will awaken
REM our task. In this case, we have defined only one event (via the IDCMP
REM flag in the NewWindow Structure above) which gets reported to our task,
REM so we can be sure if we get a message, it's a closewindow click!
Call xWait&(SHL(1,MyUP->mp_SigBit)) 'this actually puts our task to sleep
PRINT "Sig Value = ";MyUP->mp_SigBit
RETURN 'got the closewindow click; let's go back.
CleanUp: 'Come Here on Error or after click on window gadget
REM General Rules: Close any resources opened (libraries, fonts, devices);
REM Close in reverse order of opening.
REM Note that these MUST be done in the order listed.
IF MyWindow<>0 THEN CALL CloseWindow(MyWindow) 'Close the window, if opened
IF MyScreen&<>0 THEN CALL CloseScreen(MyScreen&) 'Close the screen, if opened
IF MyMem&<>0 THEN
IF TF&<>0 THEN CALL CloseFont(TF&) 'Close the font we opened
CALL FreeMem(MyMem&,120&) 'Give our memory back to the system
END IF
LIBRARY CLOSE 'Close all the libraries
After&=FRE(-1)
PRINT "Memory After Cleaning Up is ";After&
PRINT "Memory Has Been Reduced by ";After& - Before& 'just a check; should be
REM 0.
REM NOTE: May be non-zero if system opened fonts, or other tasks have
REM allocated memory while program is running.
RETURN 'finished here!