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
$116.17
Apple Inc.
-0.14
MSFT
$47.65
Microsoft Corpora
-1.05
GOOG
$537.79
Google Inc.
+2.96

MacTech Search:
Community Search:

Software Updates via MacUpdate

StatsBar 1.9 - Monitor system processes...
StatsBar gives you a comprehensive and detailed analysis of the following areas of your Mac: CPU usage Memory usage Disk usage Network and bandwidth usage Battery power and health (MacBooks only)... Read more
Cyberduck 4.6 - FTP and SFTP browser. (F...
Cyberduck is a robust FTP/FTP-TLS/SFTP browser for the Mac whose lack of visual clutter and cleverly intuitive features make it easy to use. Support for external editors and system technologies such... Read more
Maya 2015 - Professional 3D modeling and...
Maya is an award-winning software and powerful, integrated 3D modeling, animation, visual effects, and rendering solution. Because Maya is based on an open architecture, all your work can be scripted... Read more
Evernote 6.0.1 - 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
calibre 2.11 - Complete e-library manage...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital... Read more
Herald 5.0.1 - Notification plugin for M...
Note: Versions 2.1.3 (for OS X 10.7), 3.0.6 (for OS X 10.8), and 4.0.8 (for OS X 10.9) are no longer supported by the developer. Herald is a notification plugin for Mail.app, Apple's Mac OS X email... Read more
Firetask 3.7 - Innovative task managemen...
Firetask uniquely combines the advantages of classical priority-and-due-date-based task management with GTD. Stay focused and on top of your commitments - Firetask's "Today" view shows all relevant... Read more
TechTool Pro 7.0.6 - Hard drive and syst...
TechTool Pro is now 7, and this is the most advanced version of the acclaimed Macintosh troubleshooting utility created in its 20-year history. Micromat has redeveloped TechTool Pro 7 to be fully 64... Read more
PhotoDesk 3.0.1 - Instagram client for p...
PhotoDesk lets you view, like, comment, and download Instagram pictures/videos! (NO Uploads! / Image Posting! Instagram forbids that! AND you *need* an *existing* Instagram account). But you can do... Read more
SuperDuper! 2.7.3 - Advanced disk clonin...
SuperDuper! is an advanced, yet easy to use disk copying program. It can, of course, make a straight copy, or "clone" -- useful when you want to move all your data from one machine to another, or do... Read more

Latest Forum Discussions

See All

Golfinity – Tips, Tricks, Strategies, an...
Dig this: Would you like to know what we thought of being an infinite golfer? Check out our Golfinity review! Golfinity offers unlimited ways to test your skills at golf. Here are a few ways to make sure your score doesn’t get too high and your... | Read more »
Dark Hearts, The Sequel to Haunting Meli...
Dark Hearts, The Sequel to Haunting Melissa, is Available Now Posted by Jessica Fisher on November 21st, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Meowza! Toyze Brings Talking Tom to Life...
Meowza! | Read more »
Square Enix Announces New Tactical RPG f...
Square Enix Announces New Tactical RPG for Mobile, Heavenstrike Rivals. Posted by Jessica Fisher on November 21st, 2014 [ permalink ] With their epic stories and gorgeous graphics, | Read more »
Quest for Revenge (Games)
Quest for Revenge 1.0.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.0 (iTunes) Description: The great Kingdom of the west has fallen. The gods ignore the prayers of the desperate. A dark warlord has extinguished... | Read more »
Threadz is a New Writing Adventure for Y...
Threadz is a New Writing Adventure for You and Your Friends Posted by Jessica Fisher on November 21st, 2014 [ permalink ] In the tradition of round-robin storytelling, | Read more »
SteelSeries Stratus XL Hardware Review
Made by: SteelSeries Price: $59.99 Hardware/iOS Integration Rating: 4 out of 5 stars Usability Rating: 4.5 out of 5 stars Reuse Value Rating: 4.25 out of 5 stars Build Quality Rating: 4.5 out of 5 stars Overall Rating: 4.31 out of 5 stars | Read more »
ACDSee (Photography)
ACDSee 1.0.0 Device: iOS iPhone Category: Photography Price: $1.99, Version: 1.0.0 (iTunes) Description: Capture, perfect, and share your photos with ACDSee. The ACDSee iPhone app combines an innovative camera, a powerful photo... | Read more »
ProTube for YouTube (Entertainment)
ProTube for YouTube 2.0.2 Device: iOS Universal Category: Entertainment Price: $1.99, Version: 2.0.2 (iTunes) Description: ProTube is the ultimate, fully featured YouTube app. With it's highly polished design, ProTube offers ad-free... | Read more »
Weather or Not - Reports and Forecasts...
Weather or Not - Reports and Forecasts for your Calendar 1.0.0 Device: iOS iPhone Category: Weather Price: $2.99, Version: 1.0.0 (iTunes) Description: Weather or Not is a beautiful and intuitive way to check the weather and... | Read more »

Price Scanner via MacPrices.net

New 13-inch 1.4GHz MacBook Air on sale for $8...
 Adorama has the 2014 13″ 1.4GHz/128GB MacBook Air on sale for $899.99 including free shipping plus NY & NJ tax only. Their price is $100 off MSRP. B&H Photo has the 13″ 1.4GHz/128GB MacBook... Read more
Apple Expected to Reverse Nine-Month Tablet S...
Apple and Samsung combined accounted for 62 percent of the nearly 36 million branded tablets shipped in 3Q 2014, according to early vendor shipment share estimates from market intelligence firm ABI... Read more
Stratos: 30 Percent of US Smartphone Owners t...
Stratos, Inc., creator of the Bluetooth Connected Card Platform, has announced results from its 2014 Holiday Mobile Payments Survey. The consumer survey found that nearly one out of three (30 percent... Read more
2014 1.4GHz Mac mini on sale for $449, save $...
 B&H Photo has lowered their price on the new 1.4GHz Mac mini to $449.99 including free shipping plus NY tax only. Their price is $50 off MSRP, and it’s the lowest price available for this new... Read more
64GB iPod touch on sale for $249, save $50
Best Buy has the 64GB iPod touch on sale for $249 on their online store for a limited time. Their price is $50 off MSRP. Choose free shipping or free local store pickup (if available). Sale price for... Read more
15″ 2.2GHz Retina MacBook Pro on sale for $17...
 B&H Photo has the 2014 15″ 2.2GHz Retina MacBook Pro on sale for $1799.99 for a limited time. Shipping is free, and B&H charges NY sales tax only. B&H will also include free copies of... Read more
New Logitech AnyAngle Case/Stand Brings Flexi...
Logitec has announced the newest addition to its suite of tablet products — the Logitech AnyAngle. A protective case with an any-angle stand for iPad Air 2 and all iPad mini models, AnyAngle is the... Read more
2013 15-inch 2.0GHz Retina MacBook Pro availa...
B&H Photo has leftover previous-generation 15″ 2.0GHz Retina MacBook Pros available for $1499 including free shipping plus NY sales tax only. Their price is $500 off original MSRP. B&H will... Read more
16GB Retina iPad mini on sale today for $199,...
 Staples has 2nd generation 16GB Retina iPad minis on sale for $199 on their online store for a limited time. Their price is $100 off MSRP. Choose free shipping or free local store pickup (if... Read more
Developers Start Designing Apps for Apple Wat...
Apple has announced the availability of WatchKit, software that gives developers a set of tools to easily create experiences designed specifically for Apple Watch. Apple’s developer community can now... Read more

Jobs Board

*Apple* Solutions Consultant (ASC)- Retail S...
**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, *Apple* Financial Services...
**Job Summary** Apple Financial Services (AFS) offers consumers, businesses and educational institutions ways to finance Apple purchases. We work with national and Read more
*Apple* Store Leader Program - College Gradu...
Job Description: Job Summary As an Apple Store Leader Program agent, you can continue your education as you major in the art of leadership at the Apple Store. You'll 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
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
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.