TweetFollow Us on Twitter

Rolling MDEF
Volume Number:10
Issue Number:6
Column Tag:Getting Started

Related Info: Menu Manager Custom Menus

Rolling Your Own MDEFs

Help your menus get the picture

By Dave Mark, MacTech Magazine Regular Contributing Author

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

This month’s program is a departure from our traditional applications. Though we do build an application, it only serves as a tester for our MENU definition procedure. When your application includes a menu bar made up of a series of MENU resources, you’ll normally take advantage of the standard menu definition procedure (better known as an MDEF) provided by the Menu Manager.

Every time you call MenuSelect() (in response to a command-key equivalent or to a click in the menu bar), the Menu Manager takes over, drawing and erasing menus in response to your mouse clicks. Every menu specifies an MDEF resource (we’ll get to that when we create the tester’s MENU resources later in the column). Each time a menu is drawn, the MDEF specified by the menu is called to draw the menu’s contents and to highlight the appropriate item as the mouse moves.

This month, we’re going to write our own MDEF, compile it into an MDEF resource, then write a test program to test the MDEF. Rather than rewrite the standard MDEF, our MDEF will create a menu of PICT resources, as opposed to text.

This MDEF is actually a rewrite of the MDEF from Volume II of the Mac Primer. Besides being a little long in the tooth (i.e., old and funky), the original broke some Toolbox rules that caused the Thought Police to pay me a visit...

Creating the MDEF Project

Create a folder called MDEF Files in your Development folder. Launch THINK C and create a new project named MDEF.Π. Add MacTraps to the project. Next, create a new source code file, save it as MDEF.c, and add it to the project.

Type in this source code in the MDEF.c window:


/* 1 */
#define kTopMargin 1
#define kLeftMargin2

void  DoSizeMessage( MenuHandle menu, Rect *menuRectPtr );
void  DoDrawMessage( MenuHandle menu, Rect *menuRectPtr );
void  DoChooseMessage( MenuHandle menu, Rect *menuRectPtr,
  Point hitPt, short *whichItemPtr );
void  InvertItem( short itemNumber, short itemHeight, 
  Rect *menuRectPtr );
void  DrawCenteredPict( PicHandle pic, Rect *rectPtr );
void  CalcitemHeightAndWidth( short basePICTid, short numPICTs,
 short *widthPtr, short *heightPtr );
void  GetNumPICTs( MenuHandle menu, short *baseIDPtr,
 short *numPICTsPtr );

main


/* 2 */
pascal void main( short message,
 MenuHandle menu,
 Rect *menuRectPtr,
 Point hitPt,
 short *whichItemPtr )
{
 switch( message )
 {
 case mDrawMsg:
 DoDrawMessage( menu, menuRectPtr );
 break;
 case mChooseMsg:
 DoChooseMessage( menu,menuRectPtr,hitPt,whichItemPtr );
 break;
 case mSizeMsg:
 DoSizeMessage( menu, menuRectPtr );
 break;
 }
}

DoSizeMessage


/* 3 */
void  DoSizeMessage( MenuHandle menu,
 Rect *menuRectPtr )
{
 short  basePICTid, numPICTs, maxPICTWidth, maxPICTHeight;
 
 GetNumPICTs( menu, &basePICTid, &numPICTs );
 CalcitemHeightAndWidth( basePICTid, numPICTs, &maxPICTWidth,
   &maxPICTHeight );
 
 (**menu).menuWidth = maxPICTWidth + 2 * kLeftMargin;
 (**menu).menuHeight = (maxPICTHeight + kTopMargin*2) * numPICTs;
}

DoDrawMessage


/* 4 */
void  DoDrawMessage( MenuHandle menu,
 Rect *menuRectPtr )
{
 short  basePICTid, numPICTs, maxPICTWidth, 
 maxPICTHeight, itemHeight, i;
 Rect   r, tempRect;
 PicHandlepic;
 
 GetNumPICTs( menu, &basePICTid, &numPICTs );
 CalcitemHeightAndWidth(  basePICTid, numPICTs, 
 &maxPICTWidth, &maxPICTHeight );
 
 itemHeight = maxPICTHeight + kTopMargin * 2;
 
 r.top = menuRectPtr->top + kTopMargin;
 r.left = menuRectPtr->left + kLeftMargin;
 r.bottom = r.top + maxPICTHeight;
 r.right = r.left + maxPICTWidth;
 
 for ( i=0; i<numPICTs; i++ )
 {
 pic = GetPicture( basePICTid + i );
 
 DrawCenteredPict( pic, &r );
 
 OffsetRect( &r, 0, itemHeight );
 }
}

DoChooseMessage


/* 5 */
void  DoChooseMessage(  MenuHandle menu,
 Rect *menuRectPtr,
 Point hitPt,
 short *whichItemPtr )
{
 short  basePICTid, selectedItem, numPICTs, 
 maxPICTWidth, maxPICTHeight, itemHeight;
 Rect   r;
 
 GetNumPICTs( menu, &basePICTid, &numPICTs );
 CalcitemHeightAndWidth(  basePICTid, numPICTs, 
 &maxPICTWidth, &maxPICTHeight );
 
 itemHeight = (2 * kTopMargin) + maxPICTHeight;
 
 if ( PtInRect( hitPt, menuRectPtr ) )
 {
 selectedItem = ( (hitPt.v - menuRectPtr->top) / 
 itemHeight ) + 1;
 
 if ((*whichItemPtr > 0) && (*whichItemPtr != selectedItem))
 {
 InvertItem( *whichItemPtr, itemHeight, menuRectPtr );
 }
 
 if ( *whichItemPtr != selectedItem )
 {
 *whichItemPtr = selectedItem;
 InvertItem( *whichItemPtr, itemHeight, menuRectPtr );
 }
 }
 else if ( *whichItemPtr > 0 )
 {
 InvertItem( *whichItemPtr, itemHeight, menuRectPtr );
 *whichItemPtr = 0;
 }
}

InvertItem


/* 6 */
void  InvertItem( short itemNumber,
 short itemHeight,
 Rect *menuRectPtr )
{
 Rect r;
 
 r = *menuRectPtr;
 
 r.top += ( (itemNumber-1) * itemHeight );
 r.bottom = r.top + itemHeight;
 
 InvertRect( &r );
}

DrawCenteredPict


/* 7 */
void  DrawCenteredPict( PicHandle pic,
 Rect *rectPtr )
{
 Rect pictRect;
 
 pictRect = (**pic).picFrame;
 
 OffsetRect( &pictRect, rectPtr->left - pictRect.left,
    rectPtr->top  - pictRect.top);
 OffsetRect( &pictRect,(rectPtr->right - pictRect.right)/2,
   (rectPtr->bottom - pictRect.bottom)/2);
 
 DrawPicture( pic, &pictRect );
}

CalcitemHeightAndWidth


/* 8 */
void  CalcitemHeightAndWidth( short basePICTid,
 short numPICTs,
 short *widthPtr,
 short *heightPtr )
{
 short  i;
 Rect   r;
 PicHandlepic;
 
 *widthPtr = 0;
 *heightPtr = 0;
 
 for ( i=0; i<numPICTs; i++ )
 {
 pic = GetPicture( basePICTid + i );
 r = (**pic).picFrame;
 
 if ( r.bottom - r.top > *heightPtr )
 *heightPtr = r.bottom - r.top;
 
 if ( r.right - r.left > *widthPtr )
 *widthPtr = r.right - r.left;
 }
}

GetNumPICTs


/* 9 */
void  GetNumPICTs( MenuHandle menu,
 short *baseIDPtr,
 short *numPICTsPtr )
{
 Handle longHandle;
 long retrievedLong;
 short  menuID;
 
 menuID = (**menu).menuID;
 
 longHandle = GetResource( 'long', menuID );
 
 retrievedLong = (*((long *)(*longHandle)));
 
 *baseIDPtr = HiWord( retrievedLong );
 *numPICTsPtr = LoWord( retrievedLong );
}

Save your source code. Next, select Set Project Type... from the Project menu. When the dialog appears, click on the Code Resource radio button. Now make your dialog box look like the one in Figure 1. Be sure to check every single field!

Figure 1. The Set Project Type... dialog box.

The File Type and Creator fields will make your MDEF file look like a ResEdit document. That way, when you double-click on the file MDEF.rsrc (which we’re about to create) you’ll automatically launch ResEdit.

Why do this? Well, if we create the MDEF resource in a file, we’ll eventually want to copy the MDEF into the resource file (or application) that will use the MDEF. We’ll most likely do this in ResEdit.

Now select Build Code Resource... from the Project menu. You’ll be prompted to name the file the MDEF resource will be copied to. There are two approaches you can use. If you plan on using this resource in more than one application, you should save it as its own resource file. That’s what we’ll do. Enter the name MDEF.Π.rsrc and press the Save button.

The second approach we could have taken would be to click on the Merge checkbox, then entering the name of the resource file of the application that will be using the MDEF. If you do this, the MDEF resource will be copied into the application’s resource file, which is really what you want. We’ll do the same thing by hand.

Creating the Tester Resources

Now that your MDEF is complete, you’ll build an application to test the sucker. We’ll start by building the project resources. Start ResEdit and create a new file in the MDEF Files folder called Tester.Π.rsrc. Now open the file MDEF.Π.rsrc, click on the MDEF icon, and select Copy from the Edit menu. Now click on the Tester.Π.rsrc window and select Paste from the Edit menu. The MDEF icon should appear in the Tester.Π.rsrc window. When you double-click on the MDEF icon, you should see a single MDEF with an ID of 128. So far, so good.

Next, create a WIND resource with an ID of 128, a top of 40, Left of 2, Height of 160, and Width of 200. Click on the second icon from the left for the window type. Make the window not visible.

Next, create an MBAR resource (with ID 128) with four menus in it, numbered 128, 129, 130, and 131.

Next, create four MENU resources using the pictures in Figure 2 as a guide. Note that MENU 131 has a title (Pictures) but no items.

Figure 2. The four MENU resources.

Now comes a critical step. Open up the MENU editor to edit MENU 131. Select Edit Menu & MDEF ID... from the MENU menu. A dialog box will appear allowing you to set the MENU and MDEF resource IDs for this MENU. Change the MDEF ID from 0 to 128. Leave the MENU ID as is.

Be sure you change the MDEF id. If you don’t, the program will not work!

Next, you’ll create a custom resource that will tell the MDEF the resource ID of the first PICT to display, as well as the number of PICTs to display in the menu. Close all the windows till you are back in the main Tester.Π.rsrc window. Now select Create New Resource from the Resource menu. When prompted for a resource type, enter the four characters long. Since ResEdit doesn’t have a ‘long’ template, it will throw you into the hex/ASCII editor. Use the hex side and enter the hex number 00800005. For a peek at mine, check out Figure 3.

Figure 3. The long resource.

Next, select Get Resource Info from the Resource menu to change the resource ID to 131. You must make this change, so the MDEF will associate this resource with MENU 131.

The first two bytes of the long resource tell the MDEF to start off with PICT 128 (in hex, that’s 0080) and to use 5 PICT resources in a row (128, 129, 130, 131, and 132). Oh, by the way, I called this resource long because it is always 4 bytes in length.

Once you’ve changed the long resource ID to 131 (you did do that, didn’t you?) you are ready to create the PICT resources. Create five of them, being sure that they are numbered from 128 to 132. Color is fine. For best results, you might want to keep all of them around the size of an icon. My five are shown in Figure 4.

Figure 4. My five PICTs.

Save your resource file and quit ResEdit.

Creating the Tester Project

In THINK C, create a new project in the MDEF Files folder called Tester.Π. Add MacTraps to the project. Create a new source code file named Tester.c and add it to the project. Here’s the source code:


/* 10 */
#define kWindowResID 128
#define kMBARResID 128
#define kNULLStorage 0L
#define kMoveToFront (WindowPtr)-1L
#define kSleep   60L

#define mApple   128
#define iAbout   1

#define mFile    129
#define iQuit    1

#define mPICT    131


/*  Globals  */

Boolean gDone;
short   gCurPICTid;

/*  Functions  */

void  ToolboxInit( void );
void  MenuBarInit( void );
void  WindowInit( 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  HandlePICTChoice( short item );
void  DoUpdate( WindowPtr window );
void  DrawPictInWindow( PicHandle pic, WindowPtr window );
short GetBasePICTid( short menuID );

main


/* 11 */
void  main( void )
{
 ToolboxInit();
 MenuBarInit();
 WindowInit();
 
 gCurPICTid = GetBasePICTid( mPICT );
 
 EventLoop();
}

ToolboxInit


/* 12 */
void  ToolboxInit( void )
{
 InitGraf( &thePort );
 InitFonts();
 InitWindows();
 InitMenus();
 TEInit();
 InitDialogs( NULL );
 InitCursor();
}

MenuBarInit


/* 13 */
void  MenuBarInit( void )
{
 Handle menuBar;
 MenuHandle menu;
 
 menuBar = GetNewMBar( kMBARResID );
 SetMenuBar( menuBar );

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

WindowInit


/* 14 */
void  WindowInit( void )
{
 WindowPtrwindow;
 
 window = GetNewWindow( kWindowResID,kNULLStorage,kMoveToFront);
 
 if ( window == NULL )
 {
 SysBeep( 20 );  /* Couldn't load WIND */
 ExitToShell();
 }
 
 SetPort( window );
 ShowWindow( window );
}

EventLoop


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

DoEvent


/* 16 */
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;
 case updateEvt:
 DoUpdate( (WindowPtr)eventPtr->message );
 break;
 }
}

HandleMouseDown


/* 17 */
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;
 case inDrag : 
 DragWindow( window, eventPtr->where, &(screenBits.bounds) );
 break;
 }
}

HandleMenuChoice


/* 18 */
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 mPICT:
 HandlePICTChoice( item );
 break;
 }
 HiliteMenu( 0 );
 }
}

HandleAppleChoice


/* 19 */
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


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

HandlePICTChoice


/* 21 */
void  HandlePICTChoice( short item )
{
 WindowPtrwindow;
 
 window = FrontWindow();
 
 EraseRect( &window->portRect );
 InvalRect( &window->portRect );
 
 gCurPICTid = GetBasePICTid( mPICT ) + item - 1;
}

DoUpdate


/* 22 */
void  DoUpdate( WindowPtr window )
{
 PicHandlepic;
 
 BeginUpdate( window );
 
 pic = GetPicture( gCurPICTid );

 if ( pic == NULL )
 {
 SysBeep( 20 );  /* Couldn't load PICT */
 ExitToShell();
 }
 
 DrawPictInWindow( pic, FrontWindow() );
 
 EndUpdate( window );
}

DrawPictInWindow


/* 23 */
void  DrawPictInWindow( PicHandle pic,
 WindowPtr window )
{
 Rect   pictRect, windRect;
 
 pictRect = (**pic).picFrame;
 
 windRect = window->portRect;
 
 OffsetRect(&pictRect, windRect.left - pictRect.left,
 windRect.top - pictRect.top);
 OffsetRect(&pictRect,(windRect.right - pictRect.right)/2,
 (windRect.bottom - pictRect.bottom)/2);
 
 DrawPicture( pic, &pictRect );
}

GetBasePICTid


/* 24 */
short GetBasePICTid( short menuID )
{
 Handle longHandle;
 long retrievedLong;
 
 longHandle = GetResource( 'long', menuID );
 
 retrievedLong = (*((long *)(*longHandle)));
 
 return( HiWord( retrievedLong ) );
}

Once the code is typed in, save your changes and run this puppy.

Running the MDEF Tester

When you run your application, the first thing you should see is a window with PICT 128 centered in it. Now, for the big moment. Drumroll, please! Click your mouse on the Pictures menu. A menu should appear with your five PICTs in it. Select a picture. The selected picture should appear in the window. Figure 5 shows my menu, with Clarus the Dog-Cow selected. Moof!

Figure 5. My Pictures menu, with the second picture selected.

Till Next Month

Next month, we’ll walk through the code and talk about code resources in general. Till then, Daniel and I will be busy putting together his new swing set. Later...

 
AAPL
$104.48
Apple Inc.
+1.49
MSFT
$44.81
Microsoft Corpora
+0.43
GOOG
$542.21
Google Inc.
+9.50

MacTech Search:
Community Search:

Software Updates via MacUpdate

jAlbum Pro 12.2.4 - Organize your digita...
jAlbum Pro has all the features you love in jAlbum, but comes with a commercial license. With jAlbum, you can create gorgeous custom photo galleries for the Web without writing a line of code!... Read more
jAlbum 12.2.4 - Create custom photo gall...
With jAlbum, you can create gorgeous custom photo galleries for the Web without writing a line of code! Beginner-friendly, with pro results Simply drag and drop photos into groups, choose a design... Read more
ExpanDrive 4.1.7 - Access remote files o...
ExpanDrive builds cloud storage in every application, acts just like a USB drive plugged into your Mac. With ExpanDrive, you can securely access any remote file server directly from the Finder or... Read more
OmniOutliner Pro 4.1.3 - Pro version of...
OmniOutliner Pro is a flexible program for creating, collecting, and organizing information. Give your creativity a kick start by using an application that's actually designed to help you think. It'... Read more
Evernote 5.6.2 - Create searchable notes...
Evernote allows you to easily capture information in any environment using whatever device or platform you find most convenient, and makes this information accessible and searchable at anytime, from... Read more
OmniOutliner 4.1.3 - Organize your ideas...
OmniOutliner is a flexible program for creating, collecting, and organizing information. Give your creativity a kick start by using an application that's actually designed to help you think. It's... Read more
BBEdit 11.0 - Powerful text and HTML edi...
BBEdit is the leading professional HTML and text editor for the Mac. Specifically crafted in response to the needs of Web authors and software developers, this award-winning product provides a... Read more
Apple Security Update 2014-005 - For OS...
Apple Security Update is recommended for all users and improves the security of Mac OS X. For information on the security content of this update, please visit this website: http://support.apple.com/... Read more
EyeTV 3.6.6 - Watch and record TV on you...
EyeTV brings a rich TV experience to your Mac. Watch live TV on your Mac. Pause, rewind, and record whenever you want. EyeTV gives you powerful control over what you watch and how you watch it. Put... Read more
RapidWeaver 6.0 - Create template-based...
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

Latest Forum Discussions

See All

Jam Messenger Review
Jam Messenger Review By Jennifer Allen on October 23rd, 2014 Our Rating: :: SIMPLE MESSAGINGiPhone App - Designed for the iPhone, compatible with the iPad Want a very quick way to send push-based messages? Jam Messenger is basic... | Read more »
Felllice (Games)
Felllice 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: EXCLUSIVE PRICE DROP! 50% OFF FOR A LIMITED TIME! EAT EAT EAT AND GROW ! | Read more »
The Arrow Game: by Grazie Media (Games)
The Arrow Game: by Grazie Media 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: Guide a flying arrow through skyscrapers and city streets to hit a distant target. Experience an endless... | Read more »
Worldly (Games)
Worldly 1.2 Device: iOS Universal Category: Games Price: $2.99, Version: 1.2 (iTunes) Description: | Read more »
Money Pro - EASY! Bills, Budgets and Acc...
Money Pro - EASY! Bills, Budgets and Accounts w/ Sync 1.0 Device: iOS Universal Category: Finance Price: $4.99, Version: 1.0 (iTunes) Description: Manage money like a pro. Money Pro is the next generation of Money app (over 2 million... | Read more »
Pro Strategy Football 2014 (Games)
Pro Strategy Football 2014 2014.141001 Device: iOS Universal Category: Games Price: $4.99, Version: 2014.141001 (iTunes) Description: Take the proven strategy of the PSF franchise and add in Casual Play, improved graphics and... | Read more »
Super Glyph Quest (Games)
Super Glyph Quest 1.01 Device: iOS Universal Category: Games Price: $2.99, Version: 1.01 (iTunes) Description: Adventure is back Questers! Combine elemental glyphs together to cast powerful spells and vanquish adorable monsters in... | Read more »
Fighting Fantasy: Caverns of the Snow Wi...
Fighting Fantasy: Caverns of the Snow Witch 1.0 Device: iOS Universal Category: Games Price: $5.99, Version: 1.0 (iTunes) Description: Travel to Northern Allansia’s perilous Icefinger Mountains to defeat the wicked Snow Witch in this... | Read more »
Star Warfare 2: Payback Review
Star Warfare 2: Payback Review By Blake Grundman on October 22nd, 2014 Our Rating: :: ONE-TRICK PONYUniversal App - Designed for iPhone and iPad Unfortunately, it doesn’t take long for Star Warfare 2’s free-firing fun to turn into... | Read more »
TinType by Hipstamatic (Photography)
TinType by Hipstamatic 1.0 Device: iOS iPhone Category: Photography Price: $.99, Version: 1.0 (iTunes) Description: Create hauntingly beautiful, soul capturing portraits with TinType by Hipstamatic. Inspired by daguerreotypes,... | Read more »

Price Scanner via MacPrices.net

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
Save with Best Buy’s College Student Deals
Take an additional $50 off all MacBooks and iMacs at Best Buy Online with their College Students Deals Savings, valid through November 1st. Anyone with a valid .EDU email address can take advantage... Read more
iPad Air 2 & iPad mini 3 Best Tablets Yet...
The new iPads turned out to be pretty much everything I’d been hoping for and more than I’d expected.”More” particularly in terms of a drinking-from-a-firehose choice of models and configurations,... Read more
Drafts 4 Reinvents iOS Productivity App
N Richland Hills, Texas based Agile Tortoise has announced the release of Drafts 4 for iPhone and iPad. Drafts is a quick capture note taking app with flexible output actions. Drafts 4 scales from... Read more
AT&T accepting preorders for new iPads fo...
AT&T Wireless is accepting preorders for the new iPad Air 2 and iPad mini 3, cellular models, for $100 off MSRP with a 2-year service agreement: - 16GB iPad Air 2 WiFi + Cellular: $529.99 - 64GB... Read more
Apple offering refurbished Mac Pros for up to...
The Apple Store is offering Apple Certified Refurbished 2013 Mac Pros for up to $600 off the cost of new models. An Apple one-year warranty is included with each Mac Pro, and shipping is free. The... Read more
Select MacBook Airs $100 off MSRP, free shipp...
B&H Photo has 2014 a couple of MacBook Airs on sale for $100 off MSRP. Shipping is free, and B&H charges NY sales tax only. They also include free copies of Parallels Desktop and LoJack for... Read more
13-inch 2.5GHz MacBook Pro on sale for $100 o...
B&H Photo has the 13″ 2.5GHz MacBook Pro on sale for $999.99 including free shipping plus NY sales tax only. Their price is $100 off MSRP. Read more
Strong iPhone, Mac And App Store Sales Drive...
Apple on Monday announced financial results for its fiscal 2014 fourth quarter ended September 27, 2014. The Company posted quarterly revenue of $42.1 billion and quarterly net profit of $8.5 billion... Read more
Apple Posts How-To For OS X Recovery
OS X 10.7 Lion and later include OS X Recovery. This feature includes all of the tools you need to reinstall OS X, repair your disk, and even restore from a Time Machine backup. OS X Recovery... Read more

Jobs Board

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
*Apple* Retail - Multiple Positions (US) - A...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Position Opening at *Apple* - Apple (United...
…customers purchase our products, you're the one who helps them get more out of their new Apple technology. Your day in the Apple Store is filled with a range of Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.