home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / macintosh-c / macc-carbon-demos-nonbinhex.sit / macc-carbon-demos-nonbinhex / chap10-demo / AppleEvents.c < prev    next >
C/C++ Source or Header  |  2001-05-07  |  24KB  |  821 lines

  1. // *******************************************************************************************
  2. // AppleEvents.c                                                           CLASSIC EVENT MODEL
  3. // *******************************************************************************************
  4. // 
  5. // This program:
  6. //
  7. // •    Installs handlers for the required Apple events, Appearance Manager Apple events, and,
  8. //        on Mac OS X only, the Show Preferences Apple event.
  9. //
  10. // •    Responds to the receipt of required Apple events by displaying descriptive text in a
  11. //        window opened for that purpose, and by opening simulated document windows as
  12. //        appropriate.  These responses result from the user:
  13. //
  14. //        •        Double clicking on the application's icon, or selecting the icon and choosing Open
  15. //                from the Finder's File menu, thus causing the receipt of an Open Application event.
  16. //
  17. //        •        When the application is already open, double clicking on the application's icon, or
  18. //                selecting the icon and choosing Open from the Finder's File menu, thus causing the
  19. //                receipt of a Re-open    Application event.
  20. //
  21. //        •        Double clicking on one of the document icons, selecting one or both of the document
  22. //                icons and choosing Open from the Finder's File menu, or dragging one or both of the
  23. //                document icons onto the application's icon, thus causing the receipt of an Open
  24. //                Documents event.
  25. //
  26. //        •        On Mac OS 8/9, selecting one or both of the document icons and choosing Print from
  27. //                the Finder's file menu, thus causing the receipt of a Print Documents event and, if
  28. //                the application is not already running, a subsequent Quit Application event.
  29. //
  30. //        •        While the application is running, choosing Shut Down or Restart from the Finder's
  31. //                Special menu, thus causing the receipt of a Quit Application event.   
  32. //
  33. // •    Responds to the receipt of Appearance Manager Apple events (Mac OS 8/9) and the Show 
  34. //        Preferences Apple event (Mac OS X) by displaying descriptive text.
  35. //
  36. // The program, which is intended to be run as a built application rather than within
  37. // CodeWarrior, utilises the following resources:
  38. //
  39. // •    A 'plst' resource containing an information property list which provides information
  40. //        to the Mac OS X Finder.
  41. //
  42. // •    An 'icns' resource containing application and document icons for Mac OS X.
  43. //
  44. // •    'WIND' resources (purgeable, initially visible) for the descriptive text display window
  45. //         and simulated document windows.
  46. //
  47. // •    'MBAR' and 'MENU' resources (preload, non-purgeable).
  48. //
  49. // •    'STR#' resources (purgeable) for displaying error messages using StandardAlert.
  50. //
  51. // •    For Mac OS 8/9:
  52. //
  53. //        •        'ICN#', 'ics#', 'ics4', 'ics8', 'icl4', and 'icl8' resources (that is, an icon 
  54. //                family) for the application and for the application's documents. (Purgeable.)
  55. //
  56. //        •        'FREF' resources (non-purgeable) for the application and the application's 'TEXT'
  57. //                documents, which link the icons with the file types they represent, and which allow
  58. //                users to launch the application by dragging the document icons to the application 
  59. //                icon.
  60. //
  61. //        •        The application's signature resource (non-purgeable), which enables the Finder to
  62. //                identify and start up the application when the user double clicks the application's
  63. //                document icons.  
  64. //
  65. //        •        A 'BNDL' resource (non-purgeable), which groups together the application's
  66. //                signature, icon and 'FREF' resources.  
  67. //
  68. //        •        A 'hfdr' resource (purgeable), which provides the customised finder icon help 
  69. //                override help balloon for the    application icon. 
  70. //
  71. //        •        A 'vers' resource (purgeable), which provides version information via the Show Info
  72. //                window and the Version column in list view windows.
  73. //
  74. // •    A 'SIZE' resource with the acceptSuspendResumeEvents, canBackground, 
  75. //        doesActivateOnFGSwitch, and isHighLevelEventAware flags set.
  76. //
  77. // *******************************************************************************************
  78.  
  79. // ………………………………………………………………………………………………………………………………………………………………………………………………………………………… includes
  80.  
  81. #include <Carbon.h>
  82.  
  83. // …………………………………………………………………………………………………………………………………………………………………………………………………………………………… defines
  84.  
  85. #define rMenubar                            128
  86. #define mFile                                    129
  87. #define  iQuit                                12
  88. #define rDisplayWindow                128
  89. #define rDocWindow                        129
  90. #define rErrorStrings                    128
  91. #define eInstallHandler                1
  92. #define eGetRequiredParam            2
  93. #define eGetDescriptorRecord    3
  94. #define eMissedRequiredParam    4
  95. #define eCountDescripRecords    5
  96. #define eCannotOpenFile                6
  97. #define eCannotPrintFile            7
  98. #define eCannotOpenWindow            8
  99. #define eMenus                                9
  100. #define MIN(a,b)                             ((a) < (b) ? (a) : (b))
  101.  
  102. // …………………………………………………………………………………………………………………………………………………………………………………………………… global variables
  103.  
  104. WindowRef    gWindowRef;
  105. Boolean        gRunningOnX = false;
  106. Boolean        gDone;
  107. Boolean        gApplicationWasOpen    = false;
  108.  
  109. // …………………………………………………………………………………………………………………………………………………………………………………………… function prototypes
  110.  
  111. void            main                                                        (void);
  112. void            doPreliminaries                                    (void);
  113. void            doInstallAEHandlers                            (void);
  114. void            doInstallAnAEHandler                        (AEEventClass,AEEventID,void *);
  115. void            doEvents                                                (EventRecord *);
  116. OSErr            openAppEventHandler                            (AppleEvent *,AppleEvent *,SInt32);
  117. OSErr            reopenAppEventHandler                        (AppleEvent *,AppleEvent *,SInt32);
  118. OSErr            openDocsEventHandler                        (AppleEvent *,AppleEvent *,SInt32);
  119. OSErr            printDocsEventHandler                        (AppleEvent *,AppleEvent *,SInt32);
  120. OSErr            quitAppEventHandler                            (AppleEvent *,AppleEvent *,SInt32);
  121. OSErr            sysFontChangeEventHandler                (AppleEvent *,AppleEvent *,SInt32);
  122. OSErr            smallSysFontChangeEventHandler    (AppleEvent *,AppleEvent *,SInt32);
  123. OSErr            viewsFontChangeEventHandler            (AppleEvent *,AppleEvent *,SInt32);
  124. OSErr            showPreferencesEventHandler            (AppleEvent *,AppleEvent *,SInt32);
  125. OSErr            doHasGotRequiredParams                    (AppleEvent *);
  126. Boolean        doOpenFile                                            (FSSpec *,SInt32,SInt32);
  127. Boolean        doPrintFile                                            (FSSpec *,SInt32,SInt32);
  128. void            doPrepareToTerminate                        (void);
  129. WindowRef    doNewWindow                                            (void);
  130. void            doMenuChoice                                        (SInt32);
  131. void            doErrorAlert                                        (SInt16);
  132. void            doDrawText                                            (Str255);
  133. void            doConcatPStrings                                (Str255,Str255);
  134.  
  135. // ************************************************************************************** main
  136.  
  137. void  main(void)
  138. {
  139.     Rect                    portRect;
  140.     RGBColor            foreColour = { 0xFFFF,0xFFFF,0xFFFF };
  141.     RGBColor            backColour = { 0x4444,0x4444,0x9999 };
  142.     MenuBarHandle    menubarHdl;
  143.     SInt32                response;
  144.     MenuRef                menuRef;
  145.     EventRecord        eventStructure;
  146.     
  147.     // ……………………………………………………………………………………………………………………………………………………………………………………………… do preliminaries
  148.  
  149.     doPreliminaries();
  150.  
  151.     // ……………………………………………………………………………………………………………………………………………………………………… set up menu bar and menus
  152.  
  153.     menubarHdl = GetNewMBar(rMenubar);
  154.     if(menubarHdl == NULL)
  155.         doErrorAlert(eMenus);
  156.     SetMenuBar(menubarHdl);
  157.     DrawMenuBar();
  158.  
  159.     Gestalt(gestaltMenuMgrAttr,&response);
  160.     if(response & gestaltMenuMgrAquaLayoutMask)
  161.     {
  162.         menuRef = GetMenuRef(mFile);
  163.         if(menuRef != NULL)
  164.         {
  165.             DeleteMenuItem(menuRef,iQuit);
  166.             DeleteMenuItem(menuRef,iQuit - 1);
  167.             DisableMenuItem(menuRef,0);
  168.         }
  169.  
  170.         gRunningOnX = true;
  171.  
  172.         EnableMenuCommand(NULL,kAEShowPreferences);
  173.     }
  174.  
  175.     // ……………………………………………………………………………………………………………………………………………………………………………………………………… open a window
  176.  
  177.     if(!(gWindowRef = GetNewCWindow(rDisplayWindow,NULL,(WindowRef) -1)))
  178.     {
  179.         doErrorAlert(eCannotOpenWindow);
  180.         ExitToShell();
  181.     }
  182.  
  183.     SetPortWindowPort(gWindowRef);
  184.     TextSize(10);
  185.     TextFace(bold);
  186.     RGBBackColor(&backColour);
  187.     RGBForeColor(&foreColour);
  188.     GetWindowPortBounds(gWindowRef,&portRect);
  189.     EraseRect(&portRect);
  190.  
  191.     // ……………………………………………………………………………………………………………………………………………………………… install Apple event handlers
  192.  
  193.     doInstallAEHandlers();
  194.  
  195.     // ……………………………………………………………………………………………………………………………………………………………………………………………………………… event loop
  196.     
  197.     gDone = false;
  198.  
  199.     while(!gDone)
  200.     {
  201.         if(WaitNextEvent(everyEvent,&eventStructure,180,NULL))
  202.             doEvents(&eventStructure);
  203.     }
  204. }
  205.  
  206. // *************************************************************************** doPreliminaries
  207.  
  208. void  doPreliminaries(void)
  209. {
  210.     MoreMasterPointers(64);
  211.     InitCursor();
  212.     FlushEvents(everyEvent,0);
  213. }
  214.  
  215. // *********************************************************************** doInstallAEHandlers
  216.  
  217. void  doInstallAEHandlers(void)
  218. {
  219.     // ………………………………………………………………………………………………………………………………………………………………………………… required Apple events
  220.  
  221.     doInstallAnAEHandler(kCoreEventClass,kAEOpenApplication,openAppEventHandler);
  222.     doInstallAnAEHandler(kCoreEventClass,kAEReopenApplication,reopenAppEventHandler);
  223.     doInstallAnAEHandler(kCoreEventClass,kAEOpenDocuments,openDocsEventHandler);
  224.     doInstallAnAEHandler(kCoreEventClass,kAEPrintDocuments,printDocsEventHandler);
  225.     doInstallAnAEHandler(kCoreEventClass,kAEQuitApplication,quitAppEventHandler);
  226.  
  227.     // ……………………………………………………………………………………………………………………………………………………… Appearance Manager Apple events
  228.  
  229.     doInstallAnAEHandler(kAppearanceEventClass,kAESystemFontChanged,sysFontChangeEventHandler);
  230.     doInstallAnAEHandler(kAppearanceEventClass,kAESmallSystemFontChanged,
  231.                                              smallSysFontChangeEventHandler);
  232.     doInstallAnAEHandler(kAppearanceEventClass,kAEViewsFontChanged,viewsFontChangeEventHandler);
  233.  
  234.     // ……………………………………………………………………………………………………………………………………………………………… Show Preferences Apple event
  235.  
  236.     if(gRunningOnX)
  237.         doInstallAnAEHandler(kCoreEventClass,kAEShowPreferences,showPreferencesEventHandler);
  238. }
  239.  
  240. // ********************************************************************** doInstallAnAEHandler
  241.  
  242. void  doInstallAnAEHandler(AEEventClass eventClass,AEEventID eventID,void *theHandler)
  243. {
  244.     OSErr    osError;
  245.  
  246.     osError = AEInstallEventHandler(eventClass,eventID,
  247.                                                                     NewAEEventHandlerUPP((AEEventHandlerProcPtr) theHandler),
  248.                                                                     0L,false);
  249.     if(osError != noErr)
  250.         doErrorAlert(eInstallHandler);
  251. }
  252.  
  253. // ********************************************************************************** doEvents
  254.  
  255. void    doEvents(EventRecord *eventStrucPtr)
  256. {
  257.     WindowPartCode    partCode;
  258.     WindowRef                windowRef;
  259.     SInt32                    menuChoice;
  260.  
  261.     switch(eventStrucPtr->what)
  262.     {
  263.         case kHighLevelEvent:
  264.             AEProcessAppleEvent(eventStrucPtr);
  265.             break;
  266.  
  267.         case mouseDown:
  268.             partCode = FindWindow(eventStrucPtr->where,&windowRef);
  269.             switch(partCode)
  270.             {
  271.                 case inMenuBar:
  272.                     menuChoice = MenuSelect(eventStrucPtr->where);
  273.                     doMenuChoice(menuChoice);
  274.                     break;
  275.  
  276.                 case inDrag:
  277.                     DragWindow(windowRef,eventStrucPtr->where,NULL);
  278.                     break;
  279.  
  280.                 case inContent:
  281.                     if(windowRef != FrontWindow())
  282.                         SelectWindow(windowRef);
  283.                     break;
  284.                     
  285.                 case inGoAway:
  286.                     DisposeWindow(windowRef);
  287.                     break;
  288.             }
  289.             break;
  290.  
  291.         case keyDown:
  292.             if((eventStrucPtr->modifiers & cmdKey) != 0)
  293.                 doMenuChoice(MenuEvent(eventStrucPtr));
  294.             break;
  295.  
  296.         case updateEvt:
  297.             BeginUpdate((WindowRef)eventStrucPtr->message);
  298.             EndUpdate((WindowRef)eventStrucPtr->message);
  299.             break;
  300.     }
  301. }
  302.     
  303. // *********************************************************************** openAppEventHandler
  304.  
  305. OSErr  openAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefCon)
  306. {
  307.     OSErr            osError;
  308.     WindowRef    windowRef;
  309.  
  310.     gApplicationWasOpen = true;
  311.  
  312.     osError = doHasGotRequiredParams(appEvent);
  313.  
  314.     if(osError == noErr)
  315.     {
  316.         doDrawText("\pReceived an Apple event: OPEN APPLICATION.");
  317.         doDrawText("\p    • Opening an untitled window in response.");
  318.  
  319.         windowRef = doNewWindow();
  320.         SetWTitle(windowRef,"\puntitled");
  321.     }
  322.  
  323.     return osError;
  324. }
  325.  
  326. // ********************************************************************* reopenAppEventHandler
  327.  
  328. OSErr  reopenAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefCon)
  329. {
  330.     OSErr            osError;
  331.     WindowRef    windowRef;
  332.  
  333.     osError = doHasGotRequiredParams(appEvent);
  334.  
  335.     if(osError == noErr)
  336.     {
  337.         doDrawText("\pReceived an Apple event: RE-OPEN APPLICATION.");
  338.         doDrawText("\p    • I will check whether I have any windows open.");
  339.  
  340.         windowRef = GetWindowList();
  341.  
  342.         if((windowRef = GetNextWindow(windowRef)) == NULL)
  343.         {
  344.             doDrawText("\p      No windows are open, so I will open a window.");
  345.  
  346.             windowRef = doNewWindow();
  347.             SetWTitle(windowRef,"\puntitled 1");
  348.         }
  349.         else
  350.             doDrawText("\p      A window is open, so I won't open another.");
  351.     }
  352.  
  353.     return osError;
  354. }
  355.  
  356. // ********************************************************************** openDocsEventHandler
  357.  
  358. OSErr  openDocsEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
  359. {
  360.     AEDescList    docList;
  361.     OSErr                osError, ignoreErr;
  362.     SInt32            numberOfItems, index;
  363.     DescType        returnedType;
  364.     FSSpec            fileSpec;
  365.     AEKeyword        keyWord;
  366.     Size                actualSize;
  367.     Boolean            result;
  368.  
  369.     osError = AEGetParamDesc(appEvent,keyDirectObject,typeAEList,&docList);
  370.  
  371.     if(osError == noErr)
  372.     {
  373.         osError = doHasGotRequiredParams(appEvent);
  374.         if(osError == noErr)
  375.         {
  376.             osError = AECountItems(&docList,&numberOfItems);
  377.             if(osError == noErr)
  378.             {
  379.                 for(index=1;index<=numberOfItems;index++)
  380.                 {
  381.                     osError = AEGetNthPtr(&docList,index,typeFSS,&keyWord,&returnedType,&fileSpec,
  382.                                                                 sizeof(fileSpec),&actualSize);
  383.                     if(osError == noErr)
  384.                     {
  385.                         if(!(result = doOpenFile(&fileSpec,index,numberOfItems)))
  386.                             doErrorAlert(eCannotOpenFile);
  387.                     }
  388.                     else
  389.                         doErrorAlert(eGetDescriptorRecord);
  390.                 }
  391.             }
  392.             else
  393.                 doErrorAlert(eCountDescripRecords);
  394.         }
  395.         else
  396.             doErrorAlert(eMissedRequiredParam);
  397.  
  398.         ignoreErr = AEDisposeDesc(&docList);
  399.     }
  400.     else
  401.         doErrorAlert(eGetRequiredParam);
  402.  
  403.     return osError;
  404. }
  405.  
  406. // ********************************************************************* printDocsEventHandler
  407.  
  408. OSErr  printDocsEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
  409. {
  410.     AEDescList    docList;
  411.     OSErr                osError, ignoreErr;
  412.     SInt32            numberOfItems, index;
  413.     DescType        returnedType;
  414.     FSSpec            fileSpec;
  415.     AEKeyword        keyWord;
  416.     Size                actualSize;
  417.     Boolean            result;
  418.     
  419.     osError = AEGetParamDesc(appEvent,keyDirectObject,typeAEList,&docList);
  420.  
  421.     if(osError == noErr)
  422.     {
  423.         osError = doHasGotRequiredParams(appEvent);
  424.         if(osError == noErr)
  425.         {
  426.             osError = AECountItems(&docList,&numberOfItems);
  427.             if(osError == noErr)
  428.             {
  429.                 for(index=1;index<=numberOfItems;index++)
  430.                 {
  431.                     osError = AEGetNthPtr(&docList,index,typeFSS,&keyWord,&returnedType,&fileSpec,
  432.                                                             sizeof(fileSpec),&actualSize);
  433.                     if(osError == noErr)
  434.                     {
  435.                         if(!(result = doPrintFile(&fileSpec,index,numberOfItems)))
  436.                             doErrorAlert(eCannotPrintFile);
  437.                     }
  438.                     else
  439.                         doErrorAlert(eGetDescriptorRecord);
  440.                 }
  441.             }
  442.             else
  443.                 doErrorAlert(eCountDescripRecords);
  444.         }
  445.         else
  446.             doErrorAlert(eMissedRequiredParam);
  447.  
  448.         ignoreErr = AEDisposeDesc(&docList);
  449.     }
  450.     else
  451.         doErrorAlert(eGetRequiredParam);
  452.  
  453.     return osError;
  454. }
  455.  
  456. // *********************************************************************** quitAppEventHandler
  457.  
  458. OSErr  quitAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
  459. {
  460.     OSErr    osError;
  461.  
  462.     osError = doHasGotRequiredParams(appEvent);
  463.  
  464.     if(osError == noErr)
  465.         doPrepareToTerminate();
  466.  
  467.     return osError;
  468. }
  469.  
  470. // ***************************************************************** sysFontChangeEventHandler
  471.  
  472. OSErr  sysFontChangeEventHandler(AppleEvent *appEvent,AppleEvent *reply,
  473.                                                                  SInt32 handlerRefcon)
  474. {
  475.     OSErr        osError;
  476.     Rect        portRect;
  477.     Str255    fontName, theString = "\p   Current large system font is: ";
  478.  
  479.     osError = doHasGotRequiredParams(appEvent);
  480.  
  481.     if(osError == noErr)
  482.     {
  483.         GetWindowPortBounds(gWindowRef,&portRect);
  484.         EraseRect(&portRect);
  485.         doDrawText("\pReceived an Apple event: LARGE SYSTEM FONT CHANGED.");
  486.         GetThemeFont(kThemeSystemFont,smSystemScript,fontName,NULL,NULL);
  487.         doConcatPStrings(theString,fontName);
  488.         doDrawText(theString);
  489.         // Action as required by application.
  490.     }
  491.  
  492.     return osError;
  493. }
  494.  
  495. // ************************************************************ smallSysFontChangeEventHandler
  496.  
  497. OSErr  smallSysFontChangeEventHandler(AppleEvent *appEvent,AppleEvent *reply,
  498.                                                                             SInt32 handlerRefcon)
  499. {
  500.     OSErr        osError;
  501.     Rect        portRect;
  502.     Str255    fontName, theString = "\p   Current small system font is: ";
  503.     
  504.     osError = doHasGotRequiredParams(appEvent);
  505.  
  506.     if(osError == noErr)
  507.     {
  508.         GetWindowPortBounds(gWindowRef,&portRect);
  509.         EraseRect(&portRect);
  510.         doDrawText("\pReceived an Apple event: SMALL SYSTEM FONT CHANGED.");
  511.         GetThemeFont(kThemeSmallSystemFont,smSystemScript,fontName,NULL,NULL);
  512.         doConcatPStrings(theString,fontName);
  513.         doDrawText(theString);
  514.         // Action as required by application.
  515.     }
  516.  
  517.     return osError;
  518. }
  519.  
  520. // *************************************************************** viewsFontChangeEventHandler
  521.  
  522. OSErr  viewsFontChangeEventHandler(AppleEvent *appEvent,AppleEvent *reply,
  523.                                                                      SInt32 handlerRefcon)
  524. {
  525.     OSErr        osError;
  526.     Rect        portRect;
  527.     Str255    fontName, fontSizeString, theString = "\p   Current views font is: ";
  528.     SInt16    fontSize;
  529.  
  530.     osError = doHasGotRequiredParams(appEvent);
  531.  
  532.     if(osError == noErr)
  533.     {
  534.         GetWindowPortBounds(gWindowRef,&portRect);
  535.         EraseRect(&portRect);
  536.         doDrawText("\pReceived an Apple event: VIEWS FONT CHANGED.");
  537.         GetThemeFont(kThemeViewsFont,smSystemScript,fontName,&fontSize,NULL);
  538.         doConcatPStrings(theString,fontName);
  539.         doConcatPStrings(theString,"\p ");
  540.         NumToString((SInt32) fontSize,fontSizeString);
  541.         doConcatPStrings(theString,fontSizeString);
  542.         doConcatPStrings(theString,"\p point");
  543.         doDrawText(theString);
  544.         // Action as required by application.
  545.     }
  546.  
  547.     return osError;
  548. }
  549.  
  550. // *************************************************************** showPreferencesEventHandler
  551.  
  552. OSErr  showPreferencesEventHandler(AppleEvent *appEvent,AppleEvent *reply,
  553.                                                                      SInt32 handlerRefcon)
  554. {
  555.     OSErr    osError;
  556.     Rect    portRect;
  557.  
  558.     osError = doHasGotRequiredParams(appEvent);
  559.  
  560.     if(osError == noErr)
  561.     {
  562.         GetWindowPortBounds(gWindowRef,&portRect);
  563.         EraseRect(&portRect);
  564.         doDrawText("\pReceived an Apple event: SHOW PREFERENCES.");
  565.         doDrawText("\p    • I would present a Preferences... dialog now.");
  566.     }
  567.  
  568.     return osError;
  569. }
  570.  
  571. // ******************************************************************** doHasGotRequiredParams
  572.  
  573. OSErr  doHasGotRequiredParams(AppleEvent *appEvent)
  574. {
  575.     OSErr            osError;    
  576.     DescType    returnedType;
  577.     Size            actualSize;
  578.  
  579.     osError = AEGetAttributePtr(appEvent,keyMissedKeywordAttr,typeWildCard,&returnedType,NULL,0,
  580.                                                             &actualSize);
  581.  
  582.     if(osError == errAEDescNotFound)
  583.         osError = noErr;
  584.     else if(osError == noErr)
  585.         osError = errAEParamMissed;
  586.  
  587.     return osError;
  588. }
  589.  
  590. // ******************************************************************************** doOpenFile
  591.  
  592. Boolean  doOpenFile(FSSpec *fileSpecPtr,SInt32 index,SInt32 numberOfItems)
  593. {
  594.     WindowRef    windowRef;
  595.  
  596.     gApplicationWasOpen = true;
  597.  
  598.     if(index == 1)
  599.         doDrawText("\pReceived an Apple event: OPEN DOCUMENTS.");
  600.  
  601.     if(numberOfItems == 1)
  602.     {
  603.         doDrawText("\p    • The file to open is: ");
  604.         DrawString(fileSpecPtr->name);
  605.         doDrawText("\p    • Opening titled window in response.");
  606.     }
  607.     else
  608.     {
  609.         if(index == 1)
  610.         {        
  611.             doDrawText("\p    • The files to open are: ");
  612.             DrawString(fileSpecPtr->name);
  613.         }
  614.         else
  615.         {
  616.             DrawString("\p and ");
  617.             DrawString(fileSpecPtr->name);
  618.             doDrawText("\p    • Opening titled windows in response.");
  619.         }
  620.     }
  621.  
  622.     if(windowRef = doNewWindow())
  623.     {
  624.         SetWTitle(windowRef,fileSpecPtr->name);
  625.         return true;
  626.     }
  627.     else
  628.         return false;
  629. }
  630.  
  631. // ******************************************************************************* doPrintFile
  632.  
  633. Boolean  doPrintFile(FSSpec *fileSpecPtr,SInt32 index,SInt32 numberOfItems)
  634. {
  635.     WindowRef    windowRef;
  636.     UInt32        finalTicks;
  637.  
  638.     if(index == 1)
  639.         doDrawText("\pReceived an Apple event: PRINT DOCUMENTS");
  640.  
  641.     if(numberOfItems == 1)
  642.     {
  643.         doDrawText("\p    • The file to print is: ");
  644.         DrawString(fileSpecPtr->name);
  645.         windowRef = doNewWindow();
  646.         SetWTitle(windowRef,fileSpecPtr->name);
  647.         Delay(60,&finalTicks);
  648.         doDrawText("\p    • I would present the Print dialog first and then print");
  649.         doDrawText("\p       the document when the user has made his settings.");
  650.         Delay(60,&finalTicks);
  651.         doDrawText("\p    • Assume that I am now printing the document.");
  652.     }
  653.     else
  654.     {
  655.         if(index == 1)
  656.         {        
  657.             doDrawText("\p    • The first file to print is: ");
  658.             DrawString(fileSpecPtr->name);
  659.             doDrawText("\p       I would present the Print dialog for the first file");
  660.             doDrawText("\p       only and use the user's settings to print both files.");
  661.         }
  662.         else
  663.         {
  664.             doDrawText("\p    • The second file to print is: ");
  665.             DrawString(fileSpecPtr->name);
  666.             doDrawText("\p       I am using the Print dialog settings used for the");
  667.             doDrawText("\p       first file.");
  668.         }
  669.  
  670.         windowRef = doNewWindow();
  671.         SetWTitle(windowRef,fileSpecPtr->name);
  672.         doDrawText("\p    • Assume that I am now printing the document.");
  673.     }
  674.  
  675.     if(numberOfItems == index)
  676.     {
  677.         if(!gApplicationWasOpen)
  678.         {
  679.             doDrawText("\p       Since the application was not already open, I expect to"); 
  680.             doDrawText("\p       receive a QUIT APPLICATION event when I have finished.");
  681.         }
  682.         else
  683.         {
  684.             doDrawText("\p       Since the application was already open, I do NOT expect"); 
  685.             doDrawText("\p       to receive a QUIT APPLICATION event when I have finished.");
  686.         }
  687.  
  688.         Delay(180,&finalTicks);
  689.         doDrawText("\p    • Finished print job.");
  690.     }
  691.     else
  692.         Delay(180, &finalTicks);
  693.  
  694.     DisposeWindow(windowRef);
  695.     return true;
  696. }
  697.  
  698. // ********************************************************************** doPrepareToTerminate
  699.  
  700. void  doPrepareToTerminate(void)
  701. {
  702.     UInt32    finalTicks;
  703.  
  704.     doDrawText("\pReceived an Apple event: QUIT APPLICATION");
  705.  
  706.     if(gApplicationWasOpen)
  707.     {
  708.         doDrawText("\p    • I would now ask the user to save any unsaved files before");
  709.         doDrawText("\p       terminating myself in response to the event.");
  710.         doDrawText("\p    • Click the mouse when ready to terminate.");
  711.         while(!Button()) ;
  712.     }
  713.     else
  714.     {
  715.         doDrawText("\p    • Terminating myself in response");
  716.         Delay(240,&finalTicks);
  717.     }
  718.  
  719.     // If the user did not click the Cancel button in a Save dialog:
  720.  
  721.     gDone = true;
  722. }
  723.  
  724. // ******************************************************************************* doNewWindow
  725.  
  726. WindowRef  doNewWindow(void)
  727. {
  728.     WindowRef    windowRef;
  729.  
  730.     if(!(windowRef = GetNewCWindow(rDocWindow,NULL,(WindowRef) -1)))
  731.         doErrorAlert(eCannotOpenWindow);
  732.  
  733.     return windowRef;
  734. }
  735.  
  736. // ****************************************************************************** doMenuChoice
  737.  
  738. void  doMenuChoice(SInt32 menuChoice)
  739. {
  740.     MenuID                menuID;
  741.     MenuItemIndex    menuItem;
  742.     
  743.     menuID     = HiWord(menuChoice);
  744.     menuItem = LoWord(menuChoice);
  745.  
  746.     if(menuID == 0)
  747.         return;
  748.  
  749.     switch(menuID)
  750.     {
  751.         case mFile:
  752.             if(menuItem  == iQuit)
  753.                 gDone = true;
  754.             break;
  755.     }
  756.  
  757.     HiliteMenu(0);
  758. }
  759.  
  760. // ****************************************************************************** doErrorAlert
  761.  
  762. void  doErrorAlert(SInt16 errorType)
  763. {
  764.     Str255    errorString;
  765.     SInt16    itemHit;
  766.  
  767.     GetIndString(errorString,rErrorStrings,errorType);
  768.  
  769.     if(errorType < 7)
  770.         StandardAlert(kAlertCautionAlert,errorString,NULL,NULL,&itemHit);
  771.     else
  772.     {
  773.         StandardAlert(kAlertStopAlert,errorString,NULL,NULL,&itemHit);
  774.         ExitToShell();
  775.     }
  776. }
  777.  
  778. // ******************************************************************************** doDrawText
  779.  
  780. void    doDrawText(Str255 eventString)
  781. {
  782.     RgnHandle    tempRegion;
  783.     SInt16        a;
  784.     Rect            portRect;
  785.     UInt32        finalTicks;
  786.  
  787.     tempRegion = NewRgn();
  788.     GetWindowPortBounds(gWindowRef,&portRect);
  789.  
  790.     for(a=0;a<15;a++)
  791.     {
  792.         ScrollRect(&portRect,0,-1,tempRegion);
  793.         QDFlushPortBuffer(GetWindowPort(gWindowRef),NULL);
  794.  
  795.         Delay(4,&finalTicks);
  796.     }
  797.  
  798.     DisposeRgn(tempRegion);
  799.  
  800.     MoveTo(8,160);
  801.     DrawString(eventString);
  802.     QDFlushPortBuffer(GetWindowPort(gWindowRef),NULL);
  803. }
  804.  
  805. // ************************************************************************** doConcatPStrings
  806.  
  807. void  doConcatPStrings(Str255 targetString,Str255 appendString)
  808. {
  809.     SInt16    appendLength;
  810.  
  811.     appendLength = MIN(appendString[0],255 - targetString[0]);
  812.  
  813.     if(appendLength > 0)
  814.     {
  815.         BlockMoveData(appendString+1,targetString+targetString[0]+1,(SInt32) appendLength);
  816.         targetString[0] += appendLength;
  817.     }
  818. }
  819.  
  820. // *******************************************************************************************
  821.