home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / macintosh-pascal / macintoshp-1.2-demos.sit.hqx / chap08pascal_demo / AppleEventsPascal.p next >
Text File  |  1999-04-05  |  19KB  |  727 lines

  1. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊
  2. // AppleEventsPascal.p
  3. // ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊
  4. // 
  5. // 
  6. // This program:
  7. //
  8. // •    Installs handlers for the required Apple events.
  9. //
  10. // •    Responds to the receipt of required Apple events by displaying descriptive text in
  11. //        a 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
  15. //                Open from the Finder's File menu, thus causing the receipt of an Open
  16. //                Application event.
  17. //
  18. //        •        Double clicking on one of the document icons, selecting one or both of the
  19. //                document icons and choosing Open from the Finder's File menu, or dragging one
  20. //                or both of the document icons onto the application's icon, thus causing the
  21. //                receipt of an Open Documents event.
  22. //
  23. //        •        Selecting one or both of the document icons and choosing Print from the
  24. //                Finder's file menu, thus causing the receipt of a Print Documents event and,
  25. //                if the application was not already running, a subsequent Quit Application event.
  26. //
  27. //        •        While the application is running, choosing Shut Down or Restart from the
  28. //                Finder's Special menu, thus causing the receipt of a Quit Application event.   
  29. //
  30. // The program, which is intended to be run as a built application and not from within
  31. // CodeWarrior, utilises the following resources:
  32. //
  33. // •    'WIND' resources (purgeable) (initially visible) for the descriptive text display
  34. //        window and simulated document windows.
  35. //
  36. // •    'MBAR' and 'MENU' resources (preload, non-purgeable).
  37. //
  38. // •    An 'ALRT' resource, and associated 'DITL' and 'STR#' resources, for displaying
  39. //        error messages (purgeable).
  40. //
  41. // •    'ICN#', 'ics#', 'ics4', 'ics8', 'icl4', and 'icl8' resources (that is, an icon
  42. //        family) for the application and for the application's documents. (Purgeable.)
  43. //
  44. // •    'FREF' resources for the application and the application's 'TEXT' documents, which
  45. //        link the icons with the file types they represent, and which allow users to launch
  46. //        the application by dragging the document icons to the application icon.  (Non-
  47. //        purgeable.)
  48. //
  49. // •    The application's signature resource (non-purgeable), which enables the Finder to
  50. //        identify and start up the application when the user double clicks the application's
  51. //        document icons.  
  52. //
  53. // •    A 'BNDL' resource (non-purgeable), which groups together the application's
  54. //        signature, icon and 'FREF' resources.  
  55. //
  56. // •    An 'hfdr' resource (purgeable), which provides the customised help balloon for the
  57. //        application icon. 
  58. //
  59. // •    A 'vers' resource (purgeable), which allows users to ascertain the version number
  60. //        of the application.
  61. //
  62. // •    A 'SIZE' resource with the isHighLevelEventAware,    acceptSuspendResumeEvents, and
  63. //        and is32BitCompatible flags set.
  64. //
  65. // ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ }
  66.  
  67. program AppleEventsPascal(input, output);
  68.  
  69. { ………………………………………………………………………………………………………………… include the following Universal Interfaces }
  70.  
  71. uses
  72.  
  73.     Windows, Fonts, Menus, TextEdit, Quickdraw, Dialogs, QuickdrawText, Processes, Types,
  74.     Memory, Events, TextUtils, ToolUtils, OSUtils, Devices, AppleEvents, Errors, Files,
  75.     EPPC, Segload;
  76.  
  77. { ………………………………………………………………………………………………………………………………………………… define the following constants }
  78.  
  79. const
  80.  
  81. mApple = 128;
  82. mFile = 129;
  83.      iQuit = 11;
  84. rMenubar = 128;
  85. rDisplayWindow = 128;
  86. rDocWindow = 129;
  87. rErrorAlert = 128;
  88. rErrorStrings = 128;
  89. eInstallHandler = 1;
  90. eGetRequiredParam = 2;
  91. eGetDescriptorRecord = 3;
  92. eMissedRequiredParam = 4;
  93. eCannotOpenFile = 5;
  94. eCannotPrintFile = 6;
  95. eCannotOpenWindow = 7;
  96. eMenus = 8;
  97.  
  98. { ……………………………………………………………………………………………………………………………………………………………………………………… global variables }
  99.  
  100. var
  101.  
  102. gDone : boolean;
  103. gWindowPtr : WindowPtr;
  104. gWindowPtrs : array [0..10] of WindowPtr;
  105. gNumberOfWindows : integer;
  106. gApplicationWasOpen : boolean;
  107. eventRec : EventRecord;
  108. menubarHdl : Handle;
  109. menuHdl : MenuHandle;
  110.  
  111. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoInitManagers }
  112.  
  113. procedure DoInitManagers;
  114.  
  115.     begin
  116.     MaxApplZone;
  117.     MoreMasters;
  118.  
  119.     InitGraf(@qd.thePort);
  120.     InitFonts;
  121.     InitWindows;
  122.     InitMenus;
  123.     TEInit;
  124.     InitDialogs(nil);
  125.  
  126.     InitCursor;    
  127.     FlushEvents(everyEvent, 0);
  128.     end;
  129.         {of procedure DoInitManagers}
  130.  
  131. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoAppleMenu }
  132.  
  133. procedure DoAppleMenu(menuItem : integer);
  134.  
  135.     var
  136.     itemName : string;
  137.     daDriverRefNum : integer;
  138.  
  139.     begin
  140.     GetMenuItemText(GetMenuHandle(mApple), menuItem, itemName);
  141.     daDriverRefNum := OpenDeskAcc(itemName);
  142.     end;
  143.         {of procedure DoAppleMenu}
  144.  
  145. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoFileMenu }
  146.  
  147. procedure DoFileMenu(menuItem : integer);
  148.  
  149.     begin
  150.     if (menuItem  = iQuit) then
  151.         gDone := true;
  152.     end;
  153.         {of procedure DoFileMenu}
  154.  
  155. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoMenuChoice }
  156.  
  157. procedure DoMenuChoice(menuChoice : longint);
  158.  
  159.     var
  160.     menuID, menuItem : integer;
  161.  
  162.     begin
  163.     menuID := HiWord(menuChoice);
  164.     menuItem := LoWord(menuChoice);
  165.  
  166.     if (menuID = 0) then
  167.         Exit(DoMenuChoice);
  168.  
  169.     case (menuID) of
  170.  
  171.         mApple:
  172.             begin
  173.             DoAppleMenu(menuItem);
  174.             end;
  175.             
  176.         mFile:
  177.             begin
  178.             DoFileMenu(menuItem);
  179.             end;
  180.             
  181.         end;
  182.             {of case statement}
  183.  
  184.     HiliteMenu(0);
  185.     end;
  186.         {of procedure DoMenuChoice}
  187.  
  188. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoError }
  189.  
  190. procedure DoError(errorType : integer);
  191.  
  192.     var
  193.     errorString : string;
  194.     ignored : OSErr;
  195.     
  196.     begin
  197.     SetCursor(qd.arrow);
  198.  
  199.     GetIndString(errorString, rErrorStrings, errorType);
  200.     ParamText(errorString, '', '', '');
  201.     if (errorType < 7)
  202.         then    ignored := CautionAlert(rErrorAlert, nil)
  203.         
  204.         else    begin
  205.             ignored := StopAlert(rErrorAlert, nil);
  206.             ExitToShell;
  207.             end;
  208.     end;
  209.         {of procedure DoError}
  210.  
  211. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ HasGotRequiredParams }
  212.  
  213. function HasGotRequiredParams(appEvent : AppleEvent) : OSErr;
  214.  
  215.     var
  216.     returnedType : DescType;
  217.     actualSize : Size;
  218.     theErr : OSErr;
  219.  
  220.     begin
  221.     theErr := AEGetAttributePtr(appEvent, keyMissedKeywordAttr, typeWildCard, returnedType,
  222.                                                     nil, 0, actualSize);
  223.     
  224.     if (theErr = errAEDescNotFound)
  225.         then    HasGotRequiredParams := noErr
  226.         else    if (theErr = noErr) 
  227.             then    HasGotRequiredParams := errAEParamMissed
  228.             else    HasGotRequiredParams := noErr;
  229.     end;
  230.         {of function HasGotRequiredParams}
  231.  
  232. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DrawTextString }
  233.  
  234. procedure DrawTextString(eventString : string);
  235.  
  236.     var
  237.     tempRegion : RgnHandle;
  238.  
  239.     begin
  240.     tempRegion := NewRgn;
  241.  
  242.     ScrollRect(gWindowPtr^.portRect, 0, -15, tempRegion);
  243.     DisposeRgn(tempRegion);
  244.  
  245.     MoveTo(8, 176);
  246.     DrawString(eventString);
  247.     end;
  248.         {of procedure DrawTextString}
  249.  
  250. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoPrepareToTerminate }
  251.  
  252. procedure DoPrepareToTerminate;
  253.  
  254.     var
  255.     finalTicks : UInt32;
  256.  
  257.     begin
  258.     DrawTextString('Received an Apple event: QUIT APPLICATION');
  259.  
  260.     if (gApplicationWasOpen)
  261.         then    begin
  262.             DrawTextString('   • I would now ask the user to save any unsaved files');
  263.             DrawTextString('     before terminating myself in reponse to the event.');
  264.             DrawTextString('   • Click the mouse when ready to terminate.');
  265.         
  266.             while not (Button) do;
  267.             end
  268.                 
  269.         else    begin
  270.             DrawTextString('    • Terminating myself in response');
  271.             Delay(300, finalTicks);
  272.             end;
  273.  
  274.     { If the user did not click the Cancel button in a Save dialog box: }
  275.  
  276.     gDone := true;
  277.     end;
  278.         {of procedure DoPrepareToTerminate}
  279.  
  280. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoNewWindow }
  281.  
  282. function DoNewWindow : WindowPtr;
  283.  
  284.     begin
  285.     gWindowPtrs[gNumberOfWindows] := GetNewWindow(rDocWindow, nil, WindowPtr(-1));
  286.     if (gWindowPtrs[gNumberOfWindows] = nil) then
  287.         DoError(eCannotOpenWindow);
  288.  
  289.     gNumberOfWindows := gNumberOfWindows + 1;
  290.  
  291.     DoNewWindow := gWindowPtrs[gNumberOfWindows - 1];
  292.     end;
  293.         {of function DoNewWindow}
  294.  
  295. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoOpenFile }
  296.  
  297. function DoOpenFile(var fileSpec : FSSpec; index, numberOfItems : longint) : boolean;
  298.  
  299.     var
  300.     myWindowPtr : WindowPtr;
  301.     finalTicks : UInt32;
  302.  
  303.     begin
  304.     gApplicationWasOpen := true;
  305.  
  306.     if (index = 1) then
  307.         DrawTextString('Received an Apple event: OPEN DOCUMENTS.');
  308.  
  309.     if (numberOfItems = 1)
  310.         then    begin
  311.             DrawTextString('    • The file to open is: ');
  312.             DrawString(fileSpec.name);
  313.             DrawTextString('    • Opening titled window in reponse.');
  314.             Delay(100, finalTicks);
  315.             end
  316.                 
  317.         else    begin
  318.             if(index = 1)
  319.                 then    begin        
  320.                     DrawTextString('    • The files to open are: ');
  321.                     DrawString(fileSpec.name);
  322.                     end
  323.                     
  324.                 else    begin
  325.                     DrawString('p and ');
  326.                     DrawString(fileSpec.name);
  327.                     DrawTextString('    • Opening titled windows in reponse.');
  328.                     Delay(100, finalTicks);
  329.                     end;
  330.             end;            
  331.  
  332.     myWindowPtr := DoNewWindow;
  333.     if (myWindowPtr <> nil)
  334.         then    begin
  335.             SetWTitle(myWindowPtr, fileSpec.name);
  336.             DoOpenFile := true;
  337.             end
  338.  
  339.         else    DoOpenFile := false;
  340.     
  341.     end;
  342.         {of function DoOpenFile}
  343.  
  344. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoPrintFile }
  345.  
  346. function DoPrintFile(var fileSpec : FSSpec; index, numberOfItems : longint) : boolean;
  347.  
  348.     var
  349.     myWindowPtr : WindowPtr;
  350.     finalTicks : UInt32;
  351.  
  352.     begin
  353.     if (index = 1) then
  354.         DrawTextString('Received an Apple event: PRINT DOCUMENTS');
  355.  
  356.     if (numberOfItems = 1)
  357.         then     begin
  358.         DrawTextString('    • The file to print is: ');
  359.         DrawString(fileSpec.name);
  360.         myWindowPtr := DoNewWindow;
  361.         SetWTitle(myWindowPtr, fileSpec.name);
  362.         DrawTextString('    • I would present the Print dialog box first and then');
  363.         DrawTextString('      print the document when the user has made his settings.');
  364.         Delay(100, finalTicks);
  365.         DrawTextString('    • Assume that I am now printing the document.');
  366.         end
  367.         
  368.         else    begin
  369.         if (index = 1)
  370.             then    begin        
  371.             DrawTextString('    • The first file to print is: ');
  372.             DrawString(fileSpec.name);
  373.             DrawTextString('      I would present the Print dialog box for the first file');
  374.             DrawTextString('      only and use the users settings to print both files.');
  375.             end
  376.                     
  377.             else    begin
  378.             Delay(200, finalTicks);
  379.             DrawTextString('    • The second file to print is: ');
  380.             DrawString(fileSpec.name);
  381.             DrawTextString('      I am using the Print dialog box settings used for the');
  382.             DrawTextString('      first file.');
  383.             end;
  384.  
  385.         myWindowPtr := DoNewWindow;
  386.         SetWTitle(myWindowPtr, fileSpec.name);
  387.         Delay(200, finalTicks);
  388.         DrawTextString('    • Assume that I am now printing the document.');
  389.         Delay(200, finalTicks);
  390.         end;
  391.  
  392.     if (numberOfItems = index) then
  393.         begin
  394.         if not (gApplicationWasOpen)
  395.             then    begin
  396.             DrawTextString('      Since the application was not already open, I expect to'); 
  397.             DrawTextString('      receive a QUIT APPLICATION event when I have finished.');
  398.             end
  399.                     
  400.             else    begin
  401.             DrawTextString('      Since the application was already open, I do NOT expect'); 
  402.             DrawTextString('      to receive a QUIT APPLICATION event when I have finished.');
  403.             end;
  404.     
  405.         Delay(500, finalTicks);
  406.         DrawTextString('    • Finished print job.');
  407.         end;
  408.  
  409.     DisposeWindow(myWindowPtr);
  410.     DoPrintFile := true;
  411.     end;
  412.         {of function DoPrintFiles}
  413.  
  414. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoOpenAppEvent }
  415.  
  416. function DoOpenAppEvent(var appEvent, reply : AppleEvent; handlerRefCon : longint) 
  417.                                                 : OSErr;
  418.     var
  419.     theErr : OSErr;
  420.     myWindowPtr : WindowPtr;
  421.     finalTicks : UInt32;
  422.  
  423.     begin
  424.     gApplicationWasOpen := true;
  425.  
  426.     theErr := HasGotRequiredParams(appEvent);
  427.  
  428.     if (theErr = noErr)
  429.         then    begin
  430.             DrawTextString('Received an Apple event: OPEN APPLICATION.');
  431.             DrawTextString('    • Opening an untitled window in reponse.');
  432.             Delay(100, finalTicks);
  433.  
  434.             myWindowPtr := DoNewWindow;
  435.             SetWTitle(myWindowPtr, 'Untitled 1');
  436.  
  437.             DoOpenAppEvent := noErr;
  438.             end
  439.                 
  440.         else    DoOpenAppEvent := theErr;
  441.     end;
  442.         {of function DoOpenAppEvent}
  443.  
  444. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoOpenDocsEvent }
  445.  
  446. function DoOpenDocsEvent(var appEvent, reply : AppleEvent; handlerRefCon : longint) 
  447.                                                 : OSErr;
  448.     var
  449.     fileSpec : FSSpec;
  450.     docList : AEDescList;
  451.     theErr, ignoreErr : OSErr;
  452.     index, numberOfItems : SInt32;
  453.     actualSize : Size;
  454.     keyWord : AEKeyword;
  455.     returnedType : DescType;
  456.     result : boolean;
  457.                 
  458.     begin
  459.     theErr := AEGetParamDesc(appEvent, keyDirectObject, typeAEList, docList);
  460.  
  461.     if (theErr = noErr)
  462.       then  begin
  463.         theErr := HasGotRequiredParams(appEvent);
  464.         if (theErr = noErr)
  465.                 then  begin
  466.                 ignoreErr := AECountItems(docList, numberOfItems);
  467.                 if (theErr = noErr) then
  468.                     begin
  469.                     for index := 1 to numberOfItems do
  470.                         begin
  471.                         theErr := AEGetNthPtr(docList, index, typeFSS, keyWord, returnedType,
  472.                                             @fileSpec, sizeof(fileSpec), actualSize);
  473.                         if (theErr = noErr)
  474.                             then  begin
  475.                                 result := DoOpenFile(fileSpec, index, numberOfItems);
  476.                                 if (result = false) then
  477.                                     DoError(eCannotOpenFile);
  478.                                     end
  479.                                 else  DoError(eGetDescriptorRecord);
  480.                         end;
  481.                             {of for loop}
  482.                     end;
  483.                 end
  484.                 else  DoError(eMissedRequiredParam);
  485.  
  486.             ignoreErr := AEDisposeDesc(docList);
  487.             end
  488.           
  489.         else  DoError(eGetRequiredParam);
  490.  
  491.     DoOpenDocsEvent := theErr;
  492.     end;
  493.         {of DoOpenDocsEvent}
  494.  
  495. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoPrintDocsEvent }
  496.  
  497. function DoPrintDocsEvent(var appEvent, reply : AppleEvent; handlerRefCon : longint) 
  498.                                                 : OSErr;
  499.     var
  500.     fileSpec : FSSpec;
  501.     docList : AEDescList;
  502.     theErr, ignoreErr : OSErr;
  503.     index, numberOfItems : longint;
  504.     actualSize : Size;
  505.     keyWord : AEKeyword;
  506.     returnedType : DescType;
  507.     result : boolean;
  508.     
  509.     begin
  510.     theErr := AEGetParamDesc(appEvent, keyDirectObject, typeAEList, docList);
  511.  
  512.     if (theErr = noErr)
  513.       then  begin
  514.             theErr := HasGotRequiredParams(appEvent);
  515.             if (theErr = noErr)
  516.               then  begin
  517.                     ignoreErr := AECountItems(docList, numberOfItems);
  518.                     if (theErr = noErr) then
  519.                       begin
  520.                       for index := 1 to numberOfItems do
  521.                         begin
  522.                         theErr := AEGetNthPtr(docList, index, typeFSS, keyWord, returnedType,
  523.                         @fileSpec, sizeof(fileSpec), actualSize);
  524.                         if (theErr = noErr)
  525.                             then  begin
  526.                                 result := DoPrintFile(fileSpec, index, numberOfItems);
  527.                                 if (result = false) then
  528.                                   DoError(eCannotPrintFile);
  529.                                 end
  530.                             else  DoError(eGetDescriptorRecord);
  531.                         end;
  532.                             {of for loop}
  533.                       end;
  534.                     end
  535.                             
  536.               else  DoError(eMissedRequiredParam);
  537.  
  538.             ignoreErr := AEDisposeDesc(docList);
  539.             end
  540.                 
  541.       else  DoError(eGetRequiredParam);
  542.  
  543.     DoPrintDocsEvent := theErr;
  544.     end;
  545.         {of function DoPrintDocsEvent}
  546.  
  547. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoQuitAppEvent }
  548.  
  549. function DoQuitAppEvent(var appEvent, reply : AppleEvent; handlerRefCon : longint) 
  550.                                                 : OSErr;
  551.     var
  552.     theErr : OSErr;
  553.  
  554.     begin
  555.     theErr := HasGotRequiredParams(appEvent);
  556.  
  557.     if (theErr = noErr)
  558.         then    begin
  559.             DoPrepareToTerminate;
  560.             DoQuitAppEvent := theErr;
  561.             end
  562.                 
  563.         else    DoQuitAppEvent := theErr;
  564.     end;
  565.         {of function DoQuitAppEvent}
  566.  
  567. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoInstallAEHandlers }
  568.  
  569. procedure DoInstallAEHandlers;
  570.  
  571.     var
  572.     err : OSErr;
  573.  
  574.     begin
  575.     err := AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
  576.                                     AEEventHandlerUPP(@DoOpenAppEvent), 0, false);
  577.                                     
  578.     if (err <> noErr) then
  579.          DoError(eInstallHandler);
  580.  
  581.     err := AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  582.                                     AEEventHandlerUPP(@DoOpenDocsEvent), 0, false);
  583.                                     
  584.     if (err <> noErr) then    
  585.          DoError(eInstallHandler);
  586.  
  587.     err := AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
  588.                                     AEEventHandlerUPP(@DoPrintDocsEvent), 0, false);
  589.     
  590.     if (err <> noErr) then     
  591.         DoError(eInstallHandler);
  592.  
  593.     err := AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  594.                                     AEEventHandlerUPP(@DoQuitAppEvent), 0, false);
  595.     if (err <> noErr) then
  596.          DoError(eInstallHandler);
  597.     end;
  598.         {of procedure DoInstallAEHandlers}
  599.  
  600. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoMouseDown }
  601.  
  602. procedure DoMouseDown(eventRec : EventRecord);
  603.  
  604.     var
  605.     myWindowPtr : WindowPtr;
  606.     partCode : integer;
  607.     menuChoice : longint;
  608.  
  609.     begin
  610.     partCode := FindWindow(eventRec.where, myWindowPtr);
  611.  
  612.     case (partCode) of
  613.     
  614.         inMenuBar:
  615.             begin
  616.             menuChoice := MenuSelect(eventRec.where);
  617.             DoMenuChoice(menuChoice);
  618.             end;
  619.             
  620.         inSysWindow:
  621.             begin
  622.             SystemClick(eventRec, myWindowPtr);
  623.             end;
  624.  
  625.         inDrag:
  626.             begin
  627.             DragWindow(myWindowPtr, eventRec.where, qd.screenBits.bounds);
  628.             end;
  629.         end;
  630.             {of case statement}
  631.     end;
  632.         {of procedure DoMouseDown}
  633.  
  634. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoEvents }
  635.  
  636. procedure DoEvents(eventRec : EventRecord);
  637.  
  638.     var
  639.     charCode : char;
  640.     ignored : OSErr;
  641.  
  642.     begin
  643.     case (eventRec.what) of
  644.  
  645.         kHighLevelEvent:
  646.             begin
  647.             ignored := AEProcessAppleEvent(eventRec);
  648.             end;
  649.  
  650.         mouseDown:
  651.             begin
  652.             DoMouseDown(eventRec);
  653.             end;
  654.  
  655.         keyDown, autoKey:
  656.             begin
  657.             charCode := chr(BAnd(eventRec.message, charCodeMask));
  658.             if (BAnd(eventRec.modifiers, cmdKey) <> 0) then
  659.                 DoMenuChoice(MenuKey(charCode));
  660.             end;
  661.  
  662.         updateEvt:
  663.             begin
  664.             BeginUpdate(WindowPtr(eventRec.message));
  665.             EndUpdate(WindowPtr(eventRec.message));
  666.             end;
  667.  
  668.         osEvt:
  669.             begin
  670.             HiliteMenu(0);
  671.             end;
  672.         end;
  673.             {of case statement}
  674.     end;
  675.         {of procedure DoEvents}
  676.  
  677. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ start of main program }
  678.  
  679. begin
  680.  
  681.     gNumberOfWindows := 0;
  682.     gApplicationWasOpen := false;
  683.     
  684.     { …………………………………………………………………………………………………………………………………………………………………… initialize managers }
  685.  
  686.     DoInitManagers;
  687.     
  688.     { …………………………………………………………………………………………………………………………………………………………………………………… open a window }
  689.     
  690.     gWindowPtr := GetNewWindow(rDisplayWindow, nil, WindowPtr(-1));
  691.     if (gWindowPtr = nil) then
  692.         begin
  693.         DoError(eCannotOpenWindow);
  694.         ExitToShell;
  695.         end;
  696.  
  697.     SetPort(gWindowPtr);
  698.     TextSize(10);
  699.  
  700.     { …………………………………………………………………………………………………………………………………………………… set up menu bar and menus }
  701.     
  702.     menubarHdl := GetNewMBar(rMenubar);
  703.     if (menubarHdl = nil) then
  704.          DoError(eMenus);
  705.     SetMenuBar(menubarHdl);
  706.     DrawMenuBar;
  707.  
  708.     menuHdl := GetMenuHandle(mApple);
  709.     if (menuHdl = nil)
  710.         then DoError(eMenus)
  711.         else AppendResMenu(menuHdl,'DRVR');
  712.  
  713.     { …………………………………………………………………………………………………………………………………………… install Apple event handlers }
  714.  
  715.     DoInstallAEHandlers;
  716.  
  717.     { …………………………………………………………………………………………………………………………………………………………………………………………… event loop }
  718.     
  719.     gDone := false;
  720.  
  721.     while not (gDone) do
  722.         if (WaitNextEvent(everyEvent, eventRec, 180, nil)) then
  723.             DoEvents(eventRec);
  724.  
  725. end.
  726.     
  727. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ }