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.L A0-A4/D0-D7,-(SP)
|
MACRO RestoreRegs =
MOVEM.L (SP)+,A0-A4/D0-D7
|
true equ $0100
false equ 0
nil equ 0
arraycolumns equ 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
DialogID equ 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)