TweetFollow Us on Twitter

Controls FORTRAN
Volume Number:3
Issue Number:4
Column Tag:Fortran's World

Controls from FORTRAN

By Glenn Forney, Gaithersburg, MD

Previous articles and examples in MacTutor have shown how to incorporate features of the Macintosh user interface such as menus and windows into FORTRAN applications. This article will show how to implement simple controls such as buttons, checkboxes and radio buttons.

The text will identify which tool box routines to call, where to call them and why. The example is a modified version of the shell program demo.for supplied by MicroSoft. It will give the details of how to implement controls in FORTRAN.

Control BASICS

The three types of standard controls: buttons, checkboxes and radio buttons are on/off switches and have control definition ID's of 0, 1 and 2. The scrollbar is a type of control known as a dial since it can take on more than two values. It has a control definition ID of 16. These ID's specify to the control manager what type of control to create.

A control is either active or inactive, i.e. highlighted or unhighlighted. A control can also be visible or invisible. Only when a control is active and visible will it respond to the mouse.

A control has another attribute known as a part number. Each part of a control has a unique part number. Simple controls such as buttons, check boxes and radio buttons have only one part and hence only one part number. The scroll bar on the other hand is more complicated and has five parts: elevator box or thumb, up arrow, down arrow, up button and down button. Part numbers and control definition ID's for the standard controls are listed in Figure 1.

Control Part CodesControl Definition ID
push button100
check box111
radio button112
scroll bar16
inUpButton20
inDownButton21
inPageUp22
inPageDown23
inThumb129

Figure 1. Part codes and ID numbers for Standard Controls

Records Needed to Implement Controls

Control Record. A record is a Pascal data type used on the Macintosh to describe or specify windows, dialogs, controls, events, etc. Each control that is defined has a control record associated with it. A control record consists of 13 fields. Figure 2 lists these fields and gives decimal offsets which can be used to access the individual fields of the control record from FORTRAN. For example if CONTROLBEG is an INTEGER*4 variable containing the beginning address of the control record then the FORTRAN statement LONG(CONTROLBEG+4) will give the contrlOwner field of the control record. This field points to the window that contains the given control. Most of the fields in the control record can be accessed through tool box calls rather than directly with the LONG function. An exception is the first field of the control record, named nextControl, which is a handle to the next control in the window's control list. The fields of a control record that we will use to implement controls are: nextControl, controlValue and contrlRfcon.

The parameter, nextControl, is a handle for the next control record in the window's control list. So the control record for the next control in a window starts at the address given by the FORTRAN statement:

 LONG(LONG(nextControl))

When handling activate events one needs to activate or deactivate all controls in a window. The field nextControl then serves as the link which connects all controls belonging to a window.

The field contrlValue in the control record contains the value of the control. For simple controls this field simply indicates whether the control is on or off. A window can have several controls located in it. The application needs to know which one of the window's controls was pressed. This is done with the contrlRFCon field.

Our control example with two windows

The parameter contrlRFCon is used to store information about a control. This information could be an integer value that indexes a FORTRAN array describing the window's controls or a handle to a more complex data structure on the heap. In general these data structures allow the FORTRAN program to distinguish one control from another. For example when a mouse down event occurrs in a control, there is no way of knowing from the event record which control in the window was pressed. In the example program we simply number the controls 1, 2, 3, 4, 5 and set the controlRfCon field to these values.

Window Record. A second record needed to handle controls is the window record. The controlList field of this record gives a handle to the first control in the window's control list. So if WINDOWBEG is the address of the beginning of a window record then LONG(WINDOWBEG+Z'8C') is the handle to the control record of the first control in a window. If there are no controls in a window then this value is zero. The value Z'8C' is the hex value of the offset from the beginning of a window record. It indicates the location of the controlList field in the window record. For an illustration of this process see the code segment below the 'CASE(ACTIVATEEVT)' statement in the main event loop of the example program.

Event Record. Another record of interest when handling controls is the event record. Some examples of possible events are: the mouse is clicked ( a mouse down event), a window is drawn or erased ( an activate event), a window is covered or uncovered ( an update event). The individual fields of an event record are usually accessed with FORTRAN equivalence statements. The compiler does the work of computing offsets to individual fields of the event record rather than the programmer.

The event record gives a description of the state of the Macintosh when the event occurred, e.g. the time in ticks since startup, the mouse location in global coordinates, state of the keyboard, etc. We are interested in the fields: where, modifiers and message. When a mouse down event occurrs in the content region of a window, the where field, after converting to local coordinates with GLOBALTOLOCAL, indicates the mouse down location in the window. For an activate event, the modifiers field indicates whether a window should be activated or deactivated. For an update or activate event, the message field gives a pointer to the window where an update or activate event occurred. So when implementing controls we need to access these fields of the event record to determine how the program should respond to an event.

All of the tool box routines that we want to use are documented in Inside Macintosh. To use these routines from FORTRAN one needs to know how to use toolbx.sub to implement PASCAL calls in FORTRAN. Figure 3 gives a list of common PASCAL data types and their FORTRAN counter parts. This along with the example program should aid in implementing other undocumented tool box routines.

Creating Controls

There are several methods for creating controls in FORTRAN. The first method is to create it in FORTRAN using the tool box routine NEWCONTROL. Another method of creating a control is to read in a control resource that was compiled with RMAKER using the tool box routine GETNEWCONTROL. The programmer needs to fill in the resource id number and the pointer to the window the control in which will be. As in NEWCONTROL the routine GETNEWCONTROL returns a handle to the newly created control. A third method is to read in a list of dialog items from a resource with the routine GETNEWDIALOG.

Controls and Events

Activate Event. When implementing a control in an application one needs to be concerned with three events. These are activate, update and mouse down events. If a user has controls in a window where an activate event occurs then (s)he is responsible for highlighting or unhighlighting the control. This is done with the tool box routine HILITECONTROL. The programmer passes a control handle and a highlight code of 0 or 255 to HILITECONTROL where 0 means highlight (the control is to become active) and 255 means unhighlight. To know whether to highlight or unhighlight, test the first bit of the modifiers field in the event record. If the first bit is 1 then the window is being activated so the control needs to be highlighted, otherwise the bit is 0 and the control needs to be unhighlighted. A code segment to illustrate this is listed under the CASE(ACTIVATEEVT) section of the example program.

Update Event. The next event of concern is the update event. An update event is passed to your application when the system determines that a window's contents have been changed and hence need to be updated. To handle an update event in a window that contains one or more controls, one simply redraws the controls by passing a window pointer to the tool box routine DRAWCONTROLS. The window manager redraws the window, the programmer however is responsible for redrawing the controls and any other contents in the window. Any output to the window while updating must be bracketted by calls to BEGINUPDATE and ENDUPDATE. BEGINUPDATE clears the update region of the window. If these routines are not called then after the controls are drawn the system still thinks that the window needs to be updated so another update event is generated and the controls are redrawn and so on. The result is that the Macintosh "locks up" and the window contents exhibit a rapid flickering.

Mouse Down Event. There are several types of mouse down events that can occur. For example the mouse can be clicked in a menu bar, in a system window or in the content region of an application window. The mouse down event in which we are interested is when the mouse is detected in the content region of an application window. In this case we need to know if it was clicked in a control.

Each control belongs to a particular window. The coordinates used to express the location of the control inside the window must be in the window's local coordinates. When a mouse down event occurs, the mouse location is given in global coordinates by the 'where' field of the event record. So the mouse position must be converted to local coordinates using the tool box routine GLOBALTOLOCAL. Next the application needs to call the routine FINDCONTROL to determine if the mouse was pressed in a visible, active control. FINDCONTROL is passed the mouse location in local coordinates and a window pointer. It returns a handle to the selected control and the part number where the mouse was down if the control was visible and active, otherwise FINDCONTROL returns a zero.

If FINDCONTROL determines that the mouse was clicked in a control then the application calls TRACKCONTROL to see if the mouse is still in the control when the mouse button is released. If this is so then TRACKCONTROL returns the part number of the control. It is up to the application then, to get the value of the control with GETCVALUE, set it to a new value with SETCVALUE and perform the action that the application requires. For example if an application window has a scroll bar that contains text and the control is set to some new value then the control manager will redraw the control. The application is responsible for redrawing the text to reflect the new value of the control.

All of these ideas are put together in the example program that follows. It is relatively short but it does exhibit all of the features necessary to implement a simple control.

Concluding Remarks

The tool box routine TRACKCONTROL has a calling argument named procPTR. The argument procPTR is a pointer to a procedure that TRACKCONTROL calls periodically while the mouse is down in a control. This is how auto scrolling is done. In standard FORTRAN it is not clear how you would pass a pointer to a FORTRAN routine through the calling list of TRACKCONTROL or any other tool box routine. Absoft has solved this problem by writing an Assembly language "glue" subroutine that returns the pointer to a FORTRAN subroutine. A future article is needed that discusses this glue routine for scrolling text windows.

[Implementation notes: In compiling and executing this example, we had the usual pains with the latest Microsoft Fortran 2.1 version. For one thing, the include statement for the menu.inc file produced an error! It seems someone either left out the last line in that include file or forgot to close the line with a ")". We wonder how many other include files also have bugs! Once over that problem, we had to get the include statements to specify the complete path name of the files. We got a lot of compile errors on this one. We finally got it to work after re-typing the path name in by hand, but never did really figure out what the compiler didn't like. Then came the wonderful HFS brain damaged linker! It seems the linker doesn't like complete path names. We had to specify a partial path name from the current level where the linker was located down to our file. Guess the linker can only look down, not up. At any rate, we finally got a compilation and linkage. The linker script produces an application file. And the compiler produces an application file! And the resource compiler also produces an application file, so now you have three application files floating about, only one of which is the "real" application! So be careful. We called the output of the compiler, "control example apl", then called the linker output "control" and finally, the RMaker output, "RealControl" since it was the "real" one. As you can guess, we compiled, then linked in the run time library, and finally merged the resources in with RMaker to produce the final application. -Ed]

      PROGRAM CONTROLEXAMPLE
*
*   THIS PROGRAM IMPLEMENTS SIMPLE CONTROLS IN FORTRAN
*
*   AUTHOR: GLENN FORNEY
*   DATE:   8/86

      IMPLICIT NONE         ! HELPS KEEP US OUT OF TROUBLE
*
*   THE FOLLOWING INCLUDE FILES ARE INCLUDED WITH MS FORTRAN
*   YOU SHOULD CHANGE THE PATHNAMES TO MATCH YOUR SETUP
*
 include XP40-6:MacFortran:IncludeFiles:window.inc
 include XP40-6:MacFortran:IncludeFiles:dialog.inc
 include XP40-6:MacFortran:IncludeFiles:event.inc
 include XP40-6:MacFortran:IncludeFiles:menu.inc
 include XP40-6:MacFortran:IncludeFiles:control.inc
 include XP40-6:MacFortran:IncludeFiles:quickdraw.inc
 include XP40-6:MacFortran:IncludeFiles:misc.inc
*
*  DECLARATIONS
*
      INTEGER*4 TOOLBX               ! THE TOOL BOX INTERFACE
      INTEGER*4 WINDOW               ! GENERAL PURPOSE POINTER
      INTEGER*2 RECT(4)              ! RECTANGLE COORDINATES
      INTEGER*4 CONTROL_WINDOW ! POINTER TO THE CONTROL WINDOW
      INTEGER DUMMYHANDLE            ! HANDLE TO DUMMY WINDOW
      INTEGER MENUHANDLE             ! HANDLE TO MENUS
*
* WCONTRLLIST IS AN OFFSET THAT GIVES A 
* HANDLE TO THE FIRST CONTROL IN A WINDOW
* HEX 8C = DECIMAL 140, SO WCONTROLLIST BEGINS AT THE
* 140'TH BYTE IN THE WINDOW RECORD
*
      INTEGER WCONTROLLIST
      PARAMETER (WCONTROLLIST = Z'8C')
*
* DECLARATIONS FOR VARIOUS EVENTS AND MOUSE DOWN LOCATIONS
*        
      INTEGER ACTIVATE,CONTROL_HAN,SAVEPORT
      INTEGER MOUSEDOWN,UPDATEEVT,ACTIVATEEVT
      PARAMETER (MOUSEDOWN=1,UPDATEEVT=6,ACTIVATEEVT=8)

      EVENTMASK = -1  ! PROCESS ALL EVENTS
*
*  CLOSE MACFORTRAN I/O WINDOW (NEVER MAKE A DISPOSEWINDOW
*       CALL ON THIS WINDOW SINCE WE DIDN'T ALLOCATE IT)
*
      WINDOW = TOOLBX(FRONTWINDOW)
      CALL TOOLBX(CLOSEWINDOW,WINDOW)
*
* INITIALIZE MENU
*
      MENUHANDLE = TOOLBX(NEWMENU, 1,CHAR(7)//"OPTIONS")
      CALL TOOLBX(APPENDMENU,MENUHANDLE,
     +        CHAR(32)//"CONTROL WINDOW;DUMMY WINDOW;QUIT")
      CALL TOOLBX(INSERTMENU,MENUHANDLE,0)
      CALL TOOLBX(DRAWMENUBAR)
*
*   READ IN CONTROL_WINDOW WITH "REGULAR" CONTROLS FROM 
*   RESOURCE ID 128, 0 MEANS ALLOCATE STORAGE ON HEAP, -1
*   MEANS BRING WINDOW IN FRONT OF ALL OTHER WINDOWS
*
        CONTROL_WINDOW = TOOLBX(GETNEWDIALOG,128,0,-1)
*
*   PLACE INFORMATION IN CONTROL_WINDOW'S REFCON FIELD 
*   TO BE USED BY APPLICATION
*
      CALL INITVALUES(CONTROL_WINDOW,2)
*
*   SET UP DUMMY WINDOW TO MAKE SURE UPDATE AND ACTIVATE
*   EVENTS ARE HANDLED RIGHT
*
      RECT(1) = 40
      RECT(2) = 30
      RECT(3) = 300
      RECT(4) = 270
      DUMMYHANDLE = TOOLBX(NEWWINDOW,0,RECT,
     +      CHAR(12)//"DUMMY WINDOW",.TRUE.,4,-1,.TRUE.,0)
     
      RECT(1) = 25 ! WINDOWDRAG CONTSTRAINTS
      RECT(2) = 25
      RECT(3) = 300
      RECT(4) = 500
*
*  MAIN EVENT PROCESSING LOOP
*
      DO
        IF (TOOLBX(GETNEXTEVENT,EVENTMASK,EVENTRECORD)) THEN

          SELECT CASE (WHAT)

            CASE (MOUSEDOWN)      ! HANDLE MOUSE DOWN
              CALL DOMOUSEDOWN(WHERE,WINDOW,DUMMYHANDLE,
     1               CONTROL_WINDOW,RECT,EVENTRECORD)
     
            CASE(UPDATEEVT)     ! HANDLE UPDATE EVENT
*
*  MUST ALWAYS SET THE PORT TO THE WINDOW WHERE OUTPUT IS TO
*  OCCUR MESSAGE IS PASSED TO US IN THE EVENT RECORD AND IS A
*  POINTER TO THE WINDOW BEING UPDATED
*
    CALL TOOLBX(GETPORT,SAVEPORT)  ! SAVE THE PORT
    CALL TOOLBX(SETPORT,MESSAGE)   ! SET PORT TO UPDATE WINDOW
    CALL TOOLBX(BEGINUPDATE,MESSAGE) ! USE BEFORE UPDATE
    CALL TOOLBX(DRAWCONTROLS,MESSAGE) ! DRAW THE CONTROLS
    CALL TOOLBX(ENDUPDATE,MESSAGE)  !  USE AFTER UPDATE
    CALL TOOLBX(SETPORT,SAVEPORT)  ! RESTORE PREVIOUS PORT

            CASE(ACTIVATEEVT)    ! HANDLE ACTIVATE EVENT
              CALL TOOLBX(SETPORT,MESSAGE)
              ACTIVATE = 255  !  UNHILIGHT CONTROLS
              IF(MOD(MODIFIERS,2).EQ.1)ACTIVATE = 0 ! HILIGHT 
              CONTROL_HAN = LONG(MESSAGE+WCONTROLLIST) !1st
*
* LOOP THROUGH ALL CONTROLS IN A WINDOW
*
              WHILE(CONTROL_HAN.NE.0)
               CALL TOOLBX(HILITECONTROL,CONTROL_HAN,ACTIVATE)
               CONTROL_HAN = LONG(LONG(CONTROL_HAN)) ! NEXT
              REPEAT
              
            CASE DEFAULT
          END SELECT
        END IF
      REPEAT
      END
      SUBROUTINE DOMOUSEDOWN(WHERE,WINDOW,DUMMYWINDOW,
     1             CONTROL_WINDOW,RECT,EVENTRECORD)
*
*  THIS ROUTINE HANDLES MOUSE DOWN EVENTS
*
      IMPLICIT NONE
      INTEGER WINDOW,CONTROL_WINDOW,MOUSELOC
      INTEGER TOOLBX,SIZE
      INTEGER SAVEPORT,TTY_CT,WHICH_CTRL
      INTEGER*2 EVENTRECORD(8)    ! OVERLYING STRUCTURE
      INTEGER*2 WHERE(2),RECT(4),INVAL_RECT(4), MENUSELECTION(2)
      LOGICAL FLAG
      INTEGER QUIT, OPTIONS,CIRCLES,MENUDATA,DUMMY,DUMMYWINDOW
      PARAMETER (QUIT=3,OPTIONS=1,CIRCLES=1,DUMMY=2)
      
 include XP40-6:MacFortran:IncludeFiles:window.inc
 include XP40-6:MacFortran:IncludeFiles:menu.inc
 include XP40-6:MacFortran:IncludeFiles:control.inc
 include XP40-6:MacFortran:IncludeFiles:quickdraw.inc
*
*  MOUSE DOWN LOCATIONS
*
      INTEGER MENUBAR,SYSTEMWINDOW,CONTENTREGION,DRAGREGION
      INTEGER GROWREGION,GOAWAYREGION,NONE
      PARAMETER (MENUBAR=1,SYSTEMWINDOW=2,CONTENTREGION=3)
      PARAMETER (DRAGREGION=4,GOAWAYREGION=6,NONE=0)
      PARAMETER (GROWREGION=5)
      EQUIVALENCE (MENUDATA,MENUSELECTION)
        
      MOUSELOC = TOOLBX(FINDWINDOW,WHERE,WINDOW)

      IF (MOUSELOC=MENUBAR) THEN
        MENUDATA = TOOLBX(MENUSELECT,WHERE)
        SELECT CASE (MENUSELECTION(1))
          CASE (OPTIONS)   ! THE "OPTIONS" MENU WAS SELECTED

          SELECT CASE (MENUSELECTION(2))

            CASE (CIRCLES)
               WINDOW = CONTROL_WINDOW
            CASE (DUMMY)
               WINDOW = DUMMYWINDOW
            CASE (QUIT)
               STOP
          END SELECT

          CALL TOOLBX(SHOWWINDOW,WINDOW)
          CALL TOOLBX(SELECTWINDOW,WINDOW)
          CALL TOOLBX(HILITEMENU,0)

          CASE DEFAULT      ! JUST PLAYING WITH THE MOUSE

        END SELECT

       ELSE IF (MOUSELOC=CONTENTREGION) THEN
        CALL TOOLBX(SELECTWINDOW,WINDOW)
*
*   HANDLE MOUSEDOWN IN CONTROL
* 
        CALL TOOLBX(GETPORT,SAVEPORT)   ! SAVE CURRENT PORT
        CALL TOOLBX(SETPORT,WINDOW)     ! SET PORT TO WINDOW
        CALL TOOLBX(GLOBALTOLOCAL,WHERE)  ! TO LOCAL COORD
        CALL INCONTROL(WHERE,WINDOW)    ! HANDLE IF CTRL CLICK
        CALL TOOLBX(SETPORT,SAVEPORT) ! RESTORE PORT

       ELSE IF (MOUSELOC=DRAGREGION) THEN 
        CALL TOOLBX(DRAGWINDOW,WINDOW,WHERE,RECT)

       ELSE IF (MOUSELOC=GOAWAYREGION) THEN
        IF (TOOLBX(TRACKGOAWAY,WINDOW,WHERE))
     +     CALL TOOLBX(HIDEWINDOW,WINDOW)
      END IF
      RETURN
      END
      SUBROUTINE INCONTROL(WHERE,WINDOW)
*
*  HANDLE EVENT IF MOUSE IS DOWN IN CONTROL
*
      IMPLICIT NONE
      INTEGER*2 WHERE(2)
      INTEGER WHICH_CTRL,WINDOW,PART_NUMBER,IVALUE4,TOOLBX
      
 include XP40-6:MacFortran:IncludeFiles:control.inc
*
* DEFINE SYMBOLIC NAMES FOR CONTROL ITEMS
* NAMING CONVENTION TAKEN FROM INSIDE MACINTOSH
*
      INTEGER INBUTTON, INCHECKBOX, INUPBUTTON, INDOWNBUTTON
      INTEGER INPAGEUP, INPAGEDOWN, INTHUMB
      PARAMETER (INBUTTON=10, INCHECKBOX=11, INUPBUTTON=20)
      PARAMETER (INDOWNBUTTON=21, INPAGEUP=22, INPAGEDOWN=23)
      PARAMETER (INTHUMB=129)
      INTEGER PUSHBUTPROC,CHECKBOXPROC,RADIOBUTPROC, SCROLLBARPROC
      PARAMETER (PUSHBUTPROC=0,CHECKBOXPROC=1,RADIOBUTPROC=2)
      PARAMETER (SCROLLBARPROC=16)
      INTEGER MENUBAR,SYSTEMWINDOW,CONTENTREGION,DRAGREGION
      INTEGER GROWREGION,GOAWAYREGION
      PARAMETER (MENUBAR=1,SYSTEMWINDOW=2,CONTENTREGION=3)
      PARAMETER (DRAGREGION=4,GOAWAYREGION=6)
      PARAMETER (GROWREGION=5)

      IF(TOOLBX(FINDCONTROL,WHERE,WINDOW,WHICH_CTRL).NE.0)THEN
*
*    IS MOUSEUP IN CONTROL? IF SO HANDLE CONTROL
*
        PART_NUMBER = TOOLBX(TRACKCONTROL,WHICH_CTRL,WHERE,0)
        IF(PART_NUMBER.EQ.INBUTTON)THEN
*
*    BUTTON CONTROL DOES NOT NEED TO HAVE ITS VALUE CHANGED
*
         ELSE IF(PART_NUMBER.EQ.INCHECKBOX)THEN    
          IVALUE4 = 1 - TOOLBX(GETCTLVALUE,WHICH_CTRL)
          CALL TOOLBX(SETCTLVALUE,WHICH_CTRL,IVALUE4)
*
*   IF WE WERE HANDLING SCROLL BARS THEN CODE TO HANDLE MOUSE
*   DOWN IN SCROLL BAR PARTS WOULD GO HERE
*
        ENDIF
      ENDIF
      RETURN
      END
      SUBROUTINE INITVALUES(WINDOW,IVALUE)
*
*   INITIALIZE THE REFCON FIELD OF ALL CONTROLS IN WINDOW
*
      IMPLICIT NONE
      INTEGER WINDOW, IVALUE, CONTROL_HAN,IVAL_CTRL
      
        include XP40-6:MacFortran:IncludeFiles:window.inc
 include XP40-6:MacFortran:IncludeFiles:control.inc
*
* HANDLE TO LIST OF CONTROLS OF THIS WINDOW
*
      INTEGER WCONTROLLIST
      PARAMETER (WCONTROLLIST = Z'8C')
*
*   INITIALIZE THE WINDOW REFCON FIELD
*
      CALL TOOLBX(SETWREFCON,WINDOW,IVALUE)
      CONTROL_HAN = LONG(WINDOW+WCONTROLLIST) ! FIRST CTRL 
      IVAL_CTRL = 1
      IF(IVALUE.EQ.1)IVAL_CTRL = 129
      WHILE(CONTROL_HAN.NE.0)
        CALL TOOLBX(SETCREFCON,CONTROL_HAN,IVAL_CTRL)
        IVAL_CTRL = IVAL_CTRL + 1
*
* NEXT CONTROL IN WINDOW (LAST CONTROL IN WINDOW POINTS TO 0)
*
        CONTROL_HAN = LONG(LONG(CONTROL_HAN))
      REPEAT
      RETURN
      END


XP40-6:SoftwareDev:MacFortran:RealControl
APPLGPFR
INCLUDE XP40-6:SoftwareDev:MacFortran:control
TYPE DLOG
 ,128
CONTROL WINDOW
95 150 300 350 
Visible  GoAway
0
0
129

TYPE DITL
,129
4

button
10 20 30 58 
OK?

button 
40 20 60 99 
Cancel

checkBox
70 20 90 100 
Check

radioButton
100 20 130 120 
Radio
Link Script File
f control example apl
f :Subroutines:errmsg
f :Subroutines:toolbx
o control
l :f77 overlays:f77.rl
 

Community Search:
MacTech Search:

Software Updates via MacUpdate

OmniGraffle 6.3 - Create diagrams, flow...
OmniGraffle helps you draw beautiful diagrams, family trees, flow charts, org charts, layouts, and (mathematically speaking) any other directed or non-directed graphs. We've had people use Graffle to... Read more
PDFKey Pro 4.3.2 - Edit and print passwo...
PDFKey Pro can unlock PDF documents protected for printing and copying when you've forgotten your password. It can now also protect your PDF files with a password to prevent unauthorized access and/... Read more
Ableton Live 9.2.2 - Record music using...
Ableton Live lets you create and record music on your Mac. Use digital instruments, pre-recorded sounds, and sampled loops to arrange, produce, and perform your music like never before. Ableton Live... Read more
Macs Fan Control 1.3.1.0 - Monitor and c...
Macs Fan Control allows you to monitor and control almost any aspect of your computer's fans, with support for controlling fan speed, temperature sensors pane, menu-bar icon, and autostart with... Read more
NetShade 6.3.1 - Browse privately using...
NetShade is an anonymous proxy and VPN app+service for Mac. Unblock your Internet through NetShade's high-speed proxy and VPN servers spanning seven countries. NetShade masks your IP address as you... Read more
Dragon Dictate 4.0.7 - Premium voice-rec...
With Dragon Dictate speech recognition software, you can use your voice to create and edit text or interact with your favorite Mac applications. Far more than just speech-to-text, Dragon Dictate lets... Read more
Persecond 1.0.2 - Timelapse video made e...
Persecond is the easy, fun way to create a beautiful timelapse video. Import an image sequence from any camera, trim the length of your video, adjust the speed and playback direction, and you’re done... Read more
GIMP 2.8.14p2 - Powerful, free image edi...
GIMP is a multi-platform photo manipulation tool. GIMP is an acronym for GNU Image Manipulation Program. The GIMP is suitable for a variety of image manipulation tasks, including photo retouching,... Read more
Sandvox 2.10.2 - Easily build eye-catchi...
Sandvox is for Mac users who want to create a professional looking website quickly and easily. With Sandvox, you don't need to be a Web genius to build a stylish, feature-rich, standards-compliant... Read more
LibreOffice 5.0.1.2 - Free, open-source...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more

ReBoard: Revolutionary Keyboard (Utilit...
ReBoard: Revolutionary Keyboard 1.0 Device: iOS Universal Category: Utilities Price: $1.99, Version: 1.0 (iTunes) Description: Do everything within the keyboard without switching apps! If you are in WhatsApp, how do you schedule a... | Read more »
Tiny Empire (Games)
Tiny Empire 1.1.3 Device: iOS Universal Category: Games Price: $2.99, Version: 1.1.3 (iTunes) Description: Launch cannonballs and blow tiny orcs into thousands of pieces in this intuitive fantasy-themed puzzle shooter! Embark on an... | Read more »
Astropad Mini (Productivity)
Astropad Mini 1.0 Device: iOS iPhone Category: Productivity Price: $4.99, Version: 1.0 (iTunes) Description: *** 50% off introductory price! ​*** Get the high-end experience of a Wacom tablet at a fraction of the price with Astropad... | Read more »
Emo Chorus (Music)
Emo Chorus 1.0.0 Device: iOS Universal Category: Music Price: $1.99, Version: 1.0.0 (iTunes) Description: Realistic Choir simulator ranging from simple Chorus emulation to full ensemble Choir with 128 members. ### introductory offer... | Read more »
Forest Spirit (Games)
Forest Spirit 1.0.5 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0.5 (iTunes) Description: | Read more »
Ski Safari 2 (Games)
Ski Safari 2 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: The world's most fantastical, fun, family-friendly skiing game is back and better than ever! Play as Sven's sister Evana, share... | Read more »
Lara Croft GO (Games)
Lara Croft GO 1.0.47768 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.47768 (iTunes) Description: Lara Croft GO is a turn based puzzle-adventure set in a long-forgotten world. Explore the ruins of an ancient... | Read more »
Whispering Willows (Games)
Whispering Willows 1.23 Device: iOS Universal Category: Games Price: $4.99, Version: 1.23 (iTunes) Description: **LAUNCH SALE 50% OFF** - Whispering Willows is on sale for 50% off ($4.99) until September 9th. | Read more »
Calvino Noir (Games)
Calvino Noir 1.1 Device: iOS iPhone Category: Games Price: $3.99, Version: 1.1 (iTunes) Description: The film noir stealth game. Calvino Noir is the exploratory, sneaking adventure through the 1930s European criminal underworld.... | Read more »
Angel Sword (Games)
Angel Sword 1.0 Device: iOS Universal Category: Games Price: $6.99, Version: 1.0 (iTunes) Description: Prepare to adventure in the most epic full scale multiplayer 3D RPG for mobile! Experience amazing detailed graphics in full HD.... | Read more »

Price Scanner via MacPrices.net

Apple offering refurbished 2015 13-inch Retin...
The Apple Store is offering Apple Certified Refurbished 2015 13″ Retina MacBook Pros for up to $270 (15%) off the cost of new models. An Apple one-year warranty is included with each model, and... Read more
Apple refurbished 2015 MacBook Airs available...
The Apple Store has Apple Certified Refurbished 2015 11″ and 13″ MacBook Airs (the latest models), available for up to $180 off the cost of new models. An Apple one-year warranty is included with... Read more
21-inch iMacs on sale for up to $120 off MSRP
B&H Photo has 21″ iMacs on sale for up to $120 off MSRP including free shipping plus NY sales tax only: - 21″ 1.4GHz iMac: $999.99 $100 off - 21″ 2.7GHz iMac: $1199.99 $100 off - 21″ 2.9GHz iMac... Read more
5K iMacs on sale for up to $150 off MSRP, fre...
B&H Photo has the 27″ 3.3GHz 5K iMac on sale for $1899.99 including free shipping plus NY tax only. Their price is $100 off MSRP. They have the 27″ 3.5GHz 5K iMac on sale for $2149.99 $2199.99, $... Read more
1.4GHz Mac mini, refurbished, available for $...
The Apple Store has Apple Certified Refurbished 1.4GHz Mac minis available for $419. Apple’s one-year warranty is included, and shipping is free. Their price is $80 off MSRP, and it’s the lowest... Read more
iPad Air 2 on sale for up to $100 off MSRP
Best Buy has iPad Air 2s on sale for up to $100 off MSRP on their online store for a limited time. Choose free shipping or free local store pickup (if available). Sale prices available for online... Read more
MacBook Airs on sale for $100 off MSRP
Best Buy has MacBook Airs on sale for $100 off MSRP on their online store. Choose free shipping or free local store pickup (if available). Sale prices for online orders only, in-store prices may vary... Read more
Big Grips Lift Handle For iPad Air and iPad A...
KEM Ventures, Inc. which pioneered the extra-large, super-protective iPad case market with the introduction of Big Grips Frame and Stand in 2011, is launching Big Grips Lift featuring a new super-... Read more
Samsung Launches Galaxy Tab S2, Its Most Powe...
Samsung Electronics America, Inc. has announced the U.S. release of the Galaxy Tab S2, its thinnest, lightest, ultra-fast tablet. Blending form and function, elegant design and multitasking power,... Read more
Tablet Screen Sizes Expanding as iPad Pro App...
Larger screen sizes are gaining favor as the tablet transforms into a productivity device, with shipments growing 185 percent year-over-year in 2015. According to a new Strategy Analytics’ Tablet... Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Desktop Analyst - KDS Staffing (Unit...
…field and consistent professional recruiting achievement. Job Description: Title: Apple Desktop AnalystPosition Type: Full-time PermanentLocation: White Plains, NYHot Read more
*Apple* Systems Engineer (Mclean, VA and NYC...
Title: Apple Systems Engineer (Mclean, VA and NYC) Location: United States-New York-New York-200 Park Ave (22005) Other Locations: United States-Virginia-Vienna-Towers Read more
*Apple* Systems Engineer (Mclean, VA and NYC...
…Assist in providing strategic direction and technical leadership within the Apple portfolio, including desktops, laptops, and printing environment. This person will Read more
*Apple* Subject Matter Expert - Experis (Uni...
We are seeking an Apple Subject Matter Expert to assist in developing the architecture, support and services for integration of Apple devices into the company's Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.