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

 
AAPL
$524.94
Apple Inc.
+5.93
MSFT
$40.01
Microsoft Corpora
-0.39
GOOG
$536.10
Google Inc.
-20.44

MacTech Search:
Community Search:

Software Updates via MacUpdate

VMware Fusion 6.0.3 - Run Windows apps a...
VMware Fusion allows you to create a Virtual Machine on your Mac and run Windows (including Windows 8.1) and Windows software on your Mac. Run your favorite Windows applications alongside Mac... Read more
Tweetbot 1.5.1 - Popular iOS twitter cli...
Tweetbot is a full-featured OS X Twitter client with a lot of personality. Whether it's the meticulously-crafted interface, sounds and animation, or features like multiple timelines and column views... Read more
Mac DVDRipper Pro 4.1.7 - Copy, backup,...
Mac DVDRipper Pro is the DVD backup solution that lets you protect your DVDs from scratches, save your batteries by reading your movies from your hard disk, manage your collection with just a few... Read more
PDFpenPro 6.2 - Advanced PDF toolkit for...
PDFpenPro allows users to edit PDF's easily. Add text, images and signatures. Fill out PDF forms. Merge or split PDF documents. Reorder and delete pages. Even correct text and edit graphics! Create... Read more
PDFpen 6.2 - Edit and annotate PDFs with...
PDFpen allows users to easily edit PDF's. Add text, images and signatures. Fill out PDF forms. Merge or split PDF documents. Reorder and delete pages. Even correct text and edit graphics! Features... Read more
Monolingual 1.5.9 - Remove unwanted OS X...
Monolingual is a program for removing unnecesary language resources from OS X, in order to reclaim several hundred megabytes of disk space. It requires a 64-bit capable Intel-based Mac and at least... Read more
Maya 2015 - Professional 3D modeling and...
Maya is an award-winning software and powerful, integrated 3D modeling, animation, visual effects, and rendering solution. Because Maya is based on an open architecture, all your work can be scripted... Read more
Starcraft II: Wings of Liberty 1.1.1.180...
Download the patch by launching the Starcraft II game and downloading it through the Battle.net connection within the app. Starcraft II: Wings of Liberty is a strategy game played in real-time. You... Read more
Sibelius 7.5.0 - Music notation solution...
Sibelius is the world's best-selling music notation software for Mac. It is as intuitive to use as a pen, yet so powerful that it does most things in less than the blink of an eye. The demo includes... Read more
Typinator 5.9 - Speedy and reliable text...
Typinator turbo-charges your typing productivity. Type a little. Typinator does the rest. We've all faced projects that require repetitive typing tasks. With Typinator, you can store commonly used... Read more

Latest Forum Discussions

See All

Have a Special Dead Trigger 2 Easter Bas...
Have a Special Dead Trigger 2 Easter Basket Full of Goodies, Courtesy of Madfinger Games Posted by Rob Rich on April 18th, 2014 [ permalink ] Dead Trigger 2 | Read more »
Almost All of Playdek’s Library is on Sa...
Almost All of Playdek’s Library is on Sale Right Now, and You Should Check it Out Posted by Rob Rich on April 18th, 2014 [ permalink ] Playdek has released quite a few great iOS ports of board and card games over the years, and now most of them... | Read more »
Zynga Launches Brand New Farmville Exper...
Zynga Launches Brand New Farmville Experience with Farmville 2: Country Escape Posted by Tre Lawrence on April 18th, 2014 [ permalink ] | Read more »
David. Review
David. Review By Cata Modorcea on April 18th, 2014 Our Rating: :: MINIMALISTIC IN A DIFFERENT WAYUniversal App - Designed for iPhone and iPad David is a minimalistic game wrapped inside of a soothing atmosphere in which the hero... | Read more »
Eyefi Unveils New Eyefi Cloud Service Th...
Eyefi Unveils New Eyefi Cloud Service That Allows Users to Share Media Across Personal Devices Posted by Tre Lawrence on April 18th, 2014 [ permalink ] | Read more »
Tales from the Dragon Mountain: The Lair...
Tales from the Dragon Mountain: The Lair Review By Jennifer Allen on April 18th, 2014 Our Rating: :: STEADY ADVENTURINGiPad Only App - Designed for the iPad Treading a safe path, Tales from the Dragon Mountain: The Lair is a... | Read more »
Yahoo Updates Flickr App with Advanced E...
Yahoo Updates Flickr App with Advanced Editing Features and More Posted by Tre Lawrence on April 18th, 2014 [ permalink ] | Read more »
My Incredible Body - A Kid's App to...
My Incredible Body - A Kid's App to Learn about the Human Body 1.1.00 Device: iOS Universal Category: Education Price: $2.99, Version: 1.1.00 (iTunes) Description: Wouldn’t it be cool to look inside yourself and see what was going on... | Read more »
Trials Frontier Review
Trials Frontier Review By Carter Dotson on April 18th, 2014 Our Rating: :: A ROUGH LANDINGUniversal App - Designed for iPhone and iPad Trials Frontier finally brings the famed stunt racing franchise to mobile, but how much does its... | Read more »
Evernote Business Notebook by Moleskin I...
Evernote Business Notebook by Moleskin Introduced – Support Available in Evernote for iOS Posted by Tre Lawrence on April 18th, 2014 [ permalink ] | Read more »

Price Scanner via MacPrices.net

Free HopTo 2.2 Helps Enhance Your Productivit...
The HopTo app helps you do more on your iPad by providing more and easier adaccess to files and documents. Version 2.2 adds Egnyte and HopTo’s Mac OSX File Connector. If you already have the hopTo... Read more
National Distracted Driving Awareness Month:...
As the country recognizes National Distracted Driving Awareness Month, Sprint is reminding wireless consumers to focus on driving while behind the wheel, to not text or email while driving, and to... Read more
13-inch 2.4GHz Retina MacBook Pro available f...
Abt has the 13″ 2.4GHz 128GB Retina MacBook Pro available for $1229 including free shipping. Their price is $70 off MSRP. Read more
iMacs on sale for up to $160 off MSRP this we...
Best Buy has iMacs on sale for up to $160 off MSRP for a limited time. Choose free home shipping or free instant local store pickup (if available). Prices are valid for online orders only, in-store... Read more
iPad Airs on sale this weekend for up to $100...
Best Buy has WiFi iPad Airs on sale for $50 off MSRP and WiFi + Cellular iPad Airs on sale for $100 off MSRP on their online store for a limited time, with prices now starting at $449. Choose free... Read more
Apple restocks refurbished Mac minis starting...
The Apple Store has restocked Apple Certified Refurbished Mac minis for up to $150 off the cost of new models. Apple’s one-year warranty is included with each mini, and shipping is free: - 2.5GHz Mac... Read more
Hyundai Brings Apple CarPlay To The 2015 Sona...
Hyundai Motor America has announced it will bring Apple CarPlay functionality to the 2015 Sonata. CarPlay is pitched as a smarter, safer and easier way to use iPhone in the car and gives iPhone users... Read more
Updated iPads Coming Sooner Than We Had Thoug...
MacRumors, cites KGI securities analyst Ming Chi Kuo, well-respected as an Apple product prognisticator, saying that Apple will introduce an upgraded iPad Air and iPad mini in 2014/Q3, meaning the... Read more
Toshiba Unveils New High And Low End Laptop M...
Toshiba has announced new laptop models covering both the high-end and low-end of the notebook computer spectrum. Toshiba 4K Ultra HD Laptop Toshiba’s new Satellite P55t features one of the world’s... Read more
Save up to $270 with Apple refurbished 13-inc...
The Apple Store has Apple Certified Refurbished October 2013 13″ Retina MacBook Pros available starting at $1099, with models up to $270 off MSRP. Apple’s one-year warranty is standard, and shipping... Read more

Jobs Board

*Apple* Automotive Parts Department position...
Apple Automotive is one of the fastest growing dealer…and it shows. Consider making the switch to the Apple Automotive Group today! At Apple Automotive, we Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Retail - Manager - Holyoke - Apple I...
Job Summary Keeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, you’re a master of them all. In the store’s fast-paced, Read more
*Apple* Retail - Manager - Apple (United Sta...
Job SummaryKeeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, you're a master of them all. In the store's fast-paced, dynamic Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.