

|
Volume Number: | 1 | |
Issue Number: | 4 | |
Column Tag: | ASSEMBLY |
The “Boxes” Program
By David E. Smith
Last month we covered menu bars and event loops, but we left out complete desk accesory support. Figure 1 above shows that we’ve completed desk accessory support in this month’s “Boxes” program. Full cut and paste is supported in the note pad, and we have a dialog box to tell about our program. This represents a complete Macintosh application shell program for any game type application that does not need text editing within the application window, but wants a standard user interface. Because of the length of the program, we will have to keep our comments brief and try to expand on them in coming issues.
Notice that the number of trap calls needed to fully support the standard applcation interface has increased dramatically since last month. Even a simple program, if it uses all the Mac features, will touch nearly every ROM manager. This month’s program adds 27 ROM calls to the listing we presented last month.
TEXT EDIT SUPPORT
The key to full desk accessory support is text editing using cut and paste. Once this is successfully implemented, the rest is easy. The TextEdit manager handles all text display and management including the actual cutting and pasting. We don’t have to do hardly anything except provide a text record for him. This is done with _TENew trap. We clear room for the returning handle to the text record, push two rectangles and call the trap to set-up a text edit record on the heap. The rectangles control the text destination on the screen and the clipping of that text to a display rectange. See the “Set Up Text Edit” section of our program to see how this is done.
As Bob Denny mentioned in his “C” column, the text edit manager uses our EDIT menu, so we have to set-up our EDIT menu items in the standard order. Then, the actual text editing in a desk accessory is done for us by the trap _SysEdit. We check this trap first if we find the mouse in the edit menu to allow cutting and pasting by a desk accessory. The only support we need is for each of our EDIT menu item routines to call the corresponding Text Edit manager call that does the cutting, pasting or clearing on our text. We push the handle to our text record obtained from _TENew, and let the ROM routines do it!
MODELESS DIALOG BOXES
Most applications have a “Modal” dialog box that serves as the “About” function to tell the user about the program. This is the first item in the Apple menu. We’ve implemented a “Modeless” dialog box here. What that means is the user is free to make use of other desk accessories or the application itself while the “About” box is being displayed. This opens up the possiblity of the user again selecting the “About” box, which would cause TWO dialog boxes to be displayed! Figure 2 shows how our program allows any number of dialog boxes to be created by the user. This is interesting because it lets us slide into multiple window support without really doing multiple windows. Each dialog box is a small window set-up on the heap. The Dialog manager takes care of most of the upkeep for this mini-window. Notice our dialog box also has two icons in it as well as some static text. The resource file shows how the icons and static text are set-up in assembler format so they will be display properly in the “About” box.
Dialog Box Event Support
We have expanded our event loop from last month to include support for the dialog box. Supposedly the dialog traps check for a dialog box event (_IsDialogevent), and process such an event for us (_Dialogselect), allowing us to be unconcerned about events affecting the “About” window such as dragging or closing. In actuallity, the dialog routine for executing dialog events, _Dialogselect is quite limited and checks must be made in the application event loop to see if some action is required for a dialog box. Notice in our event loop that we check for a dialog event right after calling _GetNextEvent and before branching to our standard event routines. Dragging the dialog window or clicking the go away box in the dialog window are not indicated by the _Dialogselect routine. Apparently only a click on a control within the dialog box is returned as a “true” result.
OUR EVENT LOOP
This month our event loop is expanded to handle activate and deactivate events. We’ve added an OPEN and CLOSE feature to our application FILE menu to allow the user to selectively open and close the main window for our program. When the window is open and active, we disable the edit menu items since our application does not support these. We must then enable them again if our window is deactivated so any desk accessories can use them. This is done in the activate and deactivate event routines. The message and modify sections of our event record tell us if the activate was for our window, and whether we should activate or deactivate.
UPDATE EVENT
The hardest part about our program was getting the update event to work properly. If our window has been dragged, we will get an update event to re-draw it. I was having trouble because when I called QDSTUFF to re-draw the window, everything was going into the dialog box! This was solved by re-setting the current graf port to our window so that an update calling to QDSTUFF would be sure to draw in our window and not the dialog box, if it was still hanging around. An update event for a dialog window is handled by the dialog manager. However a drag event could be a dialog window. Since our program allows multiple dialog windows, if any of them are dragged, we re-store the window location so any new dialog windows don‘t run off the screen. Until a window is dragged, multiple dialog windows appear down and right of the previous one as shown in figure 2. The “About” routine takes care of this when we create a new dialog box by incrementing the window location box.
GO AWAY BOX
Another tricky part to dialog boxes was when the “go away” box was clicked. It seems that _CloseDialog will hang the system if used for modeless dialog boxes where more than one such box is allocated. So _CloseWindow should be used instead so that the support structure for the remaining dialog windows is not deleted. In our “HIDE” routine, if the “go away” box is clicked, we check if it’s a dialog window or our application window. If it’s the dialog window, we update the window location by backing it up so that the next dialog window will continue to appear down and to the right of the previous one. However, if we close all of them back to the origonal starting location for our chain of dialog windows, we re-set everything so the dialog windows do not appear to be going backwards! Many of these little concerns will also affect using multiple windows and so are important to take care of here where things are still easy.
DESK ACCESSORY SUPPORT
Once the text edit record is set up and the EDIT menu items in place, little is needed to support desk accessories. We find the desk accessory with _GetItem, and then push the accessory’s name and call _OpenDeskAcc to do it. We also check _SysEdit in our EDIT menu item routine as mentioned to allow any open desk accessory to do text editing.
The “About” function reads the dialog itme list from the resource file and opens a dialog window on the heap in much the same manner as _NewWindow opens a window on the heap. The “DITL” resource type holds the item list of those controls, text, icons or whatever that will appear in the dialog box. In our case, we have only static text and two icons in our “DITL” resource. The first icon is a system icon that displays a note. The second is one of ours that displays the logo for this program. Note that for this to work, the “ICON” resource must be used, not the icon list resource, as I found out the hard way. See the resource file for the assembly format of the “DITL” items.
THE APPLICATION PROGRAM
Our application itself is very simple. It is simply a static window display of a bunch of boxes created with the QDSTUFF subroutine, called whenever an update event for our window occours. To make it a little more interesting, the last box drawn is also filled with a pattern. Patterns are simply 8 bytes of hex information repeated in the rectangle.A count variable keeps track of the number of boxes drawn and a loop calls _FrameRect until all the boxes are displayed. Don’t forget to re-set the count for the next update event! Figure 3 shows the application program output and our OPEN/CLOSE flip-flop menu items. These serve to hide or display our application window in a fashon similar to the go away box. Don’t forget, if the window goes away, you have to have some method of opening it again! Hence the OPEN and CLOSE file menu items.
Finally, in figure 4, is our linker file, pretty much the same format as last month. Remember that the signiture byte, “GLAD” appears both in the resource file’s bundle and identification resources as well as in the linker file. Next month we use this same shell program, but we concentrate on the application, getting some dynamic animation in our application window. Stay tuned!
; EXAMPLE ASSEMBLY PROGRAM ; Boxes ; VERSION 23 JAN 85 ; (C) MacTutor March 1985 ; by David E. Smith ; Macro subset for Toolbox stuff MACRO _InitGraf = DC.W $A86E| MACRO _InitWind =DC.W $A912| MACRO _NewWindow = DC.W $A913| MACRO _setport = DC.W $A873| MACRO _InitFont =DC.W $A8FE| MACRO _InitMenu =DC.W $A930| MACRO _InitDialog =DC.W $A97B| MACRO _TEInit =DC.W $A9CC| MACRO _Initpack = DC.W $A9E5| MACRO _FlushEvents = DC.W $A032| MACRO _InitCursor =DC.W $A850| MACRO _GetNextEvent = DC.W $A970| MACRO _FrameRect = DC.W $A8A1| MACRO _TextFont = DC.W $A887| MACRO _TextFace = DC.W $A888| MACRO _TextSize = DC.W $A88A| MACRO _MoveTo = DC.W $A893| MACRO _DrawString = DC.W $A884| MACRO _PenSize = DC.W $A89B| MACRO _EraseRect = DC.W $A8A3| MACRO _GetRMenu =DC.W $A9BF| MACRO _InsertMenu =DC.W $A935| MACRO _DrawMenuBar = DC.W $A937| MACRO _Debugger = DC.W $A9FF| MACRO _NewMenu = DC.W $A931| MACRO _AppendMenu =DC.W $A933| MACRO _AddResMenu =DC.W $A94D| MACRO _FindWindow =DC.W $A92C| MACRO _DragWindow =DC.W $A925| MACRO _SystemTask =DC.W $A9B4| MACRO _MenuSelect =DC.W $A93D| MACRO _HiLiteMenu =DC.W $A938| MACRO _EnableItem =DC.W $A939| MACRO _DisableItem = DC.W $A93A| MACRO _BeginUpdate = DC.W $A922| MACRO _EndUpdate = DC.W $A923| MACRO _SystemClick = DC.W $A9B3| MACRO _FrontWindow = DC.W $A924| MACRO _SelectWindow = DC.W $A91F| MACRO _GetItem = DC.W $A946| MACRO _OpenDeskAcc = DC.W $A9B6| MACRO _TrackGoAway = DC.W $A91E| MACRO _HideWindow = DC.W $A916| MACRO _PenNormal = DC.W $A89E| MACRO _ShowWindow = DC.W $A915| MACRO _TENew = DC.W $A9D2| MACRO _TECut = DC.W $A9D6| MACRO _TECopy = DC.W $A9D5| MACRO _TEPaste = DC.W $A9DB| MACRO _TEDelete =DC.W $A9D7| MACRO _TEActivate =DC.W $A9D8| MACRO _TEDeactivate =DC.W $A9D9| MACRO _SysEdit = DC.W $A9C2| MACRO _NewDialog = DC.W $A97D| MACRO _GetResource = DC.W $A9A0| MACRO _IsDialogevent = DC.W $A97F| MACRO _Dialogselect = DC.W $A980| MACRO _CloseWindow = DC.W $A92D| MACRO _FillRect =DC.W $A8A5| ; DECLARE LABELS EXTERNAL XDEF START ; required for linker ; LOCAL EQUATES MouseDown equ 1 MaxEvents equ 12 AllEvents equ $0000FFFF TEXTRHANDLE equ A2 ; MAIN PROGRAM SEGMENT DC.W ‘DAVE’ ;find start of program ; -- SAVE THE WORLD ------------ START: MOVEM.L D0-D7/A0-A6, -(SP) LEA SAVEREGS,A0 MOVE.LA6,(A0) ; local var MOVE.LA7,4(A0) ; stack ptr ; --INITIALIZE ALL MANAGERS------ ; SET UP QUICKDRAW GLOBALS PEA -4(A5);push qd global ptr _InitGraf ;init quickdraw global ;-- SET UP REMAINING MANAGERS -- _InitFont ; init font manager _InitWind ; init window manager _InitMenu ; init menu manager CLR.L -(SP) ; kill the restart _InitDialog ; init dialog manager _TEInit ; init text edit (ROM) MOVE.W #2,-(SP) ; set-up _Initpack ; init package mgr MOVE.L #AllEvents,D0 ;all events _FlushEvents ;flushed _InitCursor ; make cursor the arrow ;SET UP MENU BAR WITH POP-UP MENUS CLR.L -(SP) ;returned menu handle MOVE.W #1,-(SP) ;push menu ID 1 Apple _GetRMenu ;get menu from resource LEA APPLEMENU,A0 ;copy apple menu handle MOVE.L (SP),(A0) ;to local data block MOVE.L (SP), -(SP) ;push handle for desk AC ;menu handle still on stack CLR.W -(SP) ;push 0 for append _InsertMenu ;add menu item for About... MOVE.L #’DRVR’, -(SP) ;load DRVR type res _AddResMenu ;add desk acc ;from system file. CLR.L -(SP) ;return menu handle MOVE.W #2,-(SP) ;push menu ID 2 File _GetRMenu ;get menu from resource LEA FILEMENU,A0 ; copy FILE menu handle MOVE.L (SP),(A0) ; to local data block ;leave handle on stack CLR.W -(SP) ;append to menu _InsertMenu ;the File stuff CLR.L -(SP) ;return menu handle MOVE.W #3,-(SP) ;push menu ID 3 Edit _GetRMenu ;get menu from resource ;leave handle on stack LEA EDITMENU,A0 ; copy EDIT menu handle MOVE.L (SP),(A0) ; to local data block CLR.W -(SP) ;append to menu _InsertMenu ;the File stuff _DrawMenuBar;our menu bar! ;-- SET UP NEW HEAP WINDOW ---- CLR.L -(SP) ;return window ptr CLR.L -(SP) ;window record ptr(HEAP) PEA WBOUNDS ;window rectangle size PEA WINDTITLE ; window title MOVE.W #$100,-(SP) ; true = visible MOVE.W #0,-(SP) ; doc type window MOVE.L #-1,-(SP) ; window in front MOVE.W #$100,-(SP) ; true=closebox MOVE.L #0, -(SP) ; reference value _NewWindow ; make new window ; -- ACTIVATE THIS NEW WINDOW ---- LEA WPOINTER,A0 ; copy our window ptr MOVE.L (SP),(A0) ; to stacksave ; ptr still on stack. _setport ; set to current window ; -- SET UP TEXT EDIT ABILITY ---- CLR.L -(SP) ;text handle returned PEADestRect ;destination for text PEAViewRect ;viewing of text _TENew ;new text record on heap MOVE.L (SP)+,TEXTRHANDLE ;pop handle ; ---- INITALIZE VARIABLES -------- JSRINITVAR ;INITIALIZE DS STORAGE ; -------- EVENT LOOP ------------ GetEvent: _SystemTask ;check out desk acc CLR-(SP);returned event MOVE #AllEvents,-(SP) ;mask all events PEAEventRecord ; event record block _GetNextEvent ;go check the mouse MOVE (SP)+,D0 ;get event result CMP#0,D0;if 0 then no event BEQGetEvent ;loop until it happens ; check for dialog event CLR-(SP);result PEAEventRecord ;push event _IsDialogevent ;was it a dialog event? MOVE (SP)+,D0 ;get result CMP#0,D0;is it false? BEQProcessevent ;yes, not dialog ;no, was dialog event CLR-(SP);result PEAEventRecord ;event PEAABOUTHANDLE ;dialog handle PEAITEMHIT;item hit _Dialogselect MOVE (SP)+,D0 ;get result CMP#0,D0;is it false? BEQGetEvent ;yes ; note: always false since no ; controls enabled. closebox is ; returned false. _Debugger ;do we ever get here? JMP GetEvent Processevent: ; JUMP TABLE OF EVENT PROCESSING CLR.L D0 MOVE What,D0 ;what to do! (event #) CMP#MaxEvents,D0 ;event no. >11? BGEGetEvent ;yes so ignore it ADDD0,D0;multiply by 2 MOVE EventTable(D0),D0 JMPEventTable(D0);execute event EventTable: DC.W GetEvent-EventTable ;null event #0 DC.W ButtonDown-EventTable ;mouse down#1 DC.W GetEvent-EventTable ;mouse up #2 DC.W GetEvent-EventTable ;key down #3 DC.W GetEvent-EventTable ;key up #4 DC.W GetEvent-EventTable ;auto key #5 DC.W Update-EventTable ;update event #6 DC.W GetEvent-EventTable ;Disk Event #7 DC.W Activate-EventTable ;activate #8 DC.W GetEvent-EventTable ;Abort #9 DC.W GetEvent-EventTable ;Network #10 DC.W GetEvent-EventTable ;I/O Driver #11 DC.W GetEvent-EventTable ;Appl. event 1 DC.W GetEvent-EventTable ;Appl. event 2 DC.W GetEvent-EventTable ;Appl. event 3 DC.W GetEvent-EventTable ;Appl. event 4 ; note that linker error may result if ; the table entry is >128 ; -- EVENT PROCESSING ROUTINES -- Activate: ; window needs attention MOVE.L WPOINTER,A0;copy window ptr. CMP.L Message,A0 ;Event our window? BNEGetEvent ;no MOVE.W Modify,D0;yes, check flags BTST #0,D0 ;check activate bit BEQDeactivate ;unactivate window ; activate our window MOVE.L TEXTRHANDLE,-(SP) _TEActivate ;activate text edit MOVE.L EDITMENU,-(SP) ;push menu handle MOVE.W #1,-(SP) ;push menu item 1 _DisableItem;disable undo MOVE.L EDITMENU,-(SP) ;push menu handle MOVE.W #3,-(SP) ;push menu item _DisableItem;disable cut MOVE.L EDITMENU,-(SP) ;push menu handle MOVE.W #4,-(SP) ;push menu item _DisableItem;disable copy MOVE.L EDITMENU,-(SP) ;push menu handle MOVE.W #5,-(SP) ;push menu item _DisableItem;disable paste MOVE.L EDITMENU,-(SP) ;push menu handle MOVE.W #6,-(SP) ;push menu item _DisableItem;disable clear MOVE.L WPOINTER,-(SP) ;push window ptr _SetPort;make our port active JMPGetEvent Deactivate: MOVE.L TEXTRHANDLE,-(SP) _TEDeactivate ;turn off text edit ;let desk acc. use it MOVE.L EDITMENU,-(SP) MOVE.W #1,-(SP) _EnableItem ;enable undo MOVE.L EDITMENU,-(SP) ;push menu handle MOVE.W #3,-(SP) ;push menu item _EnableItem ;able cut MOVE.L EDITMENU,-(SP) ;push menu handle MOVE.W #4,-(SP) ;push menu item _EnableItem ;enable copy MOVE.L EDITMENU,-(SP) ;push menu handle MOVE.W #5,-(SP) ;push menu item _EnableItem ;enable paste MOVE.L EDITMENU,-(SP) ;push menu handle MOVE.W #6,-(SP) ;push menu item _EnableItem ;enable clear JMPGetEvent Update: ; window needs refreshing MOVE.L WPOINTER,-(SP) ;push window ptr _BeginUpdate MOVE.L WPOINTER,-(SP) ; our window ptr. _SetPort ;restore our port ;least an update draw in ;the wrong window. BSRQDSTUFF;re-draw everything MOVE.L WPOINTER,-(SP) _EndUpdate JMP GetEvent ButtonDown: CLR-(SP) ;result of findwindow MOVE.L Point, -(SP) ;push mouse coord. PEAWWindow ;push holder window handle _FindWindow ;where was mouse click? CLR.L D0 MOVE (SP)+,D0 ;pop region number ADDD0,D0;multiply by 2 MOVE WindowTable(D0),D0 JMPWindowTable(D0) ;do mouse down event WindowTable: ;table of button down events DC.W GetEvent-WindowTable ;in desktop DC.W Menubar-WindowTable ;in menu bar DC.W System-WindowTable ;in system window DC.W Content-WindowTable ;in content region DC.W Drag-WindowTable ;in drag region DC.W GetEvent-WindowTable ;in grow region (ignored) DC.W Hide-WindowTable ;in go-away region System: ; Button pressed in a system window ; _SystemClick calls the desk acc. PEAEventRecord ;push event record MOVE.L WWindow,-(SP) ;push find window _SystemClick;let system do desk JMPGetEvent Content: MOVE.L WWindow,-(SP) ;activate window _SelectWindow ;make it front JMPGetEvent Drag: ;mouse button in drag ;could be dialog window MOVE.L WWindow,-(SP);push find window pt MOVE.L Point, -(SP) ;push mouse coord PEADRAGWINDOW ;window boundries _DragWindow ;move window MOVE.L WWindow,A0 ;find window ptr. CMP.L ABOUTHANDLE,A0 ;is it about window? BNE ENDDRAG;no, exit JSRINITVAR;yes, reset about ;window location ENDDRAG: JMPGetEvent ;return to event loop Hide: ;close box ;could be dialog window CLR.W -(SP) ;boolean result MOVE.L WWindow,-(SP) ;push find window MOVE.L Point, -(SP) ;push mouse loc _TrackGoAway MOVE.W (SP)+,D0 ;get result BEQGetEvent ;false result MOVE.L WWindow,A0 ;find window ptr. CMP.L WPOINTER,A0;is it our window? BEQHideours ;yes, hide ours MOVE.L WWindow, -(SP) ;must be about _CloseWindow;close it ;note: Don’t use closedialog for modeless ;dialog windows if more than one present. ; update about window location LEADBOUNDS,A0 ;set-up our globals LEASavetop,A1 MOVE.W 0(A0),D0 ;TOP VALUE MOVE.W 0(A1),D1 ;origonal value CMP.W D1,D0 ;past init value? BLEGetEvent ;skip update ADDI #-20,D0 ;decrement top MOVE.W D0,(A0) MOVE.W 2(A0),D0 ;LEFT VALUE ADDI #-20,D0 MOVE.W D0,2(A0) MOVE.W 4(A0),D0 ;BOTTOM VALUE ADDI #-20,D0 MOVE.W D0,4(A0) MOVE.W 6(A0),D0 ;RIGHT VALUE ADDI #-20,D0 MOVE.W D0,6(A0) JMPGetEvent Hideours: MOVE.L WPOINTER, -(SP) ;our window ptr _HideWindow ;hide window MOVE.L FILEMENU,-(SP) ;menu handle MOVE.W #1,-(SP) ;open item _EnableItem ;enable open for file menu MOVE.L FILEMENU,-(SP);push menu handle MOVE.W #2,-(SP) ;close _DisableItem;disable it JMP GetEvent Menubar: CLR.L -(SP) ;returned menu choice MOVE.L Point,-(SP);mouse position _MenuSelect ;Find menu selected MOVE (SP)+,D5 ;pop menu ID to D5 MOVE (SP)+,D6 ;pop menu item ID CLR-(SP);select all menus _HiLiteMenu ;unhilite them all CMP#1, D5 ;apple menu? BEQInapplemenu CMP#2, D5 ;file menu? BEQInfilemenu CMP#3,D5;edit menu? BEQIneditmenu BRAGetEvent ;no place else Inapplemenu: CMP#1, D6 ;is it about...? BEQAbout ; must be a desk accessory MOVE.L APPLEMENU, -(SP) ;push apple menu MOVE.W D6,-(SP) ;push item number PEADeskName ;push holder for desk name _GetItem;find desk acc. name CLR-(SP);result PEADeskName ;push desk acc. name _OpenDeskAcc;do it MOVE (SP)+,D0 ;pop result MOVE.L WPOINTER,-(SP) ;push window ptr. _SetPort ;restore our port JMP GetEvent About: CLR.L -(SP) ;return handle MOVE.L #’DITL’,-(SP);item list MOVE.W #256,-(SP) ;ID _GetResource ;load item list resource LEA DIALOGITEMS,A0 ;handle storage MOVE.L (SP)+,(A0) ;save handle ; update window location LEADBOUNDS,A0 ;set-up our globals MOVE.W 0(A0),D0 ;TOP VALUE ADDI #20,D0 MOVE.W D0,(A0) MOVE.W 2(A0),D0 ;LEFT VALUE ADDI #20,D0 MOVE.W D0,2(A0) MOVE.W 4(A0),D0 ;BOTTOM VALUE ADDI #20,D0 MOVE.W D0,4(A0) MOVE.W 6(A0),D0 ;RIGHT VALUE ADDI #20,D0 MOVE.W D0,6(A0) ;SET UP MODELESS DIALOG ON HEAP CLR.L -(SP) ;return window ptr CLR.L -(SP) ;window record ptr. (HEAP) PEA DBOUNDS ;window rectangle size PEA DWINDTITLE ; window title MOVE.W #$100,-(SP) ; true = visible MOVE.W #16,-(SP) ; round doc type window MOVE.L #-1,-(SP) ; window in front MOVE.W #$100,-(SP) ; true=closebox MOVE.L #0, -(SP) ; reference value MOVE.L DIALOGITEMS,-(SP) ;items list handle _NewDialog ; make new window LEAABOUTHANDLE,A0 ;dialog window handle MOVE.L (SP),(A0); save handle _SetPort ;make dialog active MOVE.L TEXTRHANDLE,-(SP) ;deactivate text _TEDeactivate JMP GetEvent Infilemenu: CMP#1, D6 ;Open? BEQOpen CMP#2, D6 ;Close? BEQClose CMP#3,D6;quit? BNEGetEvent ;no, try again BRAExit ;yes, exit Open: ; window is hiding...open it again MOVE.L WPOINTER, -(SP) ;our window ptr _ShowWindow MOVE.L FILEMENU,-(SP) ;menu handle MOVE.W #2,-(SP) ;open item _EnableItem ;enable open for file menu MOVE.L FILEMENU,-(SP) ;push handle MOVE.W #1,-(SP) ;open _DisableItem;disable it JMP GetEvent Close: ; perform go away function MOVE.L WPOINTER, -(SP) ;our window ptr _HideWindow ;hide window MOVE.L FILEMENU,-(SP) ;menu handle MOVE.W #1,-(SP) ;open item _EnableItem ;enable open MOVE.L FILEMENU,-(SP) ;push handle MOVE.W #2,-(SP) ;close _DisableItem;disable it JMP GetEvent Ineditmenu: ; check if system edit in desk acc. CLR -(SP) ;result MOVE.W D6,-(SP) ;push menu item SUBQ #1, (SP) ;system edit offset _SysEdit ;do editing MOVE.B (SP)+,D0 ;pop result BNEGetEvent ;system edit did it ;desk acc. not active CLR.L -(SP) _FrontWindow;whoose up? MOVE.L (SP)+,A0 CMP.L ABOUTHANDLE,A0 ;is this an about ? BEQGetEvent ;yes, ignore it CMP#3,D6;our cut? BEQCUT CMP#4,D6;our copy? BEQCOPY CMP#5,D6;our paste? BEQPASTE CMP#6,D6;our clear? BEQCLEAR JMPGetEvent ;nothing left ; - text editing only for desk acc. - CUT: MOVE.L TEXTRHANDLE,-(SP) ;text handle _TECut JMP GetEvent COPY: MOVE.L TEXTRHANDLE,-(SP) ;text handle _TECopy JMPGetEvent PASTE: MOVE.L TEXTRHANDLE,-(SP) ;text handle _TEPaste JMPGetEvent CLEAR: MOVE.L TEXTRHANDLE,-(SP) ;text handle _TEDelete JMPGetEvent Exit: JMPTofinder ;return to finder ; ---------- END OF MAIN ------------ ; -------- INITVAR SUBROUTINE ------ INITVAR: LEADBOUNDS(A5),A0;set-up dialog windo ;box frame size. MOVE.W #70, (A0) ;TOP MOVE.W #70, 2(A0) ;LEFT MOVE.W #220, 4(A0) ;BOTTOM MOVE.W #370, 6(A0) ;RIGHT LEA Savetop(A5),A1 MOVE.W (A0), (A1);GET TOP LEACOUNT(A5),A1 MOVE.W #24,(A1) RTS ; ---- QDSTUFF SUBROUTINE ---------- QDSTUFF: ; This subroutine is a static ; window display of boxes _PenNormal LEAtop(A5),A0 ;set-up appl. window ;box frame size. MOVE.W #10, (A0) ;TOP MOVE.W #30, 2(A0) ;LEFT MOVE.W #260, 4(A0) ;BOTTOM MOVE.W #450, 6(A0) ;RIGHT PEA top(A5) ;frame rectangle _FrameRect;draw rectangle BOXLOOP: LEAtop(A5),A0 ; do a bunch boxes LEACOUNT(A5),A4 ADDQ #5,(A0) ADDQ #5,2(A0) SUBQ #5,4(A0) SUBQ #5,6(A0) PEAtop(A5) _FrameRect SUBQ #1,(A4) BNEBOXLOOP;loop til all drawn PEAtop(A5) PEAboxpattern _FillRect ;fill last box LEACOUNT(A5),A1 MOVE.W #24,(A1) ;reset count! RTS ; -- RESTORE THE WORLD -------- Tofinder: LEA SAVEREGS,A0 ; get ‘em back MOVE.L (A0),A6 ; local var MOVE.L 4(A0),A7;restore stack MOVEM.L (SP)+,D0-D7/A0-A6 ; ---- RETURN TO FINDER -------- RTS ; return to finder ; ----LOCAL DATA AREA ---------- APPLEMENU: DC.L 0 ;apple menu handle FILEMENU: DC.L 0 ;file menu handle EDITMENU: DC.L 0 ;edit menu handle DeskName: DCB.W 16,0 ;Desk accesorys name SAVEREGS: DCB.L 2,0 ;set save area boxpattern: DC.W $1234,$ABCD,$DCBA,$4321 ; ------ our window definitions ------ WPOINTER: DC.L 0 ;store window pt WBOUNDS:DC.W 40 ;TOP -windo rect DC.W 2;LEFT DC.W 335;BOTTOM DC.W 508;RIGHT ViewRect: DC.W 50 ;text edit view rect DC.W 4 DC.W 245 DC.W 405 DestRect: DC.W 50 ;text edit dest rect DC.W 4 DC.W 245 DC.W 405 WINDTITLE: DC.B 5 ; title length DC.B ‘Boxes’,0 DRAGWINDOW: DC.W 30 ;rectangle DC.W 1 ;for dragging DC.W 350 DC.W 510 ; ---- our dialog window definitions -- ABOUTHANDLE:DC.L 0 ;handle holder DWINDTITLE: DC.B 30 ; title length DC.B ‘All about the Boxes program...’,0 ITEMHIT: DC.W 0 ;ITEM HIT HOLDER DIALOGITEMS:DC.L 0 ;handle holder for ; resource DITL ; ------------------------------------ EventRecord: What: DC.W 0;what event number Message: DC.L 0;ptr. to msg When: DC.L 0;Time event was posted Point: DC.L 0;mouse coordinates Modify: DC.W 0;state of keys & button WWindow:DC.L 0 ;Find windos result ; ---- APPLICATION GLOBALS ------ top: DS.W1 ;frame size storage left: DS.W 1 ;for QDSTUFF rect bottom: DS.W1 right: DS.W1 DBOUNDS:DS.W 1 ;TOP-windo size rect DS.W 1;LEFT DS.W 1;BOTTOM DS.W 1;RIGHT Savetop:DS.W 1 ;save top value COUNT: DS.W 1 ;BOX COUNT ; -- END OF PROGRAM -------- ; Boxes_rscs.asm ; resource file for the Boxes ; (C) MacTutor March 1985 ; created using the assembler ; signiture is creator tag ; RESOURCE ‘GLAD’ 0 ‘IDENTIFICATION’ DC.B 22, ‘BOXES -- JAN. 23 1984 ‘ .ALIGN 2 RESOURCE ‘BNDL’ 128 ‘BUNDLE’ DC.L ‘GLAD’ ;NAME OF SIGNATURE DC.W 0,1 ;DATA (DOESN’T CHANGE) DC.L ‘ICN#’ ;ICON MAPPINGS DC.W 0 ;NUMBER OF MAPPINGS-1 DC.W 0,128 ;MAP 0 TO ICON 128 DC.L ‘FREF’ ;FREF MAPPINGS DC.W 0 ;NUMBER OF MAPPINGS-1 DC.W 0,128 ;MAP 0 TO FREF 128 RESOURCE ‘FREF’ 128 ‘FREF 1’ DC.B ‘APPL’, 0, 0, 0 .ALIGN 2 RESOURCE ‘ICN#’ 128 ‘MY ICON’ ; FIRST APPLICATION ICON BIT MAP INCLUDE Boxes.icon.asm ; MENU BAR RESOURCES .ALIGN 2 RESOURCE ‘MENU’ 1 ‘apple menu’ DC.W 1 ;MENU ID DC.W 0 ;WIDTH HOLDER DC.W 0 ;HEIGHT HOLDER DC.L 0 ;STD. MENU PROC HOLDER DC.L $1FF ;ENABLE ALL ITEMS DC.B 1 ; TITLE LENGTH DC.B 20; APPLE SYMBOL DC.B 21;MENU ITEM LENGTH DC.B ‘ABOUT THIS PROGRAM...’ DC.B 0 ; NO ICON DC.B 0 ; NO KEYBOARD EQUIVALENT DC.B 0 ; MARKING CHARACTER DC.B 0 ; STYLE OF ITEM’S TEXT DC.B 0 ; END OF MENU ITEMS .ALIGN 2 RESOURCE ‘MENU’ 2 ‘file menu’ DC.W 2 ;MENU ID DC.W 0 ;WIDTH HOLDER DC.W 0 ;HEIGHT HOLDER DC.L 0 ;RESOURCE HOLDER DC.L $D ;ENABLE ALL ITEMS except 1 DC.B 4 ; TITLE LENGTH DC.B ‘File’; file menu DC.B 4 ;MENU ITEM LENGTH DC.B ‘Open’ DC.B 0 ; NO ICON DC.B 0 ; NO KEYBOARD EQUIVALENT DC.B 0 ; NO MARKING CHARACTER DC.B 0 ; STYLE OF ITEM’S TEXT DC.B 5 ;MENU ITEM LENGTH DC.B ‘Close’ DC.B 0 ; NO ICON DC.B 0 ; NO KEYBOARD EQUIVALENT DC.B 0 ; NO MARKING CHARACTER DC.B 0 ; STYLE OF ITEM’S TEXT DC.B 4 ;MENU ITEM LENGTH DC.B ‘Quit’ DC.B 0 ; NO ICON DC.B 0 ; NO KEYBOARD EQUIVALENT DC.B 0 ; NO MARKING CHARACTER DC.B 0 ; STYLE OF ITEM’S TEXT DC.B 0 ; END OF MENU ITEMS .ALIGN 2 RESOURCE ‘MENU’ 3 ‘edit menu’ DC.W 3 ;MENU ID DC.W 0 ;WIDTH HOLDER DC.W 0 ;HEIGHT HOLDER DC.L 0 ;RESOURCE ID OF PROC DC.L $3B ;ENABLE ALL ITEMS except 2 & 6 DC.B 4 ; TITLE LENGTH DC.B ‘Edit’; edit menu DC.B 4 ;MENU ITEM LENGTH DC.B ‘Undo’ DC.B 0 ; NO ICON DC.B 0 ; NO KEYBOARD EQUIVALENT DC.B 0 ; NO MARKING CHARACTER DC.B 0 ; STYLE OF ITEM’S TEXT DC.B 9 ;MENU ITEM LENGTH DC.B ‘--------’ DC.B 0 ; NO ICON DC.B 0 ; NO KEYBOARD EQUIVALENT DC.B 0 ; NO MARKING CHARACTER DC.B 0 ; STYLE OF ITEM’S TEXT DC.B 3 ;MENU ITEM LENGTH DC.B ‘Cut’ DC.B 0 ; NO ICON DC.B 0 ; NO KEYBOARD EQUIVALENT DC.B 0 ; NO MARKING CHARACTER DC.B 0 ; STYLE OF ITEM’S TEXT DC.B 4 ;MENU ITEM LENGTH DC.B ‘Copy’ DC.B 0 ; NO ICON DC.B 0 ; NO KEYBOARD EQUIVALENT DC.B 0 ; NO MARKING CHARACTER DC.B 0 ; STYLE OF ITEM’S TEXT DC.B 5 ;MENU ITEM LENGTH DC.B ‘Paste’ DC.B 0 ; NO ICON DC.B 0 ; NO KEYBOARD EQUIVALENT DC.B 0 ; NO MARKING CHARACTER DC.B 0 ; STYLE OF ITEM’S TEXT DC.B 5 ;MENU ITEM LENGTH DC.B ‘Clear’ DC.B 0 ; NO ICON DC.B 0 ; NO KEYBOARD EQUIVALENT DC.B 0 ; NO MARKING CHARACTER DC.B 0 ; STYLE OF ITEM’S TEXT DC.B 0 ; END OF MENU ITEMS .ALIGN 2 RESOURCE ‘ICON’ 256 ‘DIALOG ICON’ ; Dialog box icon bit map INCLUDE Boxes.icon.asm ; ---- DIALOG ITEMS LIST ---------- ; ; text in dialog items must be of even ; length. Item types are as follows: ; ; control item = control item + 4 ;button control = 0 ;check control = 1 ;radio button control = 2 ;resource control = 3 ; ;static text = 8 ;edit text = 16 ;icon item = 32 ;quickdraw pict item = 64 ;user item = 0 ; ;disable item = item type + 128 ; ; resource ID’s for system icons ; ;stop icon = 0 ;note icon = 1 ;caution icon = 2 .ALIGN 2 RESOURCE ‘DITL’ 256 ‘Boxes DIALOG’ DC.W 4 ;number of items -1 DC.L 0 ;handle holder item 1 DC.W 10;rectangle-top DC.W 20;left DC.W 25;bottom DC.W 375 ;right DC.B 128+8;TYPE-STATIC TEXT + disable DC.B 26;TEXT LENGTH DC.B ‘This program is a complete’ DC.L 0 ;handle holder item 2 DC.W 30;rectangle-top DC.W 20;left DC.W 45;bottom DC.W 375 ;right DC.B 128+8;TYPE-STATIC TEXT + disable DC.B 30;TEXT LENGTH DC.B ‘application shell in assembly.’ DC.L 0 ;handle holder item 3 DC.W 50;rectangle-top DC.W 200 ;left DC.W 82 ;bottom DC.W 232 ;right DC.B 128+32;TYPE- icon + disable DC.B 2 ;length of next data DC.W 256 ;icon resource ID DC.L 0 ;handle holder item 4 DC.W 50;rectangle-top DC.W 20;left DC.W 90;bottom DC.W 60;right DC.B 128+32;TYPE- icon + disable DC.B 2 ;length of next data DC.W 1 ;icon resource ID DC.L 0 ;handle holder item 5 DC.W 110 ;rectangle-top DC.W 20;left DC.W 125 ;bottom DC.W 375 ;right DC.B 128+8;TYPE-STATIC TEXT + disable DC.B 32;TEXT LENGTH DC.B ‘by David E. Smith 23 JAN 1985 ‘

- SPREAD THE WORD:
- Slashdot
- Digg
- Del.icio.us
- Newsvine