TweetFollow Us on Twitter

Easy to Use Help!
Volume Number:5
Issue Number:1
Column Tag:Assembly Lab

Related Info: List Manager

Help! An Easy to Use Help Function

By John Holder, Blue Lake, CA, MacTutor Contributing Editor

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

What’s this all about?

This article will show you a way of presenting a Help function (hereafter called DoHelp) for any of your programs that is very easy to implement and use. DoHelp must be XREF’ed (XREF DoHelp) at the beginning of the source file that calls it. To use it I just add a ‘Help...’ menu in an appropriate place in your application (I put it right below the standard ‘About Application...’ menu item in the apple menu). Call it by simply doing a BSR DoHelp when the item has been selected by the user.

DoHelp was created with the Macintosh 68000 Development System. First assemble the file ‘DoHelp.Asm’, then run the linker on your applications Linker file to Link DoHelp with the rest of your code, and finally run RMaker on your Rmaker file. You can create the needed ‘help’ resources with ResEdit (or whatever you prefer) and add them to your applications resource file. ‘YourApp.Link’ & ‘YourApp.R’ are shown as examples of how you link your applications code with DoHelp’s code.

The way DoHelp works is to show a list of resource names (a Help topic list created by showing the names of each ‘help’ resource in numeric order) using the List Manager. This makes adding and editing Help topics very easy, by using ResEdit or compiling the needed resources with RMaker. The user can click on any name to access its contents, which is displayed in a scrollable text window (which temporarily replaces the list of Help topics). When the user is done reading this, he can click on the button or within the text itself to return to the Help topics. From here he can choose to look at another topic or select the ‘Done with Help’ button to return to the application.

Why?

I wrote DoHelp to put into my latest shareware application called ‘Form It!’. I wanted to keep it as generic as possible so I could use it for any other applications that I might create in the future. I made it so the calling application wouldn’t need to know anything specific about the help but would just have to call it when the user needs it. It handles everything else.

What’s happening , step by step.

First, all files needed are Included at the beginning and a couple of often used routines for saving and restoring the registers are defined as Macros. A few standard EQUates are also defined along with some values used by the List Manager. The last EQUate is the resource ID# of the DLOG used to display the Help function. Finally the DoHelp routine is XDEF’ed so the Linker will know what the heck is going on when it’s being linked to the code that calls it!

Now a dialog box is created, the default button is hilighted, and we jump to the routine to set up the list of named ‘help’ resources. To accomplish this, we first calculate the useable width of the cells used in the list by checking the size of the User Item’s rectangle (right-left-scrollbarwidth = widthofcells) of the Help dialog box (item #2 in this DLOG). Then we create a new list with _LNew and set its selflags field to allow only one item to be selected at a time.

The routine to add each named ‘help’ resource is then called. We count how many resources of this type there are with _CountResources and set list drawing off so it won’t show each item as it’s being added to the list. Starting from the last resource we cycle through all the resources and add their names to the list with _LAddRow & _LSetCell. After the last resource (the resource id#1 since we’re adding in reverse) has been put in the list, we exit the loop and turn list drawing on and update the list to draw it.

The Dialog filter

After everything is initialized we go into a loop to watch for dialog events. A Dialog Filter is used to handle the List Manager events, all other dialog events are handled by _ModalDialog. The filter is set up to get values off of the stack (passed by _ModalDialog) and create some local variables by using the LINK instruction to set up a stack frame. When a click occurs in the rectangle of the User Item, _LClick is called to handle scrolling or a selection. If a help topic (list item) is clicked on, the rectangle is erased, we change the buttons (item #1) name to an appropriate message (‘Done Viewing’), the cursor is changed to the watch cursor and we jump to the Do_Help_View routine.

A new Text Edit record is made with _TENew and its text size and font is set. The rectangle around the User Item is framed and a scroll bar is created. The selected cells data is retrieved using _LGetCell to get the name of the resource to read in with _GetNamedResource. If the given resource doesn’t exist (why it wouldn’t I don’t know, but it pays to be safe!) we dispose of the TE record and the scroll bar and return to wait for the next event. Otherwise, we copy the data in the ‘help’ resource into the Text Edit Record and calculate how many lines are in the data. If there are more lines than one screenfull, the scroll bar is set up to match the amount of lines in the data. Next, we jump to the routine to handle text scrolling using another Dialog Filter to handle it.

If the scroll bar is clicked on, we check which part of the scroll has been clicked and handle each part individually. If the Thumb is clicked, it’s tracked by _TrackControl until released and then we scroll the text according to the difference between the controls old and new values. The text is scrolled a line at a time or a pagefull at a time depending on the part clicked on. The routine Scroll_The_Text figures how many pixels to scroll by multiplying the height of a line of text (found in the teLineHite field of the TE record) by how many lines of text are to be scrolled.

When either the button or the content of the text in the dialog is clicked, the TE record and the scroll bar are disposed of, the list is updated to show it again, we change the buttons name back to what it was and we return to watch for more list events. If the user clicks on another list item, the whole process starts again. Otherwise if the user clicks the button or hits Return, the dialog and the list handle are disposed of and control is returned to the calling application.

Credits

The basis of some of the routines used in DoHelp (such as the dialog filters and scroll handling routines) are from Dan Weston’s extremely useful books “The Complete Book of Macintosh Assembly Language Programming” (volumes I and II). These books have proved very helpful to my learning to use the power of the Mac with Assembly language!

The End...

There are many ways that DoHelp could be enhanced. For instance, a search feature or a way to print selected help topics could be added. The source code is well commented, so anything that this article doesn’t explain, the comments should be able clear up. Well, that’s it, I hope you find this useful enough to use in your own applications!

;------------------------------------------------------------
;FileName:  DoHelp.Asm
;(C) 1988 by John Holder
;------------------------------------------------------------
;What it does:
;A generic Help routine:
;Allows user to click in a list of names (these names are 
;actually the names of ‘help’ resources), and show the data
;contained in this resource (ACSII text), in a scrollable
;window.  Nothing about the dialog (other than its id#) is
;known, so the dialog can be modified without changing this
;code.  To make topics for your help routine, just create
;NAMED resources of type ‘help’ (lowercase) in your
;application starting at id#1 and making each id# one more
;than the last one.  To create the appearance of subtopics
;just add a few spaces to the beginning of the names of 
;the appropriate ‘help’ resources.

;To use this in your application, just make sure you:
;XREF   DoHelp
;at the beginning of your source code and you call it by
;doing a:
;BSR    DoHelp
;in the appropriate place in your code
Include Traps.D  ; Traps
Include ToolEqu.D; ToolBox equates
Include SysEqu.D ; System equates
Include FSEqu.D  ; File equates
Include PackMacs.Txt ; PACKage mgr equates
Include QuickEqu.D ; QDraw equates

MACRO SaveRegs =
 MOVEM.LA0-A4/D0-D7,-(SP)
 |
MACRO RestoreRegs=
 MOVEM.L(SP)+,A0-A4/D0-D7
 |
true    equ $0100
false   equ 0
nilequ  0
arraycolumnsequ  1
arrayrows equ  0
celldepth equ  16   ;depth of Cells in List
modify  EQU 14   ;State of keys and button
message equ 2    ;Message returned in EventRecord
DialogIDequ 2000 ;res id# of DLOG resource

XDEF  DoHelp  ;Define function DoHelp for Linker

;------------------------------------------------------------
;<<<< The beginning of the DoHelp routine >>>>
;------------------------------------------------------------
DoHelp
 saveregs
 CLR.L  -(SP)    ;space for ptr
 move.w #DialogID,-(sp)
 CLR.L  -(SP)    ;wstorage
 MOVE.L #-1,-(SP)
 _GetNewDialog
 MOVE.L (SP),DialogPtr(A5)  ;save ptr
 _SetPort
 ;set up stack for my routine
 move.l DialogPtr(A5),-(sp)
 move   #1,-(sp)
 bsr    HilightDialogButton
 ;Set up list of all ‘help’ resources
 bsr    SetUpHelpList
 _InitCursor

Dialog_Loop
 pea    DialogsFilter;use filter to watch 
 pea    ItemNumber(A5)  ;for List mgr events
 _ModalDialog

WhatsTheHaps21
 ;which item was clicked
 cmp.w  #1,ItemNumber(A5)
 beq    Quit_Help;click in ‘Done..’ but
 bra    Dialog_Loop;loop until done

Quit_Help
 ;all done, lets get outta here!
 ;dispose of the List handle
 move.l ListHandle(A5),-(sp)
 _LDispose
 ;kill the dialog
 move.l DialogPtr(A5),-(sp)
 _DisposDialog
 ;return to calling application!
 restoreregs
 rts

;------------------------------------------------------------
;<< Dialog Filter to watch for list selections in User Item >>
;------------------------------------------------------------
DialogsFilter
;this routine expects parameters to be on the stack (handled
;by _ModalDialog)
;PROCEDURE    
;DialogsFilter (thedialog:dialogptr;VAR theEvent:EventRecord
;  VAR itemhit:integer): boolean

 Parambytes SET  12
 tItemHit SET  8 ;a ptr to an int!
 tEvent SET 12 ;event rec
 tDialogSET 16 ;dialog ptr
 result SET 20 ;result returned
 iPoint SET -4 ;mouse point
 itype  SET -6 ;item type
 iHdl   SET -10  ;item hand
 iBox   SET -18  ;item rect
 localbytes SET  -18

 link   A6,#localbytes
 saveregs
 ;get User Item info (rect)
 move.l tDialog(A6),-(sp)
 move   #2,-(sp)
 pea    iType(A6)
 pea    iHdl(A6)
 pea    iBox(A6)
 _GetDItem
 move.l tevent(A6),A0
 move   evtnum(A0),D0
 cmp    #KeyDwnEvt,D0   ;was it a key down?
 beq    CheckForEnterorReturn ;yep!
 move.l tevent(A6),A0
 move   evtnum(A0),D0
 cmp    #mButDwnEvt,D0   ;was it a mouse down?
 bne    LetDialogHandleIt     ;if not, let
                 ;_ModalDialog 
                 ;handle
 ;was it a mouse click in the List Box (User Item)?
 lea    evtMouse(A0),A0
 lea    iPoint(A6),A1
 move.l (A0)+,(A1)+
 pea    iPoint(A6)
 _GlobalToLocal
 clr    -(sp)
 move.l iPoint(A6),-(sp)
 pea    iBox(A6)
 _PtInRect
 move   (sp)+,D0
 beq    LetDialogHandleIt  ;not in user item
 bsr    HandleListEvent    ;handle list event!
 ;we’ve taken care of the event
 move.l tItemHit(A6),A0
 move   #nil,(A0)   ;set itemhit to nil
 move   #true,result(A6)   ;stop _ModalDialog 
 bra    FilterExit    ;from handling!

LetDialogHandleIt
 move   #nil,result(A6)

FilterExit
 ;restore stack to the way it was before
 ;and return
 restoreregs
 unlk   A6
 move.l (sp)+,A0
 adda   #parambytes,SP
 jmp    (A0);rts

;------------------------------------------------------------
; <<<< Check for Return or Enter key press >>>>
;------------------------------------------------------------
CheckForEnterorReturn
;if the Enter or Return key was pushed, set the itemhit to #1
;and set result to false so it will be handled by _ModalDialog

 move.l tevent(A6),A0
 move.l message(A0),D0
 cmp.b  #$0d,D0  ;return key?
 beq    SetResult;yep!
 cmp.b  #$03,D0  ;Enter key?
 beq    SetResult;yep!
 bra    LetDialogHandleIt ;neither key

SetResult
 move.l tItemHit(A6),A0
 move   #1,(A0)             ;set itemhit to 1
 move   #true,result(A6)   ;let _ModalDialog
          ;handle it
 bra    FilterExit

;------------------------------------------------------------
;<<<< Click in List box! >>>>
;------------------------------------------------------------
;handle a click in the list box area
HandleListEvent

 ;_LClick will handle scrolling & selection of list
 ;items
 pea    iPoint(A6)
 _GetMouse
 clr    -(sp)
 move.l iPoint(A6),-(sp)
 move   tEvent+Modify(A6),-(sp)
 move.l listhandle(A5),-(sp)
 _LClick
 move   (sp)+,D0
 clr.l  TheCell(A5)   ;start at cell 0,0
    ;for _LGetSelect
 clr    -(sp)
 move   #true,-(sp)
 pea    TheCell(A5)
 move.l listhandle(A5),-(sp)
 _LGetSelect
 move   (sp)+,D0
 beq    Click_Not_In_Cell  ;no cell selected
 ;unselect the selected cell
 move   #false,-(sp)
 move.l TheCell(A5),-(sp)
 move.l listhandle(A5),-(sp)
 _LSetSelect
 ;de-activate the list
 move   #false,-(sp)
 move.l listhandle(A5),-(sp)
 _LActivate
 bsr    Erase_Rect    ;clear topic list
 bsr    Set_To_DoneViewing ;change button name
 bsr    GetandSetWatch     ;show watch cursor
 bsr    Do_Help_View    ;show text from 
                ;’help’ res
 ;re-activate the list
 move   #true,-(sp)
 move.l listhandle(A5),-(sp)
 _LActivate

Click_Not_In_Cell
 rts

;------------------------------------------------------------
; <<<< Show the user selected help text >>>>
;------------------------------------------------------------
;open the named resource and view its contents
Do_Help_View

 ;Use all of rect except enough room for scroll bar
 ;for text window
 bsr    Get_Rect_Of_Item
 lea    DispRect(A5),A2
 sub    #16,Right(A2)
 ;create new Text edit record
 clr.l  -(sp)
 pea    DispRect(A5)
 pea    DispRect(A5)
 _TENew
 move.l (sp)+,TextHand(A5);store handle
 ;set TE rec. text to 9 point Monaco
 move.l TextHand(A5),A1
 move.l (A1),A1
 move   #9,teSize(A1);Text Size!
 move.l TextHand(A5),A1
 move.l (A1),A1
 move   #Monaco,teFont(A1);Text Font!
 bsr    Frame_The_Rect

 bsr    Get_Rect_Of_Item
 ;figure rectangle for scroll bar!
 lea    DispRect(A5),A2
 move   Right(A2),D2
 sub    #15,D2   ;scroll bar width
 move   D2,Left(A2);left = right - 15
 add    #1,Right(A2) ;right = right + 1
 ;we de because the
 ;text rect is 1
 ;pixel inside the 
 ;User Item’s rect
 pea    DispRect(A5) ;expand top & bottom 
 move   #0,-(sp) ;of rect by 1 pixel
 move   #-1,-(sp)
 _InsetRect
 ;create scroll bar!
 clr.l  -(sp)
 move.l DialogPtr(A5),-(sp)
 pea    DispRect(A5) ;scrolls rect
 move.l #nil,-(sp)
 move   #true,-(sp);visible
 move   #0,-(sp) ;init value
 move   #0,-(sp) ;min value
 move   #0,-(sp) ;max value(start at 0)
 move   #16,-(sp);proc id (16=scroll)
 clr.l  -(sp)    ;refCon
 _NewControl
 move.l (sp)+,ScrollHand(A5) ;save handle
 move   #255,DataLength(A5)  ;max length of 
                ;data allowed
 ;Get the selected cells data
 lea    AString(A5),A0     ;pt to byte after
 add.l  #1,A0             ;length byte
 move.l A0,-(sp)          ;put ptr on stack
 pea    DataLength(A5)       ;data length var
 move.l TheCell(A5),-(sp)
 move.l ListHandle(A5),-(sp)
 _LGetCell
 ;add length of data to String ptr
 lea    ASTring(A5),A0
 move   DataLength(A5),D0
 move.b D0,(A0)
 ;get the res. & load it
 clr.l  -(sp)
 move.l #’help’,-(sp)
 pea    AString(A5)
 _GetNamedResource
 move.l (sp),ResHand(A5)
 _LoadResource
 ;just to make sure the resource exists!
 move.l ResHand(A5),A0
 cmp.l  #nil,A0  ;does res. exist?
 bne    A_Ok;yep,it’s there, go on
 bsr    DumpStuff;no such resource!
 rts    ;return

A_Ok
 move.l ResHand(A5),A0    ;lock handle
 _HLock
 ;size of handle (text data)
 move.l ResHand(A5),A0
 _GetHandleSize
 move.l D0,D2       ;D2 = length of text data
 ;set up Text Edit Record to use ‘help’ data
 move.l ResHand(A5),A0  ;need text ptr
 move.l (A0),-(sp)        ;convert handle
 move.l D2,-(sp)        ;text length
 move.l TextHand(A5),-(sp)
 _TESetText
 move.l ResHand(A5),A0         ;unlock handle
 _HUnLock
 ;see how many lines of text are in the 
 ;’help’ data
 move.l TextHand(A5),A1
 move.l (A1),A1
 move   tenLines(A1),d3    ;D3= lines of text!
 ;see how many lines fit into rect of user 
 ;item of dialog box
 bsr    Calc_Lines_In_One_Windowful
 move   LinesInWind(A5),D1
 sub    D1,D3       ;sub enough for a
 cmp    #nil,D3     ;window full!
 ble    Wont_Pass_Bottom   ;not enough lines 
    ;to adda scroll bar
 ;set the scroll bars max value by the # of lines
 move.l ScrollHand(A5),-(sp)
 move   D3,-(sp)    ;# of lines
 _SetMaxCtl

Wont_Pass_Bottom
 ;update the text
 pea    DispRect(A5)
 move.l TextHand(A5),-(sp)
 _TEUpDate
 _InitCursor
 ;go watch for text events
 bsr    HandleTextEditDialogEvent
 rts    ;done with the text, return

;------------------------------------------------------------
;<<<< Handle events in Dialog box (with text scrolling)! >>>>
;------------------------------------------------------------
HandleTextEditDialogEvent
 saveregs

D_Loop
 pea    CheckTextScroll   ;filter to watch
 pea    ItemNumber(A5)    ;for text scrolling
 _ModalDialog

 ;check which buttons are clicked here
 cmp.w  #1,ItemNumber(A5)
 beq    Done_With_This    ;done viewing text

 ;if ItemNumber(A5) = 2, that means the user
 ;clicked in the content of the text of the dialog
 ;which is handled the same as clicked the 
 ;’Done Viewing’ button
 cmp.w  #2,ItemNumber(A5)
 beq    Done_With_This    ;done viewing text
 bra    D_Loop     ;keep looping

;------------------------------------------------------------
;    <<<< Finished here with text view >>>>
;------------------------------------------------------------
Done_With_This
 bsr    DumpStuff
 restoreregs
 rts

;------------------------------------------------------------
;     <<<< Dump TE rec. & scroll bar >>>>
;------------------------------------------------------------
DumpStuff
 ;dispose of text edit record
 move.l TextHand(A5),-(sp)
 _TEDispose
 ;dispose of Scroll bar
 move.l ScrollHand(A5),-(sp)
 _DisposControl
 bsr    Erase_Rect ;erase the rect
 ;reset text font & size to System values
 move   #12,-(sp);12 point
 _TextSize
 move   #0,-(sp) ;Use System Font
 _TextFont
 ;re-show the list by causing list update
 MOVE.L DialogPtr(A5),A1
 move.l 24(A1),-(sp)
 move.l ListHandle(A5),-(sp)
 _LUpdate
 bsr    Frame_The_Rect  ;re-frame list rect
 bsr    Set_To_DoneWithHelp
 rts

;------------------------------------------------------------
;    <<<< Dialog Filter to watch for text scrolling >>>>
;------------------------------------------------------------
CheckTextScroll
;this routine expects parameters to be on the stack (set up
;by _ModalDialog)
;PROCEDURE    
;CheckTextScroll (thedialog:dialogptr;VAR theEvent:EventRecord
; VAR itemhit:integer): boolean

 Parambytes SET  12
 tItemHit SET  8 ;a ptr to an int!
 tEvent SET 12 ;event rec
 tDialogSET 16 ;dialog ptr
 result SET 20 ;result returned

 iPoint SET -4 ;mouse point
 itype  SET -6 ;item type
 iHdl   SET -10  ;item hand
 iBox   SET -18  ;item rect
 PartCode SET  -20 ;used for scroll
 localbytes SET  -20

 link   A6,#localbytes
 saveregs
 move.l tDialog(A6),-(sp)
 move   #2,-(sp)
 pea    iType(A6)
 pea    iHdl(A6)
 pea    iBox(A6)
 _GetDItem
 ;only rect in user item will be scroll bar that
 ;this dialog filter handles
 lea    iBox(A6),A2
 move   Right(A2),D2
 sub    #16,D2   ;scroll bar width
 move   D2,Left(A2);left = right - 16
 move.l tevent(A6),A0
 move   evtnum(A0),D0
 cmp    #KeyDwnEvt,D0   ;was it a key down?
 beq    CheckForEnterorReturn2;yep!
 move.l tevent(A6),A0
 move   evtnum(A0),D0
 cmp    #mButDwnEvt,D0   ;was it a mouse down?
 bne    LetDialogHandleIt2    ;if not, let
       ;_ModalDialog 
       ;handle
 ;change mouse pt into local coordinates
 lea    evtMouse(A0),A0
 lea    iPoint(A6),A1
 move.l (A0)+,(A1)+
 pea    iPoint(A6)
 _GlobalToLocal
 ;was it a mouse click in the Text Box scroll 
 ;bar (User Item)? 
 clr    -(sp)
 move.l iPoint(A6),-(sp)
 pea    iBox(A6)
 _PtInRect
 move   (sp)+,D0
 beq    LetDialogHandleIt2  ;not in scroll,  
     ;let dialog handle
 bsr    HandleScroll   ;go handle text 
     ;scroll event!
 ;we’ve taken care of the event
 move.l tItemHit(A6),A0
 move   #nil,(A0)  ;set itemhit to nil

 move   #true,result(A6)  ;set result to true,  
 bra    FilterExit2  ;stop _ModalDialog
   ;from handling

LetDialogHandleIt2
 move   #nil,result(A6)   ;set to nil, let 
   ;_ModalDialog handle
   ;it
FilterExit2
 ;get out of the routine here!
 restoreregs
 unlk   A6
 move.l (sp)+,A0
 adda   #parambytes,SP
 jmp    (A0);rts

;------------------------------------------------------------
; <<<< Check for Return or Enter key press >>>>
;------------------------------------------------------------
CheckForEnterorReturn2
;if the Enter or Return key was pushed set the itemhit to #1
;and set result to false so it will be handled!

 move.l tevent(A6),A0
 move.l message(A0),D0
 cmp.b  #$0d,D0  ;return key?
 beq    SetResult2 ;yep!
 cmp.b  #$03,D0  ;Enter key?
 beq    SetResult2 ;yep!
 bra    LetDialogHandleIt2;neither key

SetResult2
 move.l tItemHit(A6),A0
 move   #1,(A0)       ;set itemhit to 1
 move   #true,result(A6)  ;let modaldialog
 bra    FilterExit2     ;handle it

;------------------------------------------------------------
;------------------------------------------------------------
;    <<<< ALL text scrolling routines >>>>
;------------------------------------------------------------
;------------------------------------------------------------

;------------------------------------------------------------
;     <<<< Click in Text Scroll bar >>>>
;------------------------------------------------------------
HandleScroll
 pea    iPoint(A6)
 _GetMouse
 clr    -(sp)
 move.l iPoint(A6),-(sp)
 move.l DialogPtr(A5),-(sp)
 pea    WhichControl(A5)
 _FindControl
 move   (sp)+,PartCode(A6)
 beq    ScrollDone    ;not in any control
 ;was click in the scroll bar?
 ;compare value returned by _FindControl & the
 ;scrolls handle we have stored, if they are
 ;equal then do the scroll routines
 move.l ScrollHand(A5),D0
 move.l WhichControl(A5),D1
 cmp.l  D0,D1
 beq    Click_In_Scroll
 bra    ScrollDone   ;click not in scroll

Click_In_Scroll
 ;which part of scroll?
 cmp    #inUpButton,PartCode(A6)
 beq    DoUpSCroll
 cmp    #inDownButton,PartCode(A6)
 beq    DoDownSCroll
 cmp    #inPageUp,PartCode(A6)
 beq    DoPageUpSCroll
 cmp    #inPageDown,PartCode(A6)
 beq    DoPageDownSCroll
 cmp    #inThumb,PartCode(A6)
 beq    DoThumb
 bra    ScrollDone

;handle different parts of scroll
DoUpSCroll
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 move.l iPoint(A6),-(sp)
 pea    UpActionProc
 _TrackControl
 move   (sp)+,D0
 bra    ScrollDone

DoDownSCroll
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 move.l iPoint(A6),-(sp)
 pea    DownActionProc
 _TrackControl
 move   (sp)+,D0
 bra    ScrollDone

DoPageUpSCroll
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 move.l iPoint(A6),-(sp)
 pea    PageUpActionProc
 _TrackControl
 move   (sp)+,D0
 bra    ScrollDone

DoPageDownSCroll
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 move.l iPoint(A6),-(sp)
 pea    PageDownActionProc
 _TrackControl
 move   (sp)+,D0
 bra    ScrollDone

;handle click in thumb of control
DoThumb
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 _GetCtlValue
 move   (sp)+,D4       ;D4 = old control value
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 move.l iPoint(A6),-(sp)
 clr.l  -(sp)
 _TrackControl
 move   (sp)+,D0
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 _GetCtlValue
 move   (sp)+,D3  ;D3 = new cntl value
 sub    D3,D4     ;D4-D3=new view value
 move   D4,D6
 bsr    Scroll_The_Text  ;scroll text selected spot
 bra    ScrollDone
;return from HandleScroll
ScrollDone
 rts
;------------------------------------------------------------
;      <<<< Handle Up Scroll arrow >>>>
;------------------------------------------------------------
UpActionProc
 ;offsets into A6 stack
 thecontrol set  10
 pcode  set 8
 parambytes set  6

 link   A6,#0
 saveregs
 tst    pcode(A6)
 beq    UpActionDone
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 _GetCtlValue
 move   (sp)+,D1
 beq    UpActionDone ;do nothing if control
 ;value is already 0
 sub    #1,D1  ;sub 1 from scroll val
 move.l WhichControl(A5),-(sp)
 move   D1,-(sp)
 _SetCtlValue    ;set to new value
 move   #1,D6      ;d6 = how many lines
 bsr    Scroll_The_Text ;to scroll!

UpActionDone
 restoreregs
 unlk   A6
 move.l (sp)+,A1
 adda.w #parambytes,SP
 jmp    (a1);rts
;------------------------------------------------------------
;      <<<< Handle Down Scroll arrow >>>>
;------------------------------------------------------------
DownActionProc
 ;offsets into A6 stack
 thecontrol set  10
 pcode  set 8
 parambytes set  6

 link   A6,#0
 saveregs
 tst    pcode(A6)
 beq    DownActionDone
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 _GetCtlValue
 move   (sp)+,D2
 add    #1,D2    ;add 1 to scroll val
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 _GetMaxCtl
 move   (sp)+,D1
 ;don’t scroll past controls max setting!
 cmp    D1,D2
 bgt    DownActionDone
 move.l WhichControl(A5),-(sp)
 move   D2,-(sp)
 _SetCtlValue
 move   #-1,D6     ;d6 = how many lines
 bsr    Scroll_The_Text   ;to scroll!

DownActionDone
 restoreregs
 unlk   A6
 move.l (sp)+,A1
 adda.w #parambytes,SP
 jmp    (a1);rts
;------------------------------------------------------------
;      <<<< Handle PageUp Scroll arrow >>>>
;------------------------------------------------------------
PageUpActionProc
 ;offsets into A6 stack
 thecontrol set  10
 pcode  set 8
 parambytes set  6

 link   A6,#0
 saveregs
 tst    pcode(A6)
 beq    PageUpActionDone
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 _GetCtlValue
 move   (sp)+,D1
 move   LinesInWind(A5),D0
 sub    #1,D0
 sub    D0,D1
 move   D0,D6    ;d6 = how many lines
 ;to scroll!
 ;are we going to go before 1st line?
 ;if so, figure how many lines from current position
 ;until 0 (zero) and use that # to scroll text!
 cmp    #nil,D1
 bge    Not_Past_Begin2
 add    D1,D6    ;set to proper value
 ;for scroll
 move   #nil,D1  ;to set ctrl

Not_Past_Begin2
 move.l WhichControl(A5),-(sp)
 move   D1,-(sp)
 _SetCtlValue
 bsr    Scroll_The_Text

PageUpActionDone
 restoreregs
 unlk   A6
 move.l (sp)+,A1
 adda.w #parambytes,SP
 jmp    (a1);rts
;------------------------------------------------------------
;     <<<< Handle PageDown Scroll arrow >>>>
;------------------------------------------------------------
PageDownActionProc
 ;offsets into A6 stack
 thecontrol set  10
 pcode  set 8
 parambytes set  6

 link   A6,#0
 saveregs
 tst    pcode(A6)
 beq    PageDownActionDone
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 _GetCtlValue
 move   (sp)+,D7
 move   D7,D2
 move   LinesInWind(A5),D0
 sub    #1,D0
 add    D0,D2
 neg    D0
 move   D0,D6  ;d6 = how many lines
 ;to scroll!
 ;are we going to go after last line?
 ;if so, figure how many lines from current position
 ;until last line and use that # to scroll text
 clr    -(sp)
 move.l WhichControl(A5),-(sp)
 _GetMaxCtl
 move   (sp)+,D3 ;to set ctrl
 cmp    D3,D2
 ble    Not_Past_End
 sub    D3,D7    ;set to proper value
 move   D7,D6    ;for scroll
 move   D3,D2    ;to set ctrl

Not_Past_End
 move.l WhichControl(A5),-(sp)
 move   D2,-(sp)
 _SetCtlValue
 bsr    Scroll_The_Text

PageDownActionDone
 restoreregs
 unlk   A6
 move.l (sp)+,A1
 adda.w #parambytes,SP
 jmp    (a1);rts
;------------------------------------------------------------
;     <<<< Do the actual text scrolling >>>>
;------------------------------------------------------------
Scroll_The_Text
 ;d6 has how many lines and which direction to scroll
 ;(depending on whether the value is pos. or neg.)
 ;use teLineHite to figure how many pixels to scroll
 ;by multiplying it with the amount of lines
 clr.l  D2
 move.l TextHand(A5),A2
 move.l (A2),A2
 move   teLineHite(A2),D2
 muls   D6,D2
 move   #nil,-(sp) ;no horiz. scroll
 move   D2,-(sp) ;vert. scroll
 move.l TextHand(A5),-(sp)
 _TESCroll
 rts
;<<<< END of all text scrolling routines >>>>
;------------------------------------------------------------
;   <<<< How many text lines can fit in user item rect >>>>
;------------------------------------------------------------
Calc_Lines_In_One_Windowful
 saveregs

 bsr    Get_Rect_Of_Item
 clr.l  D4
 lea    DispRect(A5),A2
 move   Top(A2),D3
 move   Bottom(A2),D4
 sub    D3,D4      ;Top-Bottom = how many 
       ;pixels in text view box
       ;D4= heighth (in pixels)
       ;of help window
 clr.l  D5
 move.l TextHand(A5),A2
 move.l (A2),A2
 move   teLineHite(A2),D5  ;rect heighth
 divu   D5,D4    ;divided by the
      ;heighth of one
      ;line of text =
      ;how many lines
      ;can fit!
 ;D4 now = how many lines of text can fit into one
 ;screen of the user item of the dialog box!
 move   D4,LinesInWind(A5)
 restoreregs
 rts
;------------------------------------------------------------
;    <<<< Erase inside of user item rect of dialog >>>>
;------------------------------------------------------------
Erase_Rect
 ;erase entire user item rectangle
 bsr    Get_Rect_Of_Item
 pea    DispRect(A5)
 _EraseRect

 rts
;------------------------------------------------------------
;    <<<< Get user item rect of dialog >>>>
;------------------------------------------------------------
Get_Rect_Of_Item
 ;Get info from User Item #2
 move.l DialogPtr(A5),-(SP)
 move   #2,-(sp)
 pea    ItemType(A5)
 pea    ItemHandle(A5)
 pea    DispRect(A5)
 _GetDItem
 rts
;------------------------------------------------------------
;<<<< Change button to say ‘Done Viewing’ >>>>
;------------------------------------------------------------
Set_To_DoneViewing
 bsr    Get_Button_Handle
 move.l ItemHandle(A5),-(sp)
 pea    DoneViewing
 _SetCTitle
 rts
;------------------------------------------------------------
;      <<<< Change button to say ‘Done with Help’ >>>>
;------------------------------------------------------------
Set_To_DoneWithHelp
 bsr    Get_Button_Handle
 move.l ItemHandle(A5),-(sp)
 pea    DoneString
 _SetCTitle
 rts
;------------------------------------------------------------
;    <<<< Get handle of button in dialog >>>>
;------------------------------------------------------------
Get_Button_Handle
 ;Get the buttons handle (for changing the buttons
 ;title)
 move.l DialogPtr(A5),-(SP)
 move   #1,-(sp)
 pea    ItemType(A5)
 pea    ItemHandle(A5)
 pea    DispRect(A5)
 _GetDItem
 rts
;------------------------------------------------------------
;  <<<< Get watch CURSor and display it >>>>
;------------------------------------------------------------
GetandSetWatch
 clr.l  -(sp)
 move   #watchcursor,-(sp)
 _GetCursor
 move.l (sp)+,A0
 move.l (A0),-(sp)
 _SetCursor
 rts
;------------------------------------------------------------
;  <<<< Frame the user item rect of dialog >>>>
;------------------------------------------------------------
Frame_The_Rect
 ;frame the outside of the user items rectangle
 bsr    Get_Rect_Of_Item
 pea    DispRect(A5)    ;Inset rect by 1
 move   #-1,-(sp)      ;outward
 move   #-1,-(sp)
 _InSetRect
 pea    DispRect(A5)
 _FrameRect
 rts
;------------------------------------------------------------
;     <<<< Hilight A Dialog Button >>>>
;------------------------------------------------------------
;this routine expects parameters to be on the stack
;PROCEDURE    HilightDialogButton (WPtr: Ptr; WhichItem: Int)
;Will hilight a button in a dialog box
HilightDialogButton
 WindPt SET 10
 WhichItemSET  8
 parambytes SET  6

 ;local variables
 TheTypeSET -4 ;Vars for _GetDItem
 TheHandleSET  -8;handle
 TheRectSET -16  ;item rect
 localbytes SET  -16 ;for link

 link   A6,#localbytes
 saveregs
 move.l WindPt(A6),-(SP)
 _SetPort
 move.l WindPt(A6),-(SP)
 move   WhichItem(A6),-(sp)
 pea    TheType(A6)
 pea    TheHandle(A6)
 pea    TheRect(A6)
 _GetDItem
 move   #3,-(sp)
 move   #3,-(sp)
 _PenSize
 pea    TheRect(A6)
 move   #-4,-(sp)
 move   #-4,-(sp)
 _InSetRect
 pea    TheRect(A6)
 move   #16,-(sp)
 move   #16,-(sp)
 _FrameRoundRect
 move   #1,-(sp)
 move   #1,-(sp)
 _PenSize
 restoreregs
 unlk   A6
 move.l (sp)+,A0
 adda   #parambytes,SP
 jmp    (A0);rts

;------------------------------------------------------------
;     <<<< Set up the dialog box with the help info >>>>
;------------------------------------------------------------
SetUpHelpList
 saveregs

 bsr    Calc_Cell_Width
 bsr    Get_Rect_Of_Item
 ;must allow room for the lists scroll bar on the right
 ;side so subtract 15 from the rects right side!
 lea    DispRect(A5),A1
 sub    #15,right(A1)
 ;set up the arrayrect (for the cells rows and columns)
 ;for the List Mgr
 lea    arrayrect(A5),a0
 move.l #0,(A0)+
 move   #arrayRows,(A0)+
 move   #arraycolumns,(A0)+
 move   #celldepth,D0
 swap   D0
 move   cellWidth(A5),D0
 ;create a new List
 clr.l  -(sp)
 pea    DispRect(A5) ;list rect!
 pea    arrayrect(A5)
 move.l D0,-(sp) ;cell size
 move   #0,-(sp) ;res id of proc.
 move.l DialogPtr(A5),-(sp) ;window ptr
 move.w #false,-(sp) ;draw it?
 move   #false,-(sp) ;has grow?
 move   #false,-(sp) ;horiz scroll?
 move   #true,-(sp);vert scroll?
 _LNew
 move.l (sp)+,ListHandle(A5)
 ;set selflags to allow only one selection at a time!
 move.l ListHandle(A5),A0
 move.l (A0),A0
 move.b #128,selFlags(A0)
 ;put all the ‘help’ names (topics) into the list
 bsr    AddHelpNamesToList
 restoreregs
 rts
;------------------------------------------------------------
;<<<< Calculate cell width for list manager >>>>
;------------------------------------------------------------
Calc_Cell_Width
 bsr    Get_Rect_Of_Item
 move   DispRect+right(A5),D2
 move   DispRect+left(A5),D3
 sub    D3,D2
 sub    #16,D2       ;allow for scroll
 move   D2,cellwidth(A5)    ;return value
 rts
;------------------------------------------------------------
; <<<< Add ‘help’ resource names to List >>>>
;------------------------------------------------------------
AddHelpNamesToList
;this is a routine to add all ‘help’ resource names 
;to a list

 saveregs
 clr    -(sp)
 move.l #’help’,-(sp)
 _CountResources
 move   (sp)+,D4   ;how many there are
 move   D4,D7
 beq    None_Here  ;if no ‘help’ res’s
   ;here, quit!
 sub    #1,D4    ;sub 1 for looping
   ;(the DBRA later)
 move   #false,-(sp)    ;set drawing off
 move.l ListHandle(A5),-(sp)
 _LDoDraw
 move.l #nil,TheCell(A5) ;start with zero cell
 ;set ResLoad off (so resources are not
 ;automatically read into memory)
 move   #false,-(sp)
 _SetResLoad

AddhelpLoop
 clr.l  -(sp)
 move.l #’help’,-(sp)
 move   D7,-(sp) ;res. id #
 _GetResource
 move.l (sp),A4  ;leave handle on stack 
 ;for next routine
 ;get the resources name
 pea    ResId(A5)
 pea    ResType(A5)
 pea    ResName(A5)
 _GetResInfo
 lea    ResName(A5),A3
 clr.l  D3
 move.b (A3)+,D3 ;how many chars in 
 ;name for later
 sub    #1,D7  ;decrement index #
 ;D7 = the res id#
 ;d3 = how many characters in string, 
 ;A3 = ptr to string data
 ;add a new row
 clr    -(sp)
 move   #1,-(sp)
 move   #0,-(sp)
 move.l ListHandle(A5),-(sp)
 _LAddRow
 move   (sp)+,D0
 ;set the cells data to the resources name
 move.l A3,-(sp) ;points to name
 move   D3,-(sp) ;how many chars?
 move.l TheCell(A5),-(sp)
 move.l ListHandle(A5),-(sp)
 _LSetCell
 dbra   D4,AddhelpLoop  ;loop until D4 = 0
 ;set ResLoad back on
 move   #true,-(sp)
 _SetResLoad
 move   #true,-(sp);turn drawing on
 move.l ListHandle(A5),-(sp)
 _LDoDraw
 ;update the list to show it
 MOVE.L DialogPtr(A5),A1
 move.l 24(A1),-(sp)
 move.l ListHandle(A5),-(sp)
 _LUpdate
 bsr    Frame_The_Rect

None_Here
 restoreregs
 rts
;------------------------------------------------------------
;     <<<< Constants >>>>
;------------------------------------------------------------
DoneStringdc.b 14,’Done with Help’
 .align 2
DoneViewing dc.b 12,’Done viewing’
 .align 2
;------------------------------------------------------------
;  <<<< Global variables >>>>
;------------------------------------------------------------
WhichControlds.l 1    ;used by _FindControl
TextHandds.l1    ;TE record Handle
ScrollHandds.l 1    ;Handle of scroll bar
DialogPtr ds.l 1    ;Ptr to Help Dialog
LinesInWind ds 1    ;how many text lines fit in rect
AString ds.b256  ;Space for a string

ListHandleds.l 1    ;Handle to list
TheCell ds.l1    ;Used by the List Mgr
ArrayRect ds.l 2    ;Rows & columns for List Mgr
cellwidth ds.w 1    ;width of cell in list
DataLengthds.w 1    ;Var used by _LGetCell

ItemTypeds.l1    ;Vars used by _GetDItem
ItemHandleds.l 1    ;Handle of Dialog Item
DispRectds.l2    ;Rect of Dialog Item

ResHand ds.l1    ;Handle of a ‘help’ resource
ResId   ds.w1    ;Vars used by _GetResInfo ID#
ResType ds.l1    ;res. type
ResName ds.b256  ;res. name

ItemNumberds.w 1    ;Item# returned by _ModalDialog
 END

* File name:  YourApp.R
* Example .R file for YourApp, which
* is an example application name
* that has been linked with DoHelp.
* Resource is also an example name, it
* should be the name of a resource file
* containing all of the needed resources for
* YourApp, Including the ‘help’ resources for 
* DoHelp which you can create using ResEdit
* This also creates the DLOG & DITL that
* DoHelp needs.

MDS1:YourApp
APPLTEST

Type DLOG
 ,2000
Help
56 32 318 476
visible NoGoAway
4
0
2000

Type DITL
 ,2000
3

Button
232 152 256 288
Done with help

userItem
8 8 200 434

staticText Disabled
208 96 224 344
Click on a Help topic (above) to view.

INCLUDE MDS2:YourApp.Code
INCLUDE MDS1:Resources

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Whitethorn Games combines two completely...
If you have ever gone fishing then you know that it is a lesson in patience, sitting around waiting for a bite that may never come. Well, that's because you have been doing it wrong, since as Whitehorn Games now demonstrates in new release Skate... | Read more »
Call of Duty Warzone is a Waiting Simula...
It's always fun when a splashy multiplayer game comes to mobile because they are few and far between, so I was excited to see the notification about Call of Duty: Warzone Mobile (finally) launching last week and wanted to try it out. As someone who... | Read more »
Albion Online introduces some massive ne...
Sandbox Interactive has announced an upcoming update to its flagship MMORPG Albion Online, containing massive updates to its existing guild Vs guild systems. Someone clearly rewatched the Helms Deep battle in Lord of the Rings and spent the next... | Read more »
Chucklefish announces launch date of the...
Chucklefish, the indie London-based team we probably all know from developing Terraria or their stint publishing Stardew Valley, has revealed the mobile release date for roguelike deck-builder Wildfrost. Developed by Gaziter and Deadpan Games, the... | Read more »
Netmarble opens pre-registration for act...
It has been close to three years since Netmarble announced they would be adapting the smash series Solo Leveling into a video game, and at last, they have announced the opening of pre-orders for Solo Leveling: Arise. [Read more] | Read more »
PUBG Mobile celebrates sixth anniversary...
For the past six years, PUBG Mobile has been one of the most popular shooters you can play in the palm of your hand, and Krafton is celebrating this milestone and many years of ups by teaming up with hit music man JVKE to create a special song for... | Read more »
ASTRA: Knights of Veda refuse to pump th...
In perhaps the most recent example of being incredibly eager, ASTRA: Knights of Veda has dropped its second collaboration with South Korean boyband Seventeen, named so as it consists of exactly thirteen members and a video collaboration with Lee... | Read more »
Collect all your cats and caterpillars a...
If you are growing tired of trying to build a town with your phone by using it as a tiny, ineffectual shover then fear no longer, as Independent Arts Software has announced the upcoming release of Construction Simulator 4, from the critically... | Read more »
Backbone complete its lineup of 2nd Gene...
With all the ports of big AAA games that have been coming to mobile, it is becoming more convenient than ever to own a good controller, and to help with this Backbone has announced the completion of their 2nd generation product lineup with their... | Read more »
Zenless Zone Zero opens entries for its...
miHoYo, aka HoYoverse, has become such a big name in mobile gaming that it's hard to believe that arguably their flagship title, Genshin Impact, is only three and a half years old. Now, they continue the road to the next title in their world, with... | Read more »

Price Scanner via MacPrices.net

B&H has Apple’s 13-inch M2 MacBook Airs o...
B&H Photo has 13″ MacBook Airs with M2 CPUs and 256GB of storage in stock and on sale for up to $150 off Apple’s new MSRP, starting at only $849. Free 1-2 day delivery is available to most US... Read more
M2 Mac minis on sale for $100-$200 off MSRP,...
B&H Photo has Apple’s M2-powered Mac minis back in stock and on sale today for $100-$200 off MSRP. Free 1-2 day shipping is available for most US addresses: – Mac mini M2/256GB SSD: $499, save $... Read more
Mac Studios with M2 Max and M2 Ultra CPUs on...
B&H Photo has standard-configuration Mac Studios with Apple’s M2 Max & Ultra CPUs in stock today and on Easter sale for $200 off MSRP. Their prices are the lowest available for these models... Read more
Deal Alert! B&H Photo has Apple’s 14-inch...
B&H Photo has new Gray and Black 14″ M3, M3 Pro, and M3 Max MacBook Pros on sale for $200-$300 off MSRP, starting at only $1399. B&H offers free 1-2 day delivery to most US addresses: – 14″ 8... Read more
Department Of Justice Sets Sights On Apple In...
NEWS – The ball has finally dropped on the big Apple. The ball (metaphorically speaking) — an antitrust lawsuit filed in the U.S. on March 21 by the Department of Justice (DOJ) — came down following... Read more
New 13-inch M3 MacBook Air on sale for $999,...
Amazon has Apple’s new 13″ M3 MacBook Air on sale for $100 off MSRP for the first time, now just $999 shipped. Shipping is free: – 13″ MacBook Air (8GB RAM/256GB SSD/Space Gray): $999 $100 off MSRP... Read more
Amazon has Apple’s 9th-generation WiFi iPads...
Amazon has Apple’s 9th generation 10.2″ WiFi iPads on sale for $80-$100 off MSRP, starting only $249. Their prices are the lowest available for new iPads anywhere: – 10″ 64GB WiFi iPad (Space Gray or... Read more
Discounted 14-inch M3 MacBook Pros with 16GB...
Apple retailer Expercom has 14″ MacBook Pros with M3 CPUs and 16GB of standard memory discounted by up to $120 off Apple’s MSRP: – 14″ M3 MacBook Pro (16GB RAM/256GB SSD): $1691.06 $108 off MSRP – 14... Read more
Clearance 15-inch M2 MacBook Airs on sale for...
B&H Photo has Apple’s 15″ MacBook Airs with M2 CPUs (8GB RAM/256GB SSD) in stock today and on clearance sale for $999 in all four colors. Free 1-2 delivery is available to most US addresses.... Read more
Clearance 13-inch M1 MacBook Airs drop to onl...
B&H has Apple’s base 13″ M1 MacBook Air (Space Gray, Silver, & Gold) in stock and on clearance sale today for $300 off MSRP, only $699. Free 1-2 day shipping is available to most addresses in... Read more

Jobs Board

Medical Assistant - Surgical Oncology- *Apple...
Medical Assistant - Surgical Oncology- Apple Hill Location: WellSpan Medical Group, York, PA Schedule: Full Time Sign-On Bonus Eligible Remote/Hybrid Regular Apply Read more
Omnichannel Associate - *Apple* Blossom Mal...
Omnichannel Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Cashier - *Apple* Blossom Mall - JCPenney (...
Cashier - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Blossom Mall Read more
Operations Associate - *Apple* Blossom Mall...
Operations Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Business Analyst | *Apple* Pay - Banco Popu...
Business Analyst | Apple PayApply now " Apply now + Apply Now + Start applying with LinkedIn Start + Please wait Date:Mar 19, 2024 Location: San Juan-Cupey, PR Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.