TweetFollow Us on Twitter

Menu Management
Volume Number:9
Issue Number:2
Column Tag:Getting Started

Related Info: Menu Manager Resource Manager

On the Menu for Today

How does the Macintosh Menu Manager work?

By Dave Mark, MacTech Magazine Regular Contributing Author

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

In last month’s column, we expanded our event-handling repertoire to include activate, update, and suspend/resume events. By now, you should feel pretty comfortable with the Event Manager. If you haven’t already, put down this column and go read the Event Manager chapters in Inside Macintosh, Volumes I and VI.

In this month’s column, we’re going to take a look at the Menu Manager, the part of the Toolbox responsible for your program’s menus.

The Pull-Down Menu

Almost every single Macintosh program comes complete with its own menu bar, the strip of menu titles along the top of your Mac’s main screen. The menu bar contains one menu title for each of your program’s current pull-down menus. Figure 1 shows the Finder’s menu bar with the File menu pulled down.

Figure 1. A menu bar with a pull-down menu exposed.

A proper menu bar always features at least three menus, , File, and Edit. When a menu is pulled-down, its menu items will be drawn. In addition to the item’s name, a menu item may feature an icon, as well as a command-key equivalent. The command-key equivalent, when typed by the user, simulates the selection of the equivalenced menu item. For example, in the menu in Figure 1, the command-key equivalent W will cause the Close Window item to be selected from the File menu.

Items may be dimmed, or disabled, which prevents the user from selecting them. If an item is disabled, it is drawn in gray. A normal item is said to be enabled.

You may have noticed that some menu items are drawn followed by an ellipsis, a sequence of three dots (...). The ellipsis tells the user that this item will cause a dialog box to appear, prompting the user for further information. We’ll get to dialog boxes in a later column.

Working With the Menu Manager

The Menu Manager consists of a series of routines designed to work with two resource types, MBAR and MENU. The MBAR resource links together a series of MENU resources to form a menu bar. A MENU resource is used to completely specify a menu, including all the menus items and any associated icons and command-key equivalents. Here’s a quick tour through the main Menu Manager routines.

Once you’ve built your MBAR and MENU resources (you’ll see how in a bit), you’re ready to start programming. You’ll start off by creating a menu initialization routine. In it, you’ll call GetNewMBar(), which builds a menu list, based on the MENUs specified in an MBAR resource. A menu list is the data structure the Menu Manager bases a menu bar on. Once the menu list is built, pass it to SetMenuBar() to make it the current menu bar. Note that you can have more than one menu bar, but only one current menu bar.

Once you’ve specified a current menu bar, draw the menu bar by calling DrawMenuBar(). Now you’re ready to work with your individual menus.

Modifying the Menu Bar

There will be times when the menu bar described in your MBAR resource won’t be enough. For example, you might have a menu that appears only if the user has color turned on, or when a certain type of window is open. You can add a menu to or delete a menu from the menu bar. To add a menu to the menu bar, call GetMenu() to load a new MENU resource into memory, into the list of available menus (but not into the current menu bar). GetMenu() returns a MenuHandle which you can pass to InsertMenu(). InsertMenu() inserts the specified menu into the current menu bar. To delete a menu from the menu bar, call DeleteMenu().

Another routine you might find useful is GetMHandle(), which returns a MenuHandle to a menu already loaded into memory. Basically, you’ll use GetMenu() to get a handle to a menu that’s never been loaded, and GetMHandle() to get a handle to a previously loaded menu. Use InsertMenu() to add a loaded menu into the current menu bar. Remember, whenever you change the menu bar, call DrawMenuBar() to bring your changes to life. You only need to call DrawMenuBar() when you change the current menu bar, not when you change a menu’s items.

Changing a Menu Item’s Appearance

The Menu Manager gives you a set of routines you can use to customize your menus. For example, the routines EnableItem() and DisableItem() allow you to enable or disable a menu item. You can use the routine AddResMenu() to add all the resources of a specific type as menu items. There are two specific times when this comes in handy. To add all the fonts to a menu, pass ‘FONT’ to AddResMenu(). To add all the standard apple menu items to the apple menu, pass ‘DRVR’ to AddResMenu(). Why ‘DRVR’? Prior to System 7, all the items in the apple menu were desk accessories, which have a resource type of ‘DRVR’. Even though System 7 allows you to add more than DA’s to your apple menu, AddResMenu() still works properly, as you’ll see by this month’s program.

You can use SetItem() to change the name of a menu item. You can use GetItem() to retrieve an item’s name. CheckItem() lets you place or remove a check mark from an item and SetItemMark() lets you place or remove any character from the system font next to an item. GetItemMark() retrieves an item’s mark.

SetItemIcon() and GetItemIcon() set and get the resource ID of any icon associated with an item. For some reason, the resource ID returned by GetItemIcon() is 256 less than the icon’s actual resource ID. This means that your icon’s resource ID will range from 257 to 511.

SetItemStyle() and GetItemStyle() are used to set and get the style of an item’s name. We’ll make use of these function’s in next month’s program.

Detecting a Menu Selection

There are two ways a user can select from a menu. They can click the mouse in the menu bar or they can type a command-key equivalent. You’ll detect a mouse click in the menu bar by detecting a mouseDown event that occurred inMenuBar. If this happens, you’ll call a routine called MenuSelect(). MenuSelect() tracks your mouse, pulling down menus, highlighting items, and, if necessary, selecting an item from a menu. MenuSelect() returns a value that indicates the menu and item that was selected.

If a keyDown or autoKey event occurs, you’ll check to see if the command-key was down when the event occurred. If so, you’ll call a routine called MenuKey() which translates the key to a value that indicates the menu and item that was selected.

Whether the menu/item was selected via a keyDown or a mouseDown in the menu bar, it will be translated into a menu/item value. You’ll pass this menu/item value on to your own routine which processes the menu selection. Once you process the menu selection, call HiliteMenu() to uninvert the menu’s title, which was left inverted by MenuSelect() or MenuKey().

MenuMaster

OK, that’s about it for Menu Manager routines. There are a few that we haven’t discussed and you should definitely read the Menu Manager chapter in Inside Macintosh, Volume I. For now, let’s get into this month’s program, MenuMaster.

Create a folder named MenuMaster in your development folder. Now go into ResEdit and create a new resource file named MenuMaster.Π.rsrc in the MenuMaster folder. Select Create New Resource from the Resource menu and create a new MBAR resource. When the MBAR window appears, click on the row of *’s (Figure 2) and type K to create a new MENU field. When the new field appears, type in the MENU id 128.

Figure 2. Click on the *’s and type K to add a MENU to the MBAR.

When the second row of *’s appears, click on it and type K to create a second MENU field. Repeat this process till your MBAR looks like the one in Figure 3.

Close the MBAR window, and close the MBAR picker window. Next, select Create New Resource from the Resource menu and create a MENU resource. When the MENU editing window appears, click on the • radio button to create an apple menu. Hit a carriage return and type in the text About MenuMaster... followed by another carriage return. Now click on the separator line radio button to insert a separator line after the About MenuMaster... item. Since separator lines are never enabled, they’ll never be chosen by the user. Your menu should look like the one shown in Figure 4.

Figure 3. The filled out MBAR resource with four MENU resource ids.

Figure 4. Specifications for MENU 128.

Close the editing window and type K to create a new MENU resource. This time, instead of clicking on the • radio button, type the word File in the Title field and hit a carriage return. Next type the word Quit and type the letter Q in the Cmd-Key field that appears. You’ve just made Q a command-key equivalent to the File menu’s Quit item. Your menu should look like the one shown in Figure 5.

Figure 5. Specifications for MENU 129.

Close the editing window and create another MENU, using the MENU shown in Figure 6 as a guide. Be sure to add the separator line after the Undo item, and to type in the four command-key equivalents.

Figure 6. Specifications for MENU 130.

Close the editing window and create yet another MENU, according to the specifications shown in Figure 7. Be sure to include the three separator lines. If you forget one, you can add one at the end of the menu, then click and drag it to its proper position. Notice that the item labeled Enable Previous Item has been disabled. Do this by making sure the Enabled check box is unchecked for that item only.

Figure 7. Specifications for MENU 131.

Finally, create one more MENU. Use the title Extra Menu and add the item Delete This Menu (Figure 8).

Figure 8. Specifications for MENU 132.

Next, click on the item Delete This Menu and select Choose Icon... from the MENU menu. You’re going to attach an icon to the menu item. When the dialog box appears, click on the Small Icons radio button, then click the New button.

Figure 9. The Choose Icon... dialog box.

When the SICN editing window appears, go to town. Create whatever kind of small icon your heart desires. Get creative. Figure 10 shows my SICN, lifted from the Macintosh Programming Primer.

Figure 10. A SICN with a resource ID of 257.

If you preferred, you could use an ICON or a reduced ICON resource instead. Personally, I prefer SICNs or none at all. Once you are done editing your SICN, close the SICN editing window. You can get a preview of the menu by clicking on the prototype that appears on the right end of the menu bar. Your SICN should be in place. If not, be sure your SICN has a resource ID of 257. Icons attached to menu items must have an ID between 257 and 511.

Once you are happy with your MENU, close the MENU editing window. You may have noticed that you’ve created MENUs with resource IDs 128 through 132, while your MBAR only includes MENUs with IDs from 128 to 131. We’ll add this extra menu to our menu bar from inside our program.

Well, that’s about it for resources. Quit ResEdit, making sure you Save your changes.

Creating the MenuMaster Project

Launch THINK C and create a new project called MenuMaster.Π in the MenuMaster folder. Add MacTraps to the project, then select New from the File menu to create a new source code window. Type in the following source code:

/* 1 */

#include <Values.h>

#define kBaseResID 128
#define kMoveToFront (WindowPtr)-1L
#define kSleep   MAXLONG

#define kLastMenu0

#define mApple   kBaseResID
#define iAbout   1

#define mFile    kBaseResID+1
#define iQuit    1

#define mOptions kBaseResID+3
#define iChangeName1
#define iDisableMe 3
#define iEnablePrev4
#define iAddExtraMenu6
#define iAppendItem8
#define iAddedItem 9

#define kUnchangedName    "\pChange My Name"
#define kChangedName "\pChange Me Back Again"

#define mExtraMenu kBaseResID+4
#define iDeleteMenu1


/*************/
/*  Globals  */
/*************/

Boolean gDone;
Boolean gItemNameChanged = false;


/***************/
/*  Functions  */
/***************/

void  ToolBoxInit( void );
void  WindowInit( void );
void  MenuBarInit( void );
void  EventLoop( void );
void  DoEvent( EventRecord *eventPtr );
void  HandleMouseDown( EventRecord *eventPtr );
void  HandleMenuChoice( long menuChoice );
void  HandleAppleChoice( short item );
void  HandleFileChoice( short item );
void  HandleOptionsChoice( short item );
void  HandleExtraMenuChoice( short item );

/*************************** main *********/

void  main( void )
{
 ToolBoxInit();
 MenuBarInit();
 
 EventLoop();
}

/*************************** ToolBoxInit */

void  ToolBoxInit( void )
{
 InitGraf( &thePort );
 InitFonts();
 InitWindows();
 InitMenus();
 TEInit();
 InitDialogs( nil );
 InitCursor();
}

/****************** MenuBarInit ************/

void  MenuBarInit( void )
{
 Handle menuBar;
 MenuHandle menu;
 
 menuBar = GetNewMBar( kBaseResID );
 SetMenuBar( menuBar );

 menu = GetMHandle( mApple );
 AddResMenu( menu, 'DRVR' );
 
 DrawMenuBar();
}

/************************* EventLoop *********/

void  EventLoop( void )
{
 EventRecordevent;
 
 gDone = false;
 while ( gDone == false )
 {
 if ( WaitNextEvent( everyEvent, &event, kSleep, nil ) )
 DoEvent( &event );
 }
}

/************************** DoEvent */

void  DoEvent( EventRecord *eventPtr )
{
 char   theChar;
 
 switch ( eventPtr->what )
 {
 case mouseDown: 
 HandleMouseDown( eventPtr );
 break;
 case keyDown:
 case autoKey:
 theChar = eventPtr->message & charCodeMask;
 if ( (eventPtr->modifiers & cmdKey) != 0 ) 
 HandleMenuChoice( MenuKey( theChar ) );
 break;
 }
}

/********************* HandleMouseDown */

void  HandleMouseDown( EventRecord *eventPtr )
{
 WindowPtrwindow;
 short  thePart;
 long   menuChoice;
 
 thePart = FindWindow( eventPtr->where, &window );
 
 switch ( thePart )
 {
 case inMenuBar:
 menuChoice = MenuSelect( eventPtr->where );
 HandleMenuChoice( menuChoice );
 break;
 case inSysWindow : 
 SystemClick( eventPtr, window );
 break;
 }
}

/****************** HandleMenuChoice *********/

void  HandleMenuChoice( long menuChoice )
{
 short  menu;
 short  item;
 
 if ( menuChoice != 0 )
 {
 menu = HiWord( menuChoice );
 item = LoWord( menuChoice );
 
 switch ( menu )
 {
 case mApple:
 HandleAppleChoice( item );
 break;
 case mFile:
 HandleFileChoice( item );
 break;
 case mOptions:
 HandleOptionsChoice( item );
 break;
 case mExtraMenu:
 HandleExtraMenuChoice( item );
 break;
 }
 HiliteMenu( 0 );
 }
}

/****************** HandleAppleChoice ************/

void  HandleAppleChoice( short item )
{
 MenuHandle appleMenu;
 Str255 accName;
 short  accNumber;
 
 switch ( item )
 {
 case iAbout:
 SysBeep( 20 );
 break;
 default:
 appleMenu = GetMHandle( mApple );
 GetItem( appleMenu, item, accName );
 accNumber = OpenDeskAcc( accName );
 break;
 }
}

/***************** HandleFileChoice ************/

void  HandleFileChoice( short item )
{
 switch ( item )
 {
 case iQuit :
 gDone = true;
 break;
 }
}

/****************** HandleOptionsChoice ***************/

void  HandleOptionsChoice( short item )
{
 MenuHandle menu;
 
 menu = GetMHandle( mOptions );
 
 switch ( item )
 {
 case iChangeName:
 if ( gItemNameChanged )
 SetItem( menu, iChangeName, kUnchangedName );
 else
 SetItem( menu, iChangeName, kChangedName );
 gItemNameChanged = ! gItemNameChanged;
 break;
 case iDisableMe:
 DisableItem( menu, iDisableMe );
 EnableItem( menu, iEnablePrev );
 break;
 case iEnablePrev:
 DisableItem( menu, iEnablePrev );
 EnableItem( menu, iDisableMe );
 break;
 case iAddExtraMenu:
 DisableItem( menu, iAddExtraMenu );
 menu = GetMenu( mExtraMenu );
 InsertMenu( menu, kLastMenu );
 DrawMenuBar();
 break;
 case iAppendItem:
 AppendMenu( menu, "\pCan't Delete Me..." );
 DisableItem( menu, iAppendItem );
 break;
 case iAddedItem:
 SysBeep( 20 );
 break;
 }
}

/****************** HandleExtraMenuChoice *************/

void  HandleExtraMenuChoice( short item )
{
 MenuHandle menu;
 
 switch ( item )
 {
 case iDeleteMenu:
 menu = GetMHandle( mOptions );
 EnableItem( menu, iAddExtraMenu );
 
 DeleteMenu( mExtraMenu );
 DrawMenuBar();
 break;
 }
}

Once your code is typed in, save the source code file as MenuMaster.c, then Add the file to the project. Run the project by selecting Run from the Project menu. When the menu bar appears, select Change My Name from the Options menu. If you click on the Options menu again, you’ll see that the item has been changed to Change Me Back Again. Select the item again and it will change back to its original name.

Now select Disable Me from the Options menu. If you click on the Options menu again, you’ll see that the item has been disabled and the next item, which was disabled, is now enabled. Select Enable Previous Item and it will be disabled again, while the Disable Me item is reenabled.

Next, select Add Extra Menu from the Options menu. A new menu will appear in the menu bar, named Extra Menu. In addition, the Add Extra Menu item is disabled. If you click on Extra Menu, you’ll notice that the SICN appears to the left of the Delete This Menu item. Select Delete This Menu and the menu will disappear, and Add Extra Menu will be reenabled.

Next, select Append Item from the Options menu. A new item will appear in the Options menu with the name Can’t Delete Me.... As its name implies, once you’ve added an item to a menu, you can’t delete it. If you select Can’t Delete Me..., MenuMaster will beep once.

Finally, type Q to exit the program. Q is the command-key equivalent for the File menu’s Quit item.

Source Code Highlights

Much of MenuMaster’s code should be familiar to you. That being the case, I’m going to stick to the highlights, focusing on the new stuff.

For starters, notice the way the #defines have been set up for the menus and menu items. In general, you’ll create a #define for each menu and item, starting the menu #defines with the letter ‘m’ and the item #defines with the letter ‘i’.

/* 2 */

#define mApple   kBaseResID
#define iAbout   1

#define mFile    kBaseResID+1
#define iQuit    1

#define mOptions kBaseResID+3
#define iChangeName1
#define iDisableMe 3
#define iEnablePrev4
#define iAddExtraMenu6
#define iAppendItem8
#define iAddedItem 9

The global gItemNameChanged is a Boolean flag, used to tell whether the first Options item has been changed or not.

/* 3 */

Boolean gItemNameChanged = false;

Notice that main() calls a new routine, MenuBarInit(), which handles the menu initialization.

/* 4 */

/************************ main *********/

void  main( void )
{
 ToolBoxInit();
 MenuBarInit();
 
 EventLoop();
}

MenuBarInit() loads the MBAR resource and makes the resulting menu bar the current menu bar.

/* 5 */

/****************** MenuBarInit **********/

void  MenuBarInit( void )
{
 Handle menuBar;
 MenuHandle menu;
 
 menuBar = GetNewMBar( kBaseResID );
 SetMenuBar( menuBar );

Next, AddResMenu() is called to add the apple menu items to the • menu. Notice that GetMHandle() was used to retrieve the menu handle, because the MENU resource was already loaded into memory as part of the MBAR.

/* 6 */

 menu = GetMHandle( mApple );
 AddResMenu( menu, 'DRVR' );

Finally, the menu bar is drawn with DrawMenuBar().

/* 7 */

 DrawMenuBar();
}

The next big change is in the DoEvent() code.

/* 8 */

/************************* DoEvent  */

void  DoEvent( EventRecord *eventPtr )
{
 char   theChar;
 
 switch ( eventPtr->what )
 {
 case mouseDown: 
 HandleMouseDown( eventPtr );
 break;

The charCodeMask is used to retrieve the character embedded in the keyDown or autoKey event. If the command-key was held down, the character is passed to MenuKey() which translates it into a menu and item code. This code is passed on to HandleMenuChoice().

/* 9 */

 case keyDown:
 case autoKey:
 theChar = eventPtr->message & charCodeMask;
 if ( (eventPtr->modifiers & cmdKey) != 0 ) 
 HandleMenuChoice( MenuKey( theChar ) );
 break;
 }
}

HandleMouseDown() also contains a change.

/* 10 */

/************************ HandleMouseDown */

void  HandleMouseDown( EventRecord *eventPtr )
{
 WindowPtrwindow;
 short  thePart;
 long   menuChoice;
 
 thePart = FindWindow( eventPtr->where, &window );
 
 switch ( thePart )
 {

If the mouseDown was in the menu bar, the event is passed on to MenuSelect() which also returns a menu and item code. The code is again passed on to HandleMenuChoice().

/* 11 */

 case inMenuBar:
 menuChoice = MenuSelect( eventPtr->where );
 HandleMenuChoice( menuChoice );
 break;
 case inSysWindow : 
 SystemClick( eventPtr, window );
 break;
 }
}

HandleMenuChoice() pulls the menu and item out of the menu/item code.

/* 12 */

/****************** HandleMenuChoice **************/

void  HandleMenuChoice( long menuChoice )
{
 short  menu;
 short  item;
 
 if ( menuChoice != 0 )
 {
 menu = HiWord( menuChoice );
 item = LoWord( menuChoice );

menu is used to decide which menu handling routine to call.


/* 13 */

 switch ( menu )
 {
 case mApple:
 HandleAppleChoice( item );
 break;
 case mFile:
 HandleFileChoice( item );
 break;
 case mOptions:
 HandleOptionsChoice( item );
 break;
 case mExtraMenu:
 HandleExtraMenuChoice( item );
 break;
 }

Once the handling routine returns, HiliteMenu() is called to unhighlight the selected menu.

/* 14 */

 HiliteMenu( 0 );
 }
}

/****************** HandleAppleChoice *************/

void  HandleAppleChoice( short item )
{
 MenuHandle appleMenu;
 Str255 accName;
 short  accNumber;
 
 switch ( item )
 {

HandleAppleChoice() handles the About MenuMaster... item by beeping once.

/* 15 */

 case iAbout:
 SysBeep( 20 );
 break;

If any other item is selected, OpenDeskAcc() is called to launch the appropriate item. Under System 7, the item might not be a desk accessory.

/* 16 */

 default:
 appleMenu = GetMHandle( mApple );
 GetItem( appleMenu, item, accName );
 accNumber = OpenDeskAcc( accName );
 break;
 }
}

HandleFileChoice() sets gDone to true, which will cause the program to exit.

/* 17 */

/****************** HandleFileChoice ***********/

void  HandleFileChoice( short item )
{
 switch ( item )
 {
 case iQuit :
 gDone = true;
 break;
 }
}

HandleOptionsChoice() takes the appropriate action, depending on the action selected. Notice that GetMHandle() is used to retrieve the Options menu handle.

/* 18 */

/****************** HandleOptionsChoice **********/

void  HandleOptionsChoice( short item )
{
 MenuHandle menu;
 
 menu = GetMHandle( mOptions );
 
 switch ( item )
 {
 case iChangeName:
 if ( gItemNameChanged )
 SetItem( menu, iChangeName, kUnchangedName );
 else
 SetItem( menu, iChangeName, kChangedName );
 gItemNameChanged = ! gItemNameChanged;
 break;
 case iDisableMe:
 DisableItem( menu, iDisableMe );
 EnableItem( menu, iEnablePrev );
 break;
 case iEnablePrev:
 DisableItem( menu, iEnablePrev );
 EnableItem( menu, iDisableMe );
 break;
 case iAddExtraMenu:
 DisableItem( menu, iAddExtraMenu );
 menu = GetMenu( mExtraMenu );
 InsertMenu( menu, kLastMenu );
 DrawMenuBar();
 break;
 case iAppendItem:
 AppendMenu( menu, "\pCan't Delete Me..." );
 DisableItem( menu, iAppendItem );
 break;
 case iAddedItem:
 SysBeep( 20 );
 break;
 }
}

Finally, HandleExtraMenuChoice() handles a single item.


/* 19 */

/****************** HandleExtraMenuChoice ********/

void  HandleExtraMenuChoice( short item )
{
 MenuHandle menu;
 
 switch ( item )
 {

When Delete This Menu is selected, the Add Extra Menu item is reenabled on the Options menu.

/* 20 */

 case iDeleteMenu:
 menu = GetMHandle( mOptions );
 EnableItem( menu, iAddExtraMenu );

Next, the Extra Menu menu is deleted and the menu bar is redrawn.

/* 21 */
 DeleteMenu( mExtraMenu );
 DrawMenuBar();
 break;
 }
}

Till Next Time

Well, that’s about it for this month. Next month, we’ll dig a little further into the Menu Manager. Till then, go read Inside Macintosh, and save me a slice of pizza...

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Boom 2 1.0.1 - System-wide pro audio app...
Boom 2 is a system-wide volume booster and equalizer app that is designed especially for OS X 10.10 Yosemite. It comes with a smart interface, self-calibrates itself according to your Mac, offers... Read more
Apple Security Update 2015-001 - For OS...
Apple Security Update 2015-001 is recommended for all users and improves the security of OS X. For detailed information about the security content of this update, please visit: http://support.apple.... Read more
Drive Genius 4.0.1 - Powerful system uti...
Drive Genius 4 gives you faster performance from your Mac while also protecting it. The award-winning and improved DrivePulse feature alerts you to hard drive issues before they become major problems... Read more
Yosemite Cache Cleaner 9.0.3 - Clear cac...
Yosemite Cache Cleaner is an award-winning general purpose tool for OS X. YCC makes system maintenance simple with an easy point-and-click interface to many OS X functions. Novice and expert users... Read more
xScope 4.1.1 - Onscreen graphic measurem...
xScope is powerful set of tools that are ideal for measuring, inspecting, and testing on-screen graphics and layouts. Its tools float above your desktop windows and can be accessed via a toolbar,... Read more
OS X Yosemite 10.10.2 - Apple's lat...
OS X Yosemite is Apple's newest operating system for Mac. An elegant design that feels entirely fresh, yet inherently familiar. The apps you use every day, enhanced with new features. And a... Read more
Apple iOS 8.1.3 - The latest version of...
The latest version of iOS can be downloaded through iTunes. Apple iOS 8 comes with big updates to apps you use every day, like Messages and Photos. A whole new way to share content with your family.... Read more
SpamSieve 2.9.19 - Robust spam filter fo...
SpamSieve is a robust spam filter for major email clients that uses powerful Bayesian spam filtering. SpamSieve understands what your spam looks like in order to block it all, but also learns what... Read more
RapidWeaver 6.0.5 - Create template-base...
RapidWeaver is a next-generation Web design application to help you easily create professional-looking Web sites in minutes. No knowledge of complex code is required, RapidWeaver will take care of... Read more
Duet 1.2.2 - Use your iPad as an externa...
Duet is the first app that allows you to use your iDevice as an extra display for your Mac using the Lightning or 30-pin cable. Note: This app requires a $14.99 iOS companion app. Version 1.2.2:... Read more

Storm & Skye – Magical Adventure Sto...
Storm & Skye – Magical Adventure Story For Kids Review By Amy Solomon on January 28th, 2015 Our Rating: iPhone App - Designed for the iPhone, compatible with the iPad The first book in the Storm & Skye series includes... | Read more »
New WOTA: U-Boat Compass ‘Wets’ Your App...
New WOTA: U-Boat Compass ‘Wets’ Your Appetite for WOTA: Wolves of the Atlantic. Posted by Jessica Fisher on January 27th, 2015 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Warship Solitaire Review
Warship Solitaire Review By Nadia Oxford on January 27th, 2015 Our Rating: :: A WAR OF NUMBERSUniversal App - Designed for iPhone and iPad Warship Solitaire might lack frills and looks, but it offers some thought provoking... | Read more »
Keep Track of Your Hectic Work Schedule...
Keep Track of Your Hectic Work Schedule With Shifts Posted by Jessica Fisher on January 27th, 2015 [ permalink ] iPhone App - Designed for the iPhone, compatible with the iPad | Read more »
All Star Quarterback Review
All Star Quarterback Review By Campbell Bird on January 27th, 2015 Our Rating: :: PLAY YOUR PARTUniversal App - Designed for iPhone and iPad Train your way to the Super Bowl in this free-to-play sports management game.   | Read more »
Sentinel 4: Dark Star Adds New Campaign...
Sentinel 4: Dark Star Adds New Campaign and More Posted by Ellis Spice on January 27th, 2015 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Wheel & Deal Review
Wheel & Deal Review By Tre Lawrence on January 27th, 2015 Our Rating: :: SIMPLE FUNUniversal App - Designed for iPhone and iPad A simple arcade shooter that has a retro feel.   | Read more »
Join the NAVY in a Big New Update for WW...
Join the NAVY in a Big New Update for WW2: Sandbox. Strategy & Tactics Posted by Jessica Fisher on January 27th, 2015 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Earthworm Alchemy Review
Earthworm Alchemy Review By Campbell Bird on January 27th, 2015 Our Rating: :: FEED THE WORMUniversal App - Designed for iPhone and iPad Feed this funny looking worm and dodge bombs in this charming, free-to-play arcade game.   | Read more »
Graphic Novel App netwars – The Butterfl...
Graphic Novel App netwars – The Butterfly Attack has Received Some New Episodes Posted by Jessica Fisher on January 27th, 2015 [ permalink ] | Read more »

Price Scanner via MacPrices.net

New Good Management Suite Simplifies Enterpri...
Good Technology has announced the availability of the Good Management Suite, a comprehensive cross-platform solution for organizations getting started with mobile business initiatives. Built on the... Read more
15-inch 2.0GHz Retina MacBook Pro (refurbishe...
The Apple Store has Apple Certified Refurbished previous-generation 15″ 2.0GHz Retina MacBook Pros available for $1489 including free shipping plus Apple’s standard one-year warranty. Their price is... Read more
15-inch 2.5GHz Retina MacBook Pro on sale for...
Amazon has the 15″ 2.5GHz Retina MacBook Pro on sale for $2319.99 including free shipping. Their price is $180 off MSRP, and it’s the lowest price available for this model from any reseller. Read more
iPad Turns Five – The ”Book Mystique
Five years ago this week, the late Steve Jobs took the stage at an Apple special press event to unveil the first Apple iPad — a slab-shaped, hand-holdable device that was to shake the personal... Read more
Sale! 15-inch Retina MacBook Pros for up to $...
B&H Photo has the new 2014 15″ Retina MacBook Pros on sale for $150 off MSRP for a limited time. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.2GHz Retina MacBook Pro: $1889.99... Read more
Apple refurbished Mac minis for up to $150 of...
The Apple Store has restocked Apple Certified Refurbished 2014 Mac minis, with models available starting at $419. Apple’s one-year warranty is included with each mini, and shipping is free: - 1.4GHz... Read more
Apple Releases New Tranche Of OS Updates For...
Apple has released incremental bugfix and security updates for its most recent Mac and iOS versions. OS X Yosemite 10.10.2 Update Apple says this update includes the following improvements: Resolves... Read more
Samsung To Be Main Supplier Of A9 Chips For i...
Korea’s Maeil Business Newspaper reports that Samsung has beat out its chipmaking rivals, Taiwan’s Qualcomm and TSMC, as supplier of chipsets for the next generations of both its own Galaxy S6 and... Read more
Save up to $340 on iMacs with Apple Certified...
The Apple Store has Apple Certified Refurbished iMacs available for up to $340 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free. These are the best prices on... Read more
AppleCare Protection Plans on sale for up to...
B&H Photo has 3-Year AppleCare Warranties on sale for up to $105 off MSRP including free shipping plus NY sales tax only: - Mac Laptops 15″ and Above: $244 $105 off MSRP - Mac Laptops 13″ and... Read more

Jobs Board

*Apple* Systems Engineer - Pre Sales, Educat...
…is responsible for proactively providing technical expertise to drive sales of Apple solutions into assigned accounts. The SE architects, validates, and assists in Read more
*Apple* Solutions Consultant - Retail Sales...
As an ambassador of the Apple brand, the ASC is accountable for driving sales performance by: Connecting with customers. Discovering customers' needs and values. Showing Read more
*Apple* Solutions Consultant - Retail Sales...
As an ambassador of the Apple brand, the ASC is accountable for driving sales performance by: Connecting with customers. Discovering customers' needs and values. Showing Read more
*Apple* Tree Children's Center is hirin...
Apple Tree Learning Center is Hiring Preschool Teachers! Phoenix Childrens Academy is a national leader in the early childhood education industry and we are currently Read more
*Apple* Solutions Consultant - Retail Sales...
**Job Summary** As an Apple Solutions Consultant (ASC) you are the link between our customers and our products. Your role is to drive the Apple business in a retail Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.