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
$105.22
Apple Inc.
+0.39
MSFT
$46.13
Microsoft Corpora
+1.11
GOOG
$539.78
Google Inc.
-4.20

MacTech Search:
Community Search:

Software Updates via MacUpdate

f.lux 34.0 - Adjusts the color of your d...
f.lux makes the color of your computer's display adapt to the time of day, warm at night and like sunlight during the day. Ever notice how people texting at night have that eerie blue glow? Or wake... Read more
Ember 1.8.2 - Versatile digital scrapboo...
Ember (formerly LittleSnapper) is your digital scrapbook of things that inspire you: websites, photos, apps or other things. Just drag in images that you want to keep, organize them into relevant... Read more
Tonality Pro 1.1.2 - Professional-grade...
Tonality Pro gives you the power to create stunning and dramatic black & white images. This is a complete monochrome image editor with more than 150 one-click style presets, totally unique... Read more
VueScan 9.4.49 - Scanner software with a...
VueScan is a scanning program that works with most high-quality flatbed and film scanners to produce scans that have excellent color fidelity and color balance. VueScan is easy to use, and has... Read more
OS X Server 4.0 - For OS X 10.10 Yosemit...
Designed for OS X and iOS devices, OS X Server makes it easy to share files, schedule meetings, synchronize contacts, develop software, host your own website, publish wikis, configure Mac, iPhone,... Read more
TotalFinder 1.6.12 - Adds tabs, hotkeys,...
TotalFinder is a universally acclaimed navigational companion for your Mac. Enhance your Mac's Finder with features so smart and convenient, you won't believe you ever lived without them. Tab-based... Read more
BusyCal 2.6.3 - Powerful calendar app wi...
BusyCal is an award-winning desktop calendar that combines personal productivity features for individuals with powerful calendar sharing capabilities for families and workgroups. BusyCal's unique... Read more
calibre 2.7 - Complete e-library managem...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital... Read more
Skitch 2.7.3 - Take screenshots, annotat...
With Skitch, taking, annotating, and sharing screenshots or images is as fun as it is simple.Communicate and collaborate with images using Skitch and its intuitive, engaging drawing and annotating... Read more
Delicious Library 3.3.2 - Import, browse...
Delicious Library allows you to import, browse, and share all your books, movies, music, and video games with Delicious Library. Run your very own library from your home or office using our... Read more

Latest Forum Discussions

See All

Rami Ismail Opens Up distribute​() for D...
Rami Ismail Opens Up distribute​() for Developers Posted by Jessica Fisher on October 24th, 2014 [ permalink ] Rami Ismail, Chief Executive of Business and Development at indie game studio | Read more »
Great Hitman GO Goes on Sale and Gets Ne...
Great Hitman GO Goes on Sale and Gets New Update – Say That Three Times Fast Posted by Jessica Fisher on October 24th, 2014 [ permalink ] | Read more »
Rival Stars Basketball Review
Rival Stars Basketball Review By Jennifer Allen on October 24th, 2014 Our Rating: :: RESTRICTIVE BUT FUNUniversal App - Designed for iPhone and iPad Rival Stars Basketball is a fun mixture of basketball and card collecting but its... | Read more »
Rubicon Development Makes Over a Dozen o...
Rubicon Development Makes Over a Dozen of Their Games Free For This Weekend Only Posted by Jessica Fisher on October 24th, 2014 [ permalink ] | Read more »
I Am Dolphin Review
I Am Dolphin Review By Jennifer Allen on October 24th, 2014 Our Rating: :: NEARLY FIN-TASTICUniversal App - Designed for iPhone and iPad Swim around and eat nearly everything that moves in I Am Dolphin, a fun Ecco-ish kind of game... | Read more »
nPlayer looks to be the ultimate choice...
Developed by Newin Inc, nPlayer may seem like your standard video player – but is aiming to be the best in its field by providing high quality video play performance and support for a huge number of video formats and codecs. User reviews include... | Read more »
Fighting Fantasy: Caverns of the Snow Wi...
Fighting Fantasy: Caverns of the Snow Witch Review By Jennifer Allen on October 24th, 2014 Our Rating: :: CLASSY STORYTELLINGUniversal App - Designed for iPhone and iPad Fighting Fantasy: Caverns of the Snow Witch is a sterling... | Read more »
A Few Days Left (Games)
A Few Days Left 1.01 Device: iOS Universal Category: Games Price: $3.99, Version: 1.01 (iTunes) Description: Screenshots are in compliance to App Store's 4+ age rating! Please see App Preview for real game play! **Important: Make... | Read more »
Toca Boo (Education)
Toca Boo 1.0.2 Device: iOS Universal Category: Education Price: $2.99, Version: 1.0.2 (iTunes) Description: BOO! Did I scare you!? My name is Bonnie and my family loves to spook! Do you want to scare them back? Follow me and I'll... | Read more »
Intuon (Games)
Intuon 1.1 Device: iOS Universal Category: Games Price: $.99, Version: 1.1 (iTunes) Description: Join the battle with your intuition in a new hardcore game Intuon! How well do you trust your intuition? Can you find a needle in a... | Read more »

Price Scanner via MacPrices.net

Weekend sale: 13-inch 128GB MacBook Air for $...
Best Buy has the 2014 13-inch 1.4GHz 128GB MacBook Air on sale for $849.99, or $150 off MSRP, on their online store. Choose free home shipping or free local store pickup (if available). Price valid... Read more
Nimbus Note Cross=Platform Notes Utility
Nimbus Note will make sure you never forget or lose your valuable data again. Create and edit notes, save web pages, screenshots and any other type of data – and share it all with your friends and... Read more
NewerTech’s Snuglet Makes MagSafe 2 Power Con...
NewerTech has introduced the Snuglet, a precision-manufactured ring designed to sit inside your MagSafe 2 connector port, providing a more snug fit to prevent your power cable from unintentional... Read more
Apple Planning To Sacrifice Gross Margins To...
Digitimes Research’s Jim Hsiao says its analysts believe Apple is planning to sacrifice its gross margins to save its tablet business, which has recently fallen into decline. They project that Apple’... Read more
Who’s On Now? – First Instant-Connect Search...
It’s nighttime and your car has broken down on the side of the highway. You need a tow truck right away, so you open an app on your iPhone, search for the closest tow truck and send an instant... Read more
13-inch 2.5GHz MacBook Pro on sale for $949,...
Best Buy has the 13″ 2.5GHz MacBook Pro available for $949.99 on their online store. Choose free shipping or free instant local store pickup (if available). Their price is $150 off MSRP. Price is... Read more
Save up to $125 on Retina MacBook Pros
B&H Photo has the new 2014 13″ and 15″ Retina MacBook Pros on sale for up to $125 off MSRP. Shipping is free, and B&H charges NY sales tax only. They’ll also include free copies of Parallels... Read more
Apple refurbished Time Capsules available sta...
The Apple Store has certified refurbished Time Capsules available for up to $60 off MSRP. Apple’s one-year warranty is included with each Time Capsule, and shipping is free: - 2TB Time Capsule: $255... Read more
Textilus New Word, Notes and PDF Processor fo...
Textilus is new word-crunching, notes, and PDF processor designed exclusively for the iPad. I haven’t had time to thoroughly check it out yet, but it looks great and early reviews are positive.... Read more
WD My Passport Pro Bus-Powered Thunderbolt RA...
WD’s My Passport Pro RAID solution is powered by an integrated Thunderbolt cable for true portability and speeds as high as 233 MB/s. HighlightsOverviewSpecifications Transfer, Back Up And Edit In... Read more

Jobs Board

*Apple* Solutions Consultant - Apple Inc. (U...
…important role that the ASC serves is that of providing an excellent Apple Customer Experience. Responsibilities include: * Promoting Apple products and solutions Read more
*Apple* Solutions Consultant - Apple Inc. (U...
…important role that the ASC serves is that of providing an excellent Apple Customer Experience. Responsibilities include: * Promoting Apple products and solutions Read more
Senior Event Manager, *Apple* Retail Market...
…This senior level position is responsible for leading and imagining the Apple Retail Team's global event strategy. Delivering an overarching brand story; in-store, 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
Project Manager / Business Analyst, WW *Appl...
…a senior project manager / business analyst to work within our Worldwide Apple Fulfillment Operations and the Business Process Re-engineering team. This role will work Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.