TweetFollow Us on Twitter

MACINTOSH C CARBON

Demonstration Program AppleEvents

Goto Contents

// *******************************************************************************************
// AppleEvents.c                                                           CLASSIC EVENT MODEL
// *******************************************************************************************
// 
// This program:
//
// o  Installs handlers for the required Apple events, Appearance Manager Apple events, and,
//    on Mac OS X only, the Show Preferences Apple event.
//
// o  Responds to the receipt of required Apple events by displaying descriptive text in a
//    window opened for that purpose, and by opening simulated document windows as
//    appropriate.  These responses result from the user:
//
//    o   Double clicking on the application's icon, or selecting the icon and choosing Open
//        from the Finder's File menu, thus causing the receipt of an Open Application event.
//
//    o   When the application is already open, double clicking on the application's icon, or
//        selecting the icon and choosing Open from the Finder's File menu, thus causing the
//        receipt of a Re-open  Application event.
//
//    o   Double clicking on one of the document icons, selecting one or both of the document
//        icons and choosing Open from the Finder's File menu, or dragging one or both of the
//        document icons onto the application's icon, thus causing the receipt of an Open
//        Documents event.
//
//    o   On Mac OS 8/9, selecting one or both of the document icons and choosing Print from
//        the Finder's file menu, thus causing the receipt of a Print Documents event and, if
//        the application is not already running, a subsequent Quit Application event.
//
//    o   While the application is running, choosing Shut Down or Restart from the Finder's
//        Special menu, thus causing the receipt of a Quit Application event.   
//
// o  Responds to the receipt of Appearance Manager Apple events (Mac OS 8/9) and the Show 
//    Preferences Apple event (Mac OS X) by displaying descriptive text.
//
// The program, which is intended to be run as a built application rather than within
// CodeWarrior, utilises the following resources:
//
// o  A 'plst' resource containing an information property list which provides information
//    to the Mac OS X Finder.
//
// o  An 'icns' resource containing application and document icons for Mac OS X.
//
// o  'WIND' resources (purgeable, initially visible) for the descriptive text display window
//     and simulated document windows.
//
// o  'MBAR' and 'MENU' resources (preload, non-purgeable).
//
// o  'STR#' resources (purgeable) for displaying error messages using StandardAlert.
//
// o  For Mac OS 8/9:
//
//    o   'ICN#', 'ics#', 'ics4', 'ics8', 'icl4', and 'icl8' resources (that is, an icon 
//        family) for the application and for the application's documents. (Purgeable.)
//
//    o   'FREF' resources (non-purgeable) for the application and the application's 'TEXT'
//        documents, which link the icons with the file types they represent, and which allow
//        users to launch the application by dragging the document icons to the application 
//        icon.
//
//    o   The application's signature resource (non-purgeable), which enables the Finder to
//        identify and start up the application when the user double clicks the application's
//        document icons.  
//
//    o   A 'BNDL' resource (non-purgeable), which groups together the application's
//        signature, icon and 'FREF' resources.  
//
//    o   A 'hfdr' resource (purgeable), which provides the customised finder icon help 
//        override help balloon for the  application icon. 
//
//    o   A 'vers' resource (purgeable), which provides version information via the Show Info
//        window and the Version column in list view windows.
//
// o  A 'SIZE' resource with the acceptSuspendResumeEvents, canBackground, 
//    doesActivateOnFGSwitch, and isHighLevelEventAware flags set.
//
// *******************************************************************************************

// .................................................................................. includes

#include <Carbon.h>

// ................................................................................... defines

#define rMenubar             128
#define mFile                129
#define  iQuit               12
#define rDisplayWindow       128
#define rDocWindow           129
#define rErrorStrings        128
#define eInstallHandler      1
#define eGetRequiredParam    2
#define eGetDescriptorRecord 3
#define eMissedRequiredParam 4
#define eCountDescripRecords 5
#define eCannotOpenFile      6
#define eCannotPrintFile     7
#define eCannotOpenWindow    8
#define eMenus               9
#define MIN(a,b)             ((a) < (b) ? (a) : (b))

// .......................................................................... global variables

WindowRef gWindowRef;
Boolean   gRunningOnX = false;
Boolean   gDone;
Boolean   gApplicationWasOpen = false;

// ....................................................................... function prototypes

void      main                           (void);
void      doPreliminaries                (void);
void      doInstallAEHandlers            (void);
void      doInstallAnAEHandler           (AEEventClass,AEEventID,void *);
void      doEvents                       (EventRecord *);
OSErr     openAppEventHandler            (AppleEvent *,AppleEvent *,SInt32);
OSErr     reopenAppEventHandler          (AppleEvent *,AppleEvent *,SInt32);
OSErr     openDocsEventHandler           (AppleEvent *,AppleEvent *,SInt32);
OSErr     printDocsEventHandler          (AppleEvent *,AppleEvent *,SInt32);
OSErr     quitAppEventHandler            (AppleEvent *,AppleEvent *,SInt32);
OSErr     sysFontChangeEventHandler      (AppleEvent *,AppleEvent *,SInt32);
OSErr     smallSysFontChangeEventHandler (AppleEvent *,AppleEvent *,SInt32);
OSErr     viewsFontChangeEventHandler    (AppleEvent *,AppleEvent *,SInt32);
OSErr     showPreferencesEventHandler    (AppleEvent *,AppleEvent *,SInt32);
OSErr     doHasGotRequiredParams         (AppleEvent *);
Boolean   doOpenFile                     (FSSpec *,SInt32,SInt32);
Boolean   doPrintFile                    (FSSpec *,SInt32,SInt32);
void      doPrepareToTerminate           (void);
WindowRef doNewWindow                    (void);
void      doMenuChoice                   (SInt32);
void      doErrorAlert                   (SInt16);
void      doDrawText                     (Str255);
void      doConcatPStrings               (Str255,Str255);

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

void  main(void)
{
  Rect          portRect;
  RGBColor      foreColour = { 0xFFFF,0xFFFF,0xFFFF };
  RGBColor      backColour = { 0x4444,0x4444,0x9999 };
  MenuBarHandle menubarHdl;
  SInt32        response;
  MenuRef       menuRef;
  EventRecord   eventStructure;
  
  // ........................................................................ do preliminaries

  doPreliminaries();

  // ............................................................... set up menu bar and menus

  menubarHdl = GetNewMBar(rMenubar);
  if(menubarHdl == NULL)
    doErrorAlert(eMenus);
  SetMenuBar(menubarHdl);
  DrawMenuBar();

  Gestalt(gestaltMenuMgrAttr,&response);
  if(response & gestaltMenuMgrAquaLayoutMask)
  {
    menuRef = GetMenuRef(mFile);
    if(menuRef != NULL)
    {
      DeleteMenuItem(menuRef,iQuit);
      DeleteMenuItem(menuRef,iQuit - 1);
      DisableMenuItem(menuRef,0);
    }

    gRunningOnX = true;

    EnableMenuCommand(NULL,kAEShowPreferences);
  }

  // ........................................................................... open a window

  if(!(gWindowRef = GetNewCWindow(rDisplayWindow,NULL,(WindowRef) -1)))
  {
    doErrorAlert(eCannotOpenWindow);
    ExitToShell();
  }

  SetPortWindowPort(gWindowRef);
  TextSize(10);
  TextFace(bold);
  RGBBackColor(&backColour);
  RGBForeColor(&foreColour);
  GetWindowPortBounds(gWindowRef,&portRect);
  EraseRect(&portRect);

  // ............................................................ install Apple event handlers

  doInstallAEHandlers();

  // .............................................................................. event loop
  
  gDone = false;

  while(!gDone)
  {
    if(WaitNextEvent(everyEvent,&eventStructure,180,NULL))
      doEvents(&eventStructure);
  }
}

// *************************************************************************** doPreliminaries

void  doPreliminaries(void)
{
  MoreMasterPointers(64);
  InitCursor();
  FlushEvents(everyEvent,0);
}

// *********************************************************************** doInstallAEHandlers

void  doInstallAEHandlers(void)
{
  // ................................................................... required Apple events

  doInstallAnAEHandler(kCoreEventClass,kAEOpenApplication,openAppEventHandler);
  doInstallAnAEHandler(kCoreEventClass,kAEReopenApplication,reopenAppEventHandler);
  doInstallAnAEHandler(kCoreEventClass,kAEOpenDocuments,openDocsEventHandler);
  doInstallAnAEHandler(kCoreEventClass,kAEPrintDocuments,printDocsEventHandler);
  doInstallAnAEHandler(kCoreEventClass,kAEQuitApplication,quitAppEventHandler);

  // ......................................................... Appearance Manager Apple events

  doInstallAnAEHandler(kAppearanceEventClass,kAESystemFontChanged,sysFontChangeEventHandler);
  doInstallAnAEHandler(kAppearanceEventClass,kAESmallSystemFontChanged,
                       smallSysFontChangeEventHandler);
  doInstallAnAEHandler(kAppearanceEventClass,kAEViewsFontChanged,viewsFontChangeEventHandler);

  // ............................................................ Show Preferences Apple event

  if(gRunningOnX)
    doInstallAnAEHandler(kCoreEventClass,kAEShowPreferences,showPreferencesEventHandler);
}

// ********************************************************************** doInstallAnAEHandler

void  doInstallAnAEHandler(AEEventClass eventClass,AEEventID eventID,void *theHandler)
{
  OSErr  osError;

  osError = AEInstallEventHandler(eventClass,eventID,
                                  NewAEEventHandlerUPP((AEEventHandlerProcPtr) theHandler),
                                  0L,false);
  if(osError != noErr)
    doErrorAlert(eInstallHandler);
}

// ********************************************************************************** doEvents

void  doEvents(EventRecord *eventStrucPtr)
{
  WindowPartCode partCode;
  WindowRef      windowRef;
  SInt32         menuChoice;

  switch(eventStrucPtr->what)
  {
    case kHighLevelEvent:
      AEProcessAppleEvent(eventStrucPtr);
      break;

    case mouseDown:
      partCode = FindWindow(eventStrucPtr->where,&windowRef);
      switch(partCode)
      {
        case inMenuBar:
          menuChoice = MenuSelect(eventStrucPtr->where);
          doMenuChoice(menuChoice);
          break;

        case inDrag:
          DragWindow(windowRef,eventStrucPtr->where,NULL);
          break;

        case inContent:
          if(windowRef != FrontWindow())
            SelectWindow(windowRef);
          break;
          
        case inGoAway:
          DisposeWindow(windowRef);
          break;
      }
      break;

    case keyDown:
      if((eventStrucPtr->modifiers & cmdKey) != 0)
        doMenuChoice(MenuEvent(eventStrucPtr));
      break;

    case updateEvt:
      BeginUpdate((WindowRef)eventStrucPtr->message);
      EndUpdate((WindowRef)eventStrucPtr->message);
      break;
  }
}
  
// *********************************************************************** openAppEventHandler

OSErr  openAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefCon)
{
  OSErr     osError;
  WindowRef windowRef;

  gApplicationWasOpen = true;

  osError = doHasGotRequiredParams(appEvent);

  if(osError == noErr)
  {
    doDrawText("\pReceived an Apple event: OPEN APPLICATION.");
    doDrawText("\p    o Opening an untitled window in response.");

    windowRef = doNewWindow();
    SetWTitle(windowRef,"\puntitled");
  }

  return osError;
}

// ********************************************************************* reopenAppEventHandler

OSErr  reopenAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefCon)
{
  OSErr     osError;
  WindowRef windowRef;

  osError = doHasGotRequiredParams(appEvent);

  if(osError == noErr)
  {
    doDrawText("\pReceived an Apple event: RE-OPEN APPLICATION.");
    doDrawText("\p    o I will check whether I have any windows open.");

    windowRef = GetWindowList();

    if((windowRef = GetNextWindow(windowRef)) == NULL)
    {
      doDrawText("\p      No windows are open, so I will open a window.");

      windowRef = doNewWindow();
      SetWTitle(windowRef,"\puntitled 1");
    }
    else
      doDrawText("\p      A window is open, so I won't open another.");
  }

  return osError;
}

// ********************************************************************** openDocsEventHandler

OSErr  openDocsEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
{
  AEDescList docList;
  OSErr      osError, ignoreErr;
  SInt32     numberOfItems, index;
  DescType   returnedType;
  FSSpec     fileSpec;
  AEKeyword  keyWord;
  Size       actualSize;
  Boolean    result;

  osError = AEGetParamDesc(appEvent,keyDirectObject,typeAEList,&docList);

  if(osError == noErr)
  {
    osError = doHasGotRequiredParams(appEvent);
    if(osError == noErr)
    {
      osError = AECountItems(&docList,&numberOfItems);
      if(osError == noErr)
      {
        for(index=1;index<=numberOfItems;index++)
        {
          osError = AEGetNthPtr(&docList,index,typeFSS,&keyWord,&returnedType,&fileSpec,
                                sizeof(fileSpec),&actualSize);
          if(osError == noErr)
          {
            if(!(result = doOpenFile(&fileSpec,index,numberOfItems)))
              doErrorAlert(eCannotOpenFile);
          }
          else
            doErrorAlert(eGetDescriptorRecord);
        }
      }
      else
        doErrorAlert(eCountDescripRecords);
    }
    else
      doErrorAlert(eMissedRequiredParam);

    ignoreErr = AEDisposeDesc(&docList);
  }
  else
    doErrorAlert(eGetRequiredParam);

  return osError;
}

// ********************************************************************* printDocsEventHandler

OSErr  printDocsEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
{
  AEDescList docList;
  OSErr      osError, ignoreErr;
  SInt32     numberOfItems, index;
  DescType   returnedType;
  FSSpec     fileSpec;
  AEKeyword  keyWord;
  Size       actualSize;
  Boolean    result;
  
  osError = AEGetParamDesc(appEvent,keyDirectObject,typeAEList,&docList);

  if(osError == noErr)
  {
    osError = doHasGotRequiredParams(appEvent);
    if(osError == noErr)
    {
      osError = AECountItems(&docList,&numberOfItems);
      if(osError == noErr)
      {
        for(index=1;index<=numberOfItems;index++)
        {
          osError = AEGetNthPtr(&docList,index,typeFSS,&keyWord,&returnedType,&fileSpec,
                              sizeof(fileSpec),&actualSize);
          if(osError == noErr)
          {
            if(!(result = doPrintFile(&fileSpec,index,numberOfItems)))
              doErrorAlert(eCannotPrintFile);
          }
          else
            doErrorAlert(eGetDescriptorRecord);
        }
      }
      else
        doErrorAlert(eCountDescripRecords);
    }
    else
      doErrorAlert(eMissedRequiredParam);

    ignoreErr = AEDisposeDesc(&docList);
  }
  else
    doErrorAlert(eGetRequiredParam);

  return osError;
}

// *********************************************************************** quitAppEventHandler

OSErr  quitAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
{
  OSErr osError;

  osError = doHasGotRequiredParams(appEvent);

  if(osError == noErr)
    doPrepareToTerminate();

  return osError;
}

// ***************************************************************** sysFontChangeEventHandler

OSErr  sysFontChangeEventHandler(AppleEvent *appEvent,AppleEvent *reply,
                                 SInt32 handlerRefcon)
{
  OSErr  osError;
  Rect   portRect;
  Str255 fontName, theString = "\p   Current large system font is: ";

  osError = doHasGotRequiredParams(appEvent);

  if(osError == noErr)
  {
    GetWindowPortBounds(gWindowRef,&portRect);
    EraseRect(&portRect);
    doDrawText("\pReceived an Apple event: LARGE SYSTEM FONT CHANGED.");
    GetThemeFont(kThemeSystemFont,smSystemScript,fontName,NULL,NULL);
    doConcatPStrings(theString,fontName);
    doDrawText(theString);
    // Action as required by application.
  }

  return osError;
}

// ************************************************************ smallSysFontChangeEventHandler

OSErr  smallSysFontChangeEventHandler(AppleEvent *appEvent,AppleEvent *reply,
                                      SInt32 handlerRefcon)
{
  OSErr  osError;
  Rect   portRect;
  Str255 fontName, theString = "\p   Current small system font is: ";
  
  osError = doHasGotRequiredParams(appEvent);

  if(osError == noErr)
  {
    GetWindowPortBounds(gWindowRef,&portRect);
    EraseRect(&portRect);
    doDrawText("\pReceived an Apple event: SMALL SYSTEM FONT CHANGED.");
    GetThemeFont(kThemeSmallSystemFont,smSystemScript,fontName,NULL,NULL);
    doConcatPStrings(theString,fontName);
    doDrawText(theString);
    // Action as required by application.
  }

  return osError;
}

// *************************************************************** viewsFontChangeEventHandler

OSErr  viewsFontChangeEventHandler(AppleEvent *appEvent,AppleEvent *reply,
                                   SInt32 handlerRefcon)
{
  OSErr  osError;
  Rect   portRect;
  Str255 fontName, fontSizeString, theString = "\p   Current views font is: ";
  SInt16 fontSize;

  osError = doHasGotRequiredParams(appEvent);

  if(osError == noErr)
  {
    GetWindowPortBounds(gWindowRef,&portRect);
    EraseRect(&portRect);
    doDrawText("\pReceived an Apple event: VIEWS FONT CHANGED.");
    GetThemeFont(kThemeViewsFont,smSystemScript,fontName,&fontSize,NULL);
    doConcatPStrings(theString,fontName);
    doConcatPStrings(theString,"\p ");
    NumToString((SInt32) fontSize,fontSizeString);
    doConcatPStrings(theString,fontSizeString);
    doConcatPStrings(theString,"\p point");
    doDrawText(theString);
    // Action as required by application.
  }

  return osError;
}

// *************************************************************** showPreferencesEventHandler

OSErr  showPreferencesEventHandler(AppleEvent *appEvent,AppleEvent *reply,
                                   SInt32 handlerRefcon)
{
  OSErr osError;
  Rect  portRect;

  osError = doHasGotRequiredParams(appEvent);

  if(osError == noErr)
  {
    GetWindowPortBounds(gWindowRef,&portRect);
    EraseRect(&portRect);
    doDrawText("\pReceived an Apple event: SHOW PREFERENCES.");
    doDrawText("\p    o I would present a Preferences... dialog now.");
  }

  return osError;
}

// ******************************************************************** doHasGotRequiredParams

OSErr  doHasGotRequiredParams(AppleEvent *appEvent)
{
  OSErr    osError;  
  DescType returnedType;
  Size     actualSize;

  osError = AEGetAttributePtr(appEvent,keyMissedKeywordAttr,typeWildCard,&returnedType,NULL,0,
                              &actualSize);

  if(osError == errAEDescNotFound)
    osError = noErr;
  else if(osError == noErr)
    osError = errAEParamMissed;

  return osError;
}

// ******************************************************************************** doOpenFile

Boolean  doOpenFile(FSSpec *fileSpecPtr,SInt32 index,SInt32 numberOfItems)
{
  WindowRef windowRef;

  gApplicationWasOpen = true;

  if(index == 1)
    doDrawText("\pReceived an Apple event: OPEN DOCUMENTS.");

  if(numberOfItems == 1)
  {
    doDrawText("\p    o The file to open is: ");
    DrawString(fileSpecPtr->name);
    doDrawText("\p    o Opening titled window in response.");
  }
  else
  {
    if(index == 1)
    {    
      doDrawText("\p    o The files to open are: ");
      DrawString(fileSpecPtr->name);
    }
    else
    {
      DrawString("\p and ");
      DrawString(fileSpecPtr->name);
      doDrawText("\p    o Opening titled windows in response.");
    }
  }

  if(windowRef = doNewWindow())
  {
    SetWTitle(windowRef,fileSpecPtr->name);
    return true;
  }
  else
    return false;
}

// ******************************************************************************* doPrintFile

Boolean  doPrintFile(FSSpec *fileSpecPtr,SInt32 index,SInt32 numberOfItems)
{
  WindowRef windowRef;
  UInt32    finalTicks;

  if(index == 1)
    doDrawText("\pReceived an Apple event: PRINT DOCUMENTS");

  if(numberOfItems == 1)
  {
    doDrawText("\p    o The file to print is: ");
    DrawString(fileSpecPtr->name);
    windowRef = doNewWindow();
    SetWTitle(windowRef,fileSpecPtr->name);
    Delay(60,&finalTicks);
    doDrawText("\p    o I would present the Print dialog first and then print");
    doDrawText("\p       the document when the user has made his settings.");
    Delay(60,&finalTicks);
    doDrawText("\p    o Assume that I am now printing the document.");
  }
  else
  {
    if(index == 1)
    {    
      doDrawText("\p    o The first file to print is: ");
      DrawString(fileSpecPtr->name);
      doDrawText("\p       I would present the Print dialog for the first file");
      doDrawText("\p       only and use the user's settings to print both files.");
    }
    else
    {
      doDrawText("\p    o The second file to print is: ");
      DrawString(fileSpecPtr->name);
      doDrawText("\p       I am using the Print dialog settings used for the");
      doDrawText("\p       first file.");
    }

    windowRef = doNewWindow();
    SetWTitle(windowRef,fileSpecPtr->name);
    doDrawText("\p    o Assume that I am now printing the document.");
  }

  if(numberOfItems == index)
  {
    if(!gApplicationWasOpen)
    {
      doDrawText("\p       Since the application was not already open, I expect to"); 
      doDrawText("\p       receive a QUIT APPLICATION event when I have finished.");
    }
    else
    {
      doDrawText("\p       Since the application was already open, I do NOT expect"); 
      doDrawText("\p       to receive a QUIT APPLICATION event when I have finished.");
    }

    Delay(180,&finalTicks);
    doDrawText("\p    o Finished print job.");
  }
  else
    Delay(180, &finalTicks);

  DisposeWindow(windowRef);
  return true;
}

// ********************************************************************** doPrepareToTerminate

void  doPrepareToTerminate(void)
{
  UInt32 finalTicks;

  doDrawText("\pReceived an Apple event: QUIT APPLICATION");

  if(gApplicationWasOpen)
  {
    doDrawText("\p    o I would now ask the user to save any unsaved files before");
    doDrawText("\p       terminating myself in response to the event.");
    doDrawText("\p    o Click the mouse when ready to terminate.");
    while(!Button()) ;
  }
  else
  {
    doDrawText("\p    o Terminating myself in response");
    Delay(240,&finalTicks);
  }

  // If the user did not click the Cancel button in a Save dialog:

  gDone = true;
}

// ******************************************************************************* doNewWindow

WindowRef  doNewWindow(void)
{
  WindowRef windowRef;

  if(!(windowRef = GetNewCWindow(rDocWindow,NULL,(WindowRef) -1)))
    doErrorAlert(eCannotOpenWindow);

  return windowRef;
}

// ****************************************************************************** doMenuChoice

void  doMenuChoice(SInt32 menuChoice)
{
  MenuID        menuID;
  MenuItemIndex menuItem;
  
  menuID   = HiWord(menuChoice);
  menuItem = LoWord(menuChoice);

  if(menuID == 0)
    return;

  switch(menuID)
  {
    case mFile:
      if(menuItem  == iQuit)
        gDone = true;
      break;
  }

  HiliteMenu(0);
}

// ****************************************************************************** doErrorAlert

void  doErrorAlert(SInt16 errorType)
{
  Str255 errorString;
  SInt16 itemHit;

  GetIndString(errorString,rErrorStrings,errorType);

  if(errorType < 7)
    StandardAlert(kAlertCautionAlert,errorString,NULL,NULL,&itemHit);
  else
  {
    StandardAlert(kAlertStopAlert,errorString,NULL,NULL,&itemHit);
    ExitToShell();
  }
}

// ******************************************************************************** doDrawText

void  doDrawText(Str255 eventString)
{
  RgnHandle tempRegion;
  SInt16    a;
  Rect      portRect;
  UInt32    finalTicks;

  tempRegion = NewRgn();
  GetWindowPortBounds(gWindowRef,&portRect);

  for(a=0;a<15;a++)
  {
    ScrollRect(&portRect,0,-1,tempRegion);
    QDFlushPortBuffer(GetWindowPort(gWindowRef),NULL);

    Delay(4,&finalTicks);
  }

  DisposeRgn(tempRegion);

  MoveTo(8,160);
  DrawString(eventString);
  QDFlushPortBuffer(GetWindowPort(gWindowRef),NULL);
}

// ************************************************************************** doConcatPStrings

void  doConcatPStrings(Str255 targetString,Str255 appendString)
{
  SInt16 appendLength;

  appendLength = MIN(appendString[0],255 - targetString[0]);

  if(appendLength > 0)
  {
    BlockMoveData(appendString+1,targetString+targetString[0]+1,(SInt32) appendLength);
    targetString[0] += appendLength;
  }
}

// *******************************************************************************************

Demonstration Program AppleEvents Comments

The demonstration requires that the user open the windows containing the AppleEvents
application icon and the two document file icons AppleEvents Document A and AppleEvents
Document B.

Using all of the methods available in the Finder (that is, double clicking the icons, dragging
document icons to the application icon, selecting the icons and choosing Open and (on Mac OS
8/9 only) Print from the Finder's File menu, choosing the application from the Apple menu), the
user should launch the application, open the simulated documents and (on Mac OS 8/9 only)
"print" the documents, noting the descriptive text printed in the non-document window in
response to the receipt of the resulting Apple events.

When the application is running, the user should double-click the application icon, choose the
application from the Mac OS 8/9 Apple menu, or click the application icon and choose Open from
the Finder's File menu, noting the receipt of the Re-open Application event.  This should be
done when one or more "document" windows are open and when no "document windows are open.

The user should also choose Restart or Shut Down while the application is running, also noting
the displayed text resulting from receipt of the Quit Application event.  (On Mac OS X, the
Quit Application event is also received when Quit is chosen from the Application menu.)

On Mac OS 8/9, opening and printing should be attempted (from the Finder's File menu) when the
application is already running and when the application is not running.

On Mac OS X, the user should choose Show PreferencesÉ from the Application menu.

Note that, in this demonstration, it is possible to "open" each "document" more than once, that
is, it is possible to have several "Document A" and/or "Document B" windows open at once. (A
real application, of course, would permit only one "Document A" and/or one "Document B" window
to be open at any one time.)  The reason for this is that, in this demonstration, files are not
actually opened; accordingly, it is not possible to check whether the relevant file is already
open or not.

With regard to the Appearance Manager Apple events, the user should make changes to the system
font, small system font, and views font in the Fonts tab of the Appearance control panel,
noting the descriptive text that appears in the non-document window.

Although not related to the required Apple events aspects of the program, the following aspects
of the demonstration may also be investigated:

o On Mac OS 8/9, the customised finder icon help override help balloon for the application
  icon.  (The 'hfdr' resource refers.)

o The version information for the application in the Finder's Get Info (Mac OS 8/9) and Show
  Info (Mac OS X) window and in the window containing the AppleEvents application when list 
  view is selected.

'plst' Resource

The following is the information property list in the application's 'plst' resource:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
  <key>CFBundleInfoDictionaryVersion</key>
  <string>6.0</string>
  <key>CFBundleName</key>
  <string>AppleEvents</string>
  <key>CFBundlePackageType</key>
  <string>APPL</string>
  <key>CFBundleSignature</key>
  <string>KJBB</string>
  <key>CFBundleIconFile</key>
  <string>128</string>
  <key>CFBundleIdentifier</key>
  <string>com.Windmill Software.AppleEvents</string>
  <key>LSPrefersCarbon</key>
  <string>Yes</string>
  <key>CFBundleLongVersionString</key> 
  <string>Version 1.0.0 June 2001</string>
  <key>CFBundleShortVersionString</key> 
  <string>1.0.0</string>
  <key>CFBundleDevelopmentRegion</key>
  <string>English</string>
  <key>NSAppleScriptEnabled</key>
  <string>No</string>
  <key>CFBundleDocumentTypes</key>
  <array>
    <dict>
      <key>CFBundleTypeIconFile</key>
      <string>129</string>
      <key>CFBundleTypeName</key>
      <string>AppleEvents Document</string>
      <key>CFBundleTypeOSTypes</key>
      <array>
        <string>TEXT</string>
      </array>
      <key>CFBundleTypeRole</key>
      <string>Viewer</string>
    </dict>
  </array>
</dict>
</plist>

Global Variables

gRunningOnX will be set to true if the program is running on Mac OS X.

gApplicationWasOpen will be used to control the manner of program termination when a Quit
Application event is received, depending on whether the event followed a Print Documents event
(on Mac OS 8/9) or resulted from the user choosing Restart of Shut Down from the Finder's
Special menu.

main

In the menus setting up block, if the program is running on Mac OS X, the Preferences item in
the Mac OS X Application menu is enabled.

The call to doInstallAEHandlers installs the Apple event handlers.

doInstallAEHandlers and doInstallAnAEHandler

doInstallAEHandlers, supported by doInstallAnAEHandler, installs the handlers for the required
Apple events, the Appearance Manager Apple events, and (if the program is running on Mac OS X)
the Show Preferences Apple event in the application's Apple event dispatch table.

In doInstallAnAEHandler, false is passed in AEInstallEventHandler's isSysHandler parameter. 
false causes the handler to be installed in the application's Apple event dispatch table.  true
causes handlers to be installed in the system's Apple event dispatch table.  (The system Apple
event dispatch table is a table in the system heap containing handlers that are available to
all applications and processes running on the same computer.)

doEvents

The kHighLevelEvent case accommodates the receipt of a high-level event, in which case
AEProcessAppleEvent is called.  (AEProcessAppleEvent looks in the application's Apple event
dispatch table for a match to the event class and event ID contained in, respectively, the
event structure's message and where fields, and calls the appropriate handler.)

doOpenAppEvent

doOpenAppEvent is the handler for the Open Application event.

At the first line, the global variable gApplicationWasOpen, which controls the manner of
program termination when a Quit Application event is received, is set to true.  (This line is
required for demonstration program purposes only.)

The function doHasGotRequiredParams is then called to check whether the Apple event contains
any required parameters.  If so, the handler returns an error because, by definition, the Open
Application event should not contain any required parameters.

If noErr is returned by doHasGotRequiredParams, the handler does what the user expects the
application to do when it is opened, that is, it opens an untitled document window (the call to
doNewWindow and the subsequent call to SetWTitle).  The handler then returns noErr.

If errAEParamMissed is returned by doHasGotRequiredParams, this is returned by the handler.

The calls to doDrawText simply print some text in the text window for demonstration program
purposes.

doReopenAppEvent

doRepenAppEvent is the handler for the Re-open Documents event.

At the first line, the function doHasGotRequiredParams is called to check whether the Apple
event contains any required parameters.  If so, the handler returns an error because, by
definition, the Re-open Application event should not contain any required parameters.

If noErr is returned by doHasGotRequiredParams, and if there are currently no open windows, the
handler opens an untitled document window and returns noErr.

If errAEParamMissed is returned by doHasGotRequiredParams, this is returned by the handler.

The calls to doDrawText simply print some text in the text window for demonstration program
purposes.

doOpenDocsEvent

doOpenDocsEvent is the handler for the Open Documents event.

At the first line, AEGetParamDesc is called to get the direct parameter (specified in the
keyDirectObject keyword) out of the Apple event.  The constant typeAEList specifies the
descriptor type as a list of descriptor structures.  The descriptor list is received by the
docList variable.

Before proceeding further, the handler checks that it has received all the required parameters
by calling the function doHasGotRequiredParams.

Having retrieved the descriptor list from the Apple event, the handler calls AECountItems to
count the number of descriptors in the list.

Using the returned number as an index, AEGetNthPtr is called to get the data of each descriptor
structure in the list.  In the AEGetNthPtr call, the parameter typeFSS specifies the desired
type of the resulting data, causing the Apple Event Manager to coerce the data in the
descriptor structure to a file system specification structure.  Note also that keyWord receives
the keyword of the specified descriptor structure, returnedType receives the descriptor type,
fileSpec receives a pointer to the file system specification structure, sizeof(fileSpec)
establishes the length, in bytes, of the data returned, and actualSize receives the actual
length, in bytes, of the data for the descriptor structure.

After extracting the file system specification structure describing the document to open, the
handler calls the function for opening files (doOpenFile).  (In a real application, that
function would typically be the same as that invoked when the user chooses Open from the
application's File menu.)

If the call to AEGetNthPtr does not return noErr, the error handling function (doErrorAlert) is
called.  (AEGetNthPtr will return an error code if there was insufficient room in the heap, the
data could not be coerced, the descriptor structure was not found, the descriptor was of the
wrong type or the descriptor structure was not a valid descriptor structure.)

If the call to doHasGotRequiredParams does not return noErr, the error handling function
(doErrorAlert) is called.  (doHasGotRequiredParams returns noErr only if you got all the
required parameters.)

Since the handler has no further requirement for the data in the descriptor list, AEDisposeDesc
is called to dispose of the descriptor list.

If the call to AEGetParamDesc does not return noErr the error handling function (doErrorAlert)
is called.  (AEGetParamDesc will return an error code for much the same reasons as will
AEGetNthPtr.)

doPrintDocsEvent

doPrintDocsEvent is the handler for the Print Documents event.

The code is identical to that for the Open Documents event handler doOpenDocs except that the
function for printing files (doPrintFile) is called rather than the function for simply opening
files (doOpenFile).

doQuitAppEvent

doQuitAppEvent is the handler for the Quit Application event.

After checking that it has received all the required parameters by calling the function
doHasGotRequiredParams, the handler calls the function doPrepareToTerminate.
doSysFontChangeEvent, doSmallSysFontChange, and doViewsFontChangeEvent
doSysFontChangeEvent, doSmallSysFontChange, and doViewsFontChangeEvent are the handlers for the
appearance Apple events.

The function doHasGotRequiredParams is called to check whether the Apple event contains any
required parameters.  If so, the handler returns an error because, by definition, these events
should not contain any required parameters.

The handlers then draw some advisory text in the non-document window indicating that the event
has been received, call the Appearance Manager function GetThemeFont to obtain information
about the relevant font (large system, small system, or views), and draw the font name (and, in
the case of the views font, the font size).

showPreferencesEventHandler

showPreferencesEventHandler is the handler for the Show Preferences Apple event.  It simply
draws some advosory text in the window to prove that the event was received.

doHasGotRequiredParams

doHasGotRequiredParams is the function called by doOpenAppEvent, doReopenAppEvent,
doSysFontChangeEvent, doSmallSysFontChange, and doViewsFontChangeEvent to confirm that the
event passed to it contains no required parameters, and by the other required Apple event
handlers to check that they have received all the required parameters.

The first parameter in the call to AEGetAttributePtr is a pointer to the Apple event in
question.  The second parameter is the Apple event keyword; in this case the constant
keyMissedKeywordAttr is specified, meaning the first required parameter remaining in the event. 
The third parameter specifies the descriptor type; in this case the constant typeWildCard is
specified, meaning any descriptor type.  The fourth parameter receives the descriptor type of
the returned data.  The fifth parameter is a pointer to the data buffer which stores the
returned data.  The sixth parameter is the maximum length of the data buffer to be returned. 
Since we do not need the data itself, these parameters are set to NULL and 0 respectively.  The
last parameter receives the actual length, in bytes, of the data buffer for the attribute.

AEGetAttributePtr returns the result code errAEDescNotFound if the specified descriptor type
(typeWildCard, that is, any descriptor type) is not found, meaning that the handler extracted
all the required parameters.  In this event, doHasGotRequiredParams returns noErr.

If AEGetAttributePtr returns noErr, the handler has not extracted all of the required
parameters, in which case, the handler should return errAEParamMissed and not handle the event. 
Accordingly, errAEParamMissed is returned to the handler (and, in turn, by the handler) if
noErr is returned by AEGetAttributePtr.

doOpenFile

doOpenFile takes the file system specification structure and opens a window with the filename
contained in that structure repeated in the window's title bar (the calls to doNewWindow and
SetWTitle).  The rest of the doOpenFile code simply draws explanatory text in the text window. 

In a real application, this is the function that would open files as a result of, firstly, the
receipt of the Open Documents event and, secondly, the user choosing Open from the
application's File menu and then choosing a file or files from the resulting Navigation
Services Open dialog.

doPrintFile

doPrintFile is applicable to Mac OS 8/9 only.  It is the function which, in a real application,
would take the file system specification structure passed to it from the Print Documents event
handler, extract the filename and control the printing of that file.  In this demonstration,
most of the doPrintFile code is related to drawing explanatory text in the text window.

If your application can interact with the user, it should open windows for the documents,
display a Print dialog for the first document, and use the settings entered by the user for the
first document to print all documents.

Note that, if your application was not running when the user selected a document icon and chose
Print from the Finder's File menu, the Finder will send a Quit Application event following the
print operation.

doPrepareToTerminate

doPrepareToTerminate is the function called by the Quit Application event handler.  In this
demonstration, gDone will be set to true, and the program will thus terminate immediately, if
the Quit Application event resulted from the user initiating a print operation from the Mac OS
8/9 Finder when the application was not running.

If the application was running (gApplicationWasOpen contains true) and the Quit Application
event thus arose from the user selecting Restart or Shut Down from the Finder's File menu, the
demonstration waits for a button click before setting gDone to true.  (In a real application,
and where appropriate, this area of the code would invoke alerts to ascertain whether the user
wished to save changed documents before closing down.)

Note that, when your application is ready to quit, it must call ExitToShell from the main event
loop, not from the handlers for the Quit Application event.  Your application should quit only
after the handler returns noErr as its function result.

doNewWindow

doNewWindow opens document windows in response to calls from the Open Application and Open
Documents event handlers.
 
AAPL
$118.93
Apple Inc.
-0.07
MSFT
$47.81
Microsoft Corpora
+0.06
GOOG
$541.83
Google Inc.
+1.46

MacTech Search:
Community Search:

Software Updates via MacUpdate

Adobe Photoshop Elements 13.0 - Consumer...
Adobe Photoshop Elements 12--the #1 selling consumer photo editing software--helps you edit pictures with powerful, easy-to-use options and share them via print, the web, Facebook, and more.Version... Read more
Skype 7.2.0.412 - Voice-over-internet ph...
Skype allows you to talk to friends, family and co-workers across the Internet without the inconvenience of long distance telephone charges. Using peer-to-peer data transmission technology, Skype... Read more
HoudahSpot 3.9.6 - Advanced file search...
HoudahSpot is a powerful file search tool built upon MacOS X Spotlight. Spotlight unleashed Create detailed queries to locate the exact file you need Narrow down searches. Zero in on files Save... Read more
RapidWeaver 6.0.3 - 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
iPhoto Library Manager 4.1.10 - Manage m...
iPhoto Library Manager lets you organize your photos into multiple iPhoto libraries. Separate your high school and college photos from your latest summer vacation pictures. Or keep some photo... Read more
iExplorer 3.5.1.9 - View and transfer al...
iExplorer is an iPhone browser for Mac lets you view the files on your iOS device. By using a drag and drop interface, you can quickly copy files and folders between your Mac and your iPhone or... Read more
MacUpdate Desktop 6.0.3 - Discover and i...
MacUpdate Desktop 6 brings seamless 1-click installs and version updates to your Mac. With a free MacUpdate account and MacUpdate Desktop 6, Mac users can now install almost any Mac app on macupdate.... Read more
SteerMouse 4.2.2 - Powerful third-party...
SteerMouse is an advanced driver for USB and Bluetooth mice. It also supports Apple Mighty Mouse very well. SteerMouse can assign various functions to buttons that Apple's software does not allow,... Read more
iMazing 1.1 - Complete iOS device manage...
iMazing (was DiskAid) is the ultimate iOS device manager with capabilities far beyond what iTunes offers. With iMazing and your iOS device (iPhone, iPad, or iPod), you can: Copy music to and from... Read more
PopChar X 7.0 - Floating window shows av...
PopChar X helps you get the most out of your font collection. With its crystal-clear interface, PopChar X provides a frustration-free way to access any font's special characters. Expanded... Read more

Latest Forum Discussions

See All

Mystery Case Files: Dire Grove, Sacred G...
Mystery Case Files: Dire Grove, Sacred Grove HD Review By Jennifer Allen on November 28th, 2014 Our Rating: iPad Only App - Designed for the iPad A decent new installment for the popular Mystery Case Files series.   | Read more »
Castaway Paradise – Tips, Tricks, and St...
Ahoy there, castaways: Were you curious about our own thoughts regarding this pristine shipwreck? Check out our Castaway Paradise review! Castaway Paradise is out for iOS, finally giving mobile gamers the opportunity to enjoy the idyllic lifestyle... | Read more »
Castaway Paradise VIP Subs are on Sale f...
Castaway Paradise VIP Subs are on Sale for a Limited Time, and a Special Holiday Update is Coming Soon Posted by Rob Rich on November 28th, 2014 [ | Read more »
Primitive Review
Primitive Review By Jordan Minor on November 28th, 2014 Our Rating: :: FOLK ARTUniversal App - Designed for iPhone and iPad True to its name, Primitive is about as straightforward as runners get.   | Read more »
7 tips to get ahead of the competition i...
7 tips to get ahead of the competition in Dynasty of Dungeons Posted by Simon Reed on November 28th, 2014 [ permalink ] Playcrab has launched their action-packed new dungeon crawler, Dynasty of Dungeons, today. | Read more »
Master of Tea Kung Fu Review
Master of Tea Kung Fu Review By Jordan Minor on November 28th, 2014 Our Rating: :: ONE DROP RULESUniversal App - Designed for iPhone and iPad Master of Tea Kung Fu is a creative and complex caffeinated brawler.   | Read more »
Monster Strike Review
Monster Strike Review By Campbell Bird on November 28th, 2014 Our Rating: :: BILLIARD STRATEGYUniversal App - Designed for iPhone and iPad Collect monsters and battle by flinging them across the battlefield in this strangely... | Read more »
Proun+ Review
Proun+ Review By Jennifer Allen on November 28th, 2014 Our Rating: :: TWITCHY RACINGUniversal App - Designed for iPhone and iPad Twitchy racing aplenty in Proun+, an enjoyably tricky title.   | Read more »
Lucha Amigos (Games)
Lucha Amigos 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Forget Ninja Turtles, and meet Wrestlers Turtles! Crazier, Spicier and…Bouncier! Sling carapaces of 7 Luchadores to knock all... | Read more »
Record of Agarest War Zero (Games)
Record of Agarest War Zero 1.0 Device: iOS Universal Category: Games Price: $7.99, Version: 1.0 (iTunes) Description: HyperDevbox Holiday Turkey Black Friday Special Pricing! To celebrate the opening of the holiday season HyperDevbox... | Read more »

Price Scanner via MacPrices.net

Up To 75% Off Infovole Text Apps Over Black F...
Infovole’s entire range of apps, including the Textkraft family of word processors for iPads and iPhones, is being offered at 50-75% off over the Black Friday and Cyber Monday weekend. The five-day... Read more
Black Friday: Up to $60 off Mac minis, NY tax...
 B&H Photo has new 2014 Mac minis on sale for up to $60 off MSRP as part of their Black Friday sale. Shipping is free, and B&H charges NY sales tax only: - 1.4GHz Mac mini: $449.99 $50 off... Read more
Black Friday: 27-inch 5K iMac for $2299, save...
 B&H Photo continues to offer Black Friday sale prices on the 27″ 3.5GHz 5K iMac, in stock today and on sale for $2299 including free shipping plus NY sales tax only. Their price is $200 off MSRP... Read more
Karalux Announces 24K Gold-Plated iPhone 6
Karalux, a Vietnam-based jewellery firm, has launched a unique 24 karat gold-plated iPhone 6 version with gold-cast monolithic dragon on its back panel. The real 24 karat gold plated enclosure doesn’... Read more
Black Friday: 13-inch 2.6GHz Retina MacBook P...
 B&H Photo has lowered their price for the 13″ 2.6GHz/128GB Retina MacBook Pro to $1159 for Black Friday. That’s $140 off MSRP, and it’s the lowest price for this model (except for Apple’s $1099... Read more
View all the Black Friday sales on our Mac Pr...
We’ve updated our Mac Price Trackers with the latest information on prices, bundles, and availability on systems from Apple’s authorized internet/catalog resellers. View Black Friday sale prices at a... Read more
Black Friday: 11-inch MacBook Air for $779, s...
 Best Buy has lowered their price for the 2014 11″ 1.4GHz/128GB MacBook Air to $779.99 for Black Friday. That’s $120 off MSRP. Choose free shipping or free local store pickup (if available). Sale... Read more
Apple Store Black Friday sale for 2014: $100...
BLACK FRIDAY The Apple Store has posted their Black Friday deals for 2014. Receive a $100 PRODUCT(RED) branded iTunes gift card with the purchase of select Macs, $50 with iPads, and $25 with iPods,... Read more
Black Friday: 15% off iTunes Gift Cards
Staples is offering 15% off $50 and $100 iTunes Gift Cards on their online store as part of their Black Friday sale. Click here for more information. Shipping is free. Best Buy is offering $100... Read more
BEVL Releases Dock Tailored for iPhone 6 and...
Seattle based BEVL has released their first product: an iPhone dock that is divergent in build quality, rock-solid function and visual simplicity to complement the iPhone. BEVL is now accepting... Read more

Jobs Board

*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
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* 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* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.