home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 …ember: Reference Library / Apple Developer Reference Library (December 1999) (Disk 1).iso / pc / what's new / sample code / human interface toolbox / packagetool / packagetool.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-22  |  9.7 KB  |  354 lines

  1. /*
  2.     file PackageTool.c
  3.     
  4.     Description:
  5.     This file contains the main event displatching code used in the PackageTool
  6.     application.
  7.     
  8.     PackageTool is an application illustrating how to create application
  9.     packages in Mac OS 9.  It provides a simple interface for converting
  10.     correctly formatted folders into packages and vice versa.
  11.  
  12.     by John Montbriand, 1999.
  13.  
  14.     Copyright: © 1999 by Apple Computer, Inc.
  15.     all rights reserved.
  16.     
  17.     Disclaimer:
  18.     You may incorporate this sample code into your applications without
  19.     restriction, though the sample code has been provided "AS IS" and the
  20.     responsibility for its operation is 100% yours.  However, what you are
  21.     not permitted to do is to redistribute the source as "DSC Sample Code"
  22.     after having made changes. If you're going to re-distribute the source,
  23.     we require that you make it clear in the source that the code was
  24.     descended from Apple Sample Code, but that you've made changes.
  25.     
  26.     Change History (most recent first):
  27.     10/19/99 created by John Montbriand
  28. */
  29.  
  30. #include "PackageTool.h"
  31. #include "Utilities.h"
  32.  
  33. #include <Fonts.h>
  34. #include <Dialogs.h>
  35. #include <PLStringFuncs.h>
  36. #include <TextUtils.h>
  37. #include <Gestalt.h>
  38. #include <StdIO.h>
  39. #include <String.h>
  40. #include <Devices.h>
  41. #include <Appearance.h>
  42. #include <Resources.h>
  43.  
  44. #include "SimplePrefs.h"
  45. #include "PackageUtils.h"
  46. #include "PackageWindow.h"
  47.  
  48.  
  49. #ifndef __MWERKS__
  50. QDGlobals    qd; /* QuickDraw globals */
  51. #endif
  52.  
  53.     /* application's globals */
  54. Boolean gRunning = true; /* true while the application is running, set to false to quit */
  55. Collection gPreferences = NULL; /* main preferences collection, saved in the prefs file.  */
  56.  
  57.  
  58. Collection GetCollectedPreferences(void) {
  59.     return gPreferences;
  60. }
  61.  
  62.  
  63.  
  64.  
  65. /* ResetMenus is called to reset the menus immediately before
  66.     either MenuSelect or MenuKey is called.  Here, we disable the
  67.     quit command during file copies. */
  68. static void ResetMenus(void) {
  69.     MenuHandle fileMenu;
  70.         /* get the file menu from the current menu list */
  71.     fileMenu = GetMenuHandle(mFile);
  72.         /* disable quit if we're in the middle of copying a file */
  73. }
  74.  
  75.  
  76. /* DoMenuCommand is called after either MenuSelect of MenuKey.  The
  77.     parameter rawMenuSelectResult is the result from one of these two routines. 
  78.     DoMenuCommand parses this result into its two parts, and dispatches
  79.     the menu command as appropriate. */
  80. static void DoMenuCommand(long rawMenuSelectResult) {
  81.     short menu, item;
  82.         /* decode the MenuSelect result */
  83.     menu = (rawMenuSelectResult >> 16);
  84.     if (menu == 0) return;
  85.     item = (rawMenuSelectResult & 0x0000FFFF);
  86.         /* dispatch on result */
  87.     switch (menu) {
  88.         case mApple:
  89.             if (item == iAbout) {
  90.                     /* show the about box. */
  91.                 ParamAlert(kAboutBoxAlert, NULL, NULL);
  92.             } else if (item >= iFirstAppleItem) {
  93.                 Str255 deskAccName;
  94.                     /* open an apple menu item. */
  95.                 GetMenuItemText(GetMenuHandle(mApple), item, deskAccName);
  96.                 OpenDeskAcc(deskAccName);
  97.             }
  98.             break;
  99.         case mFile:
  100.             if (item == iQuit) gRunning = false; /* file.quit == quit */
  101.             break;
  102.         case mEdit:
  103.             if (item == iClear) SetNewDisplay(NULL); /* edit.clear == clear the display */
  104.             break;
  105.     }
  106.         /* unhilite the menu once we're done the command */
  107.     HiliteMenu(0);
  108. }
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116. /* OpenApplication is an apple event handler called for 'open application' apple events. */
  117. static pascal OSErr OpenApplication(const AppleEvent *appleEvt, AppleEvent* reply, long refcon) {
  118.     return noErr;
  119. }
  120.  
  121. /* CloseApplication is an apple event handler called for 'close application' apple events. */
  122. static pascal OSErr CloseApplication(const AppleEvent *appleEvt, AppleEvent* reply, long refcon) {
  123.     gRunning = false;
  124.     return noErr;
  125. }
  126.  
  127.  
  128. static pascal OSErr OpenDocument(const AppleEvent *appleEvt, AppleEvent* reply, long refcon) {
  129.     OSErr err;
  130.     AEDescList documents;
  131.     long n;
  132.     FSSpec fileSpec, packageSpec;
  133.     AEKeyword keyWd;
  134.     DescType typeCd;
  135.     Size actSz;
  136.     
  137.         /* initial state */
  138.     AECreateDesc(typeNull, NULL, 0, &documents);
  139.     
  140.         /* get the open parameter */
  141.     err = AEGetParamDesc(appleEvt, keyDirectObject, typeAEList, &documents);
  142.     if (err != noErr) goto bail;
  143.     err = AECountItems(&documents, &n);
  144.     if (err != noErr) goto bail;
  145.     if (n == 0) { err = paramErr; goto bail; }
  146.     err = AEGetNthPtr(&documents, 1, typeFSS, &keyWd, &typeCd,
  147.         (Ptr) &fileSpec, sizeof(fileSpec), (actSz = sizeof(fileSpec), &actSz));
  148.     if (err != noErr) goto bail;
  149.     
  150.     if (IdentifyPackage(&fileSpec, &packageSpec))
  151.         SetNewDisplay(&fileSpec);
  152.     else if (FSSpecIsAFolder(&fileSpec))
  153.         SetNewDisplay(&fileSpec);
  154.     else SetNewDisplay(NULL);
  155.  
  156. bail:
  157.     AEDisposeDesc(&documents);
  158.     return err;
  159. }
  160.  
  161.  
  162. /* EVENT HANDLING ------------------------------------------------ */
  163.  
  164.  
  165. /* HandleNextEvent handles the event in the event record *ev dispatching
  166.     the event to appropriate routines.   */
  167. static void HandleNextEvent(EventRecord *ev) {
  168.     DialogPtr theDialog;
  169.     WindowPtr theWindow;
  170.     short itemNo;
  171.     
  172.         /* dialog pre-processing */
  173.     if (((ev->what == keyDown) || (ev->what == autoKey)) && ((ev->modifiers & cmdKey) != 0)) {
  174.         ResetMenus();
  175.         DoMenuCommand(MenuKey((char) (ev->message & charCodeMask)));
  176.     } else if (ev->what == osEvt) {
  177.         WindowPtr target;
  178.         Boolean activate;
  179.         if ( (((ev->message >> 24) & 0x0FF) == suspendResumeMessage) && ((ev->message & resumeFlag) != 0)) {
  180.             activate = true;/* switching in */
  181.         } else activate = false;
  182.         target = FrontWindow();
  183.         if (IsPackageWindow(target))
  184.             ActivatePackageWindow(target, activate);
  185.     } else if (ev->what == activateEvt) {
  186.         WindowPtr target;
  187.         target = (WindowPtr) ev->message;
  188.         if (IsPackageWindow(target))
  189.             ActivatePackageWindow(target, ((ev->modifiers&1) != 0));
  190.     }
  191.  
  192.         /* handle clicks in the dialog window */
  193.     if (IsDialogEvent(ev))
  194.         if (DialogSelect(ev, &theDialog, &itemNo)) {
  195.             if (IsPackageWindow(theDialog))
  196.                 HitPackageWindow(theDialog, ev, itemNo);
  197.         }
  198.  
  199.         /* clicks and apple events... */
  200.     if (ev->what == kHighLevelEvent) {
  201.         AEProcessAppleEvent(ev);
  202.     } else if (ev->what == mouseDown)
  203.         switch (FindWindow(ev->where, &theWindow)) {
  204.             
  205.                 /* menu bar clicks */
  206.             case inMenuBar:
  207.                 ResetMenus();
  208.                 DoMenuCommand(MenuSelect(ev->where));
  209.                 break;
  210.                 
  211.                 /* clicks in the close box, close the app */
  212.             case inGoAway:
  213.                 if (TrackGoAway(theWindow, ev->where)) {
  214.                     gRunning = false;
  215.                 }
  216.                 break;
  217.                 
  218.                 /* allow window drags */
  219.             case inDrag:
  220.                 if (theWindow == FrontWindow()) {
  221.                     Rect boundsRect = { -32000, -32000, 32000, 32000};
  222.                     DragWindow(theWindow, ev->where, &boundsRect);
  223.                 }
  224.                 break;
  225.                 
  226.                 /* desktop clicks, etc... */
  227.             case inSysWindow:
  228.                 SystemClick(ev, theWindow);
  229.                 break;
  230.         }
  231. }
  232.  
  233.  
  234.  
  235.  
  236. /* MyIdleProc is the idle procedure called by AEInteractWithUser while we are waiting
  237.     for the application to be pulled into the forground.  It simply passes the event along
  238.     to HandleNextEvent */
  239. static pascal Boolean MyIdleProc(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn) {
  240.     HandleNextEvent(theEvent);
  241.     return false;
  242. }
  243.  
  244. /* ParamAlert is a general alert handling routine.  If Apple events exist, then it
  245.     calls AEInteractWithUser to ensure the application is in the forground, and then
  246.     it displays an alert after passing the s1 and s2 parameters to ParamText. */
  247. OSStatus ParamAlert(short alertID, StringPtr s1, StringPtr s2) {
  248.     AEIdleUPP theIdleUPP;
  249.     OSStatus err;
  250.     theIdleUPP = NewAEIdleProc(MyIdleProc);
  251.     if (theIdleUPP == NULL) { err = memFullErr; goto bail; }
  252.     err = AEInteractWithUser(kNoTimeOut, NULL, theIdleUPP);
  253.     if (err != noErr) goto bail;
  254.     ParamText(s1, s2, NULL, NULL);
  255.     err = Alert(alertID, NULL);
  256.     DisposeAEIdleUPP(theIdleUPP);
  257.     return err;
  258. bail:
  259.     if (theIdleUPP != NULL) DisposeAEIdleUPP(theIdleUPP);
  260.     return err;
  261. }
  262.  
  263.  
  264.  
  265.  
  266. /* main program */
  267.  
  268. int main(void) {
  269.     OSErr err;
  270.     long response;
  271.     AEEventHandlerUPP aehandler;
  272.     
  273.         /* set up the managers */
  274.     SetApplLimit(GetApplLimit());
  275.     MaxApplZone();
  276.     InitGraf(&qd.thePort);
  277.     InitFonts();
  278.     InitWindows();
  279.     TEInit();
  280.     InitMenus();
  281.     InitDialogs(0);
  282.     FlushEvents(everyEvent, 0);
  283.     InitCursor();
  284.             
  285.     if (Gestalt('sysv', &response) != noErr) response = 0;
  286.     if (response < 0x0900) {
  287.         ParamAlert(138, NULL, NULL);
  288.         err = userCanceledErr;
  289.         goto bail;
  290.     }
  291.  
  292.     err = RegisterAppearanceClient();
  293.     if (err != noErr) goto bail;
  294.     
  295.         /* Apple event handlers */
  296.     aehandler = NewAEEventHandlerProc(OpenApplication);
  297.     if (aehandler == NULL) { err = memFullErr; goto bail; }
  298.     err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, aehandler, 0, false);
  299.     if (err != noErr) goto bail;
  300.     aehandler = NewAEEventHandlerProc(CloseApplication);
  301.     if (aehandler == NULL) { err = memFullErr; goto bail; }
  302.     err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, aehandler, 0, false);
  303.     if (err != noErr) goto bail;
  304.     aehandler = NewAEEventHandlerProc(OpenDocument);
  305.     if (aehandler == NULL) { err = memFullErr; goto bail; }
  306.     err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, aehandler, 0, false);
  307.     if (err != noErr) goto bail;
  308.  
  309.         /* get our preferences */    
  310.     gPreferences = NewCollection();
  311.     if (gPreferences == NULL) { err = memFullErr; goto bail; }
  312.     GetPreferences(kAppPrefsType, kAppCreatorType, gPreferences);
  313.  
  314.         /* ***** set up the menu bar ***** */
  315.     SetMenuBar(GetNewMBar(kMenuBarResource));
  316.     DrawMenuBar();
  317.     AppendResMenu(GetMenuHandle(mApple), 'DRVR');
  318.     
  319.         /* open the window */
  320.     err = CreatePackageWindow();
  321.     if (err != noErr) {
  322.         Str255 errStr;
  323.         NumToString(err, errStr);
  324.         ParamAlert(kOpenAppFailedAlert, errStr, NULL);
  325.     }
  326.  
  327.         /* run the main loop */
  328.     while (gRunning) {
  329.         EventRecord ev;
  330.             /* get the next event */
  331.         if ( ! WaitNextEvent(everyEvent, &ev,  GetCaretTime(), NULL) )
  332.             ev.what = nullEvent;
  333.         HandleNextEvent(&ev);
  334.     }
  335.     
  336.         /* all done */
  337.     ClosePackageWindow();
  338.     UnregisterAppearanceClient();
  339.     SavePreferences(kAppPrefsType, kAppCreatorType, "\pPackageTool Preferences", gPreferences);
  340.     DisposeCollection(gPreferences);
  341.     ExitToShell();
  342.     return 0;
  343. bail:
  344.     if (err != userCanceledErr) {
  345.         Str255 errStr;
  346.         NumToString(err, errStr);
  347.         ParamAlert(kMainFailedAlert, errStr, NULL);
  348.     }
  349.     ExitToShell();
  350.     return 1;
  351. }
  352.  
  353.  
  354.