home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 August: Tool Chest / Apple_Developer_Group_August_1996_Tool_Chest.iso / Sample Code / Snippets / Toolbox / NoResDialog / NoResDialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-10  |  26.0 KB  |  675 lines  |  [TEXT/MPS ]

  1. // Modified 1994 to show NoResDialog stuff 
  2. // Look for the NoResDialog dialog function 
  3.  
  4.  
  5.  
  6. /* Simple.c */
  7. /* The simplest C System 7 shell application */
  8. /* This shell can be very handy for debugging and testing things */
  9. /* Add menu items, add dialogs, add controls, or whatever else you need */
  10. /* This sample contains basic application startup and event loop handling, */
  11. /* add more features as your needs increase. */
  12. /* This sample is High Level Event aware, so you can send and receive AppleEvents */
  13. /* from this application */
  14. /* Written  by C.K. Haun <TR> */
  15. /* Apple Developer Tech Support */
  16. /* October 1991, Tokyo, Japan */
  17. /* Of course, Copyright 1991, Apple Computer Inc. */
  18.  
  19. #include "NoResDialog.h"
  20.  
  21. /* prototypes */
  22.  
  23. void InitalizeApp(void);
  24. void DoDiskEvents(long dinfo);                              /* hi word is error code, lo word is drive number */
  25. void DrawMain(WindowPtr drawIt);
  26. Boolean DoSelected(long val);
  27. void SizeMain(WindowPtr theWindow, short how);
  28. void InitAEStuff(void);
  29. void DoHighLevel(EventRecord *AERecord);
  30. void DoDaCall(MenuHandle themenu, long theit);
  31. void DoDocumentClick(WindowPtr theWindow, EventRecord *theEvent);
  32.  
  33. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  34. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  35. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  36. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  37.  
  38. void SampleHelpDialog(void);
  39.  
  40. WindowPtr AddNewWindow(short theID);
  41.  
  42. void NilProc(void);
  43. /* one external */
  44. extern void _DataInit();                                    /* this is the C initialization code */
  45.  
  46. /* globals */
  47. Boolean gQuit, gInBackground;
  48. unsigned long gMySleep;
  49. ProcessSerialNumber gOurSN;
  50. short gHelpItem;
  51.  
  52. void NoResDialog(void);
  53. pascal void BorderDefault(DialogPtr dwind, short dinum);
  54.  
  55.  
  56. #pragma segment Main
  57. main()
  58. {
  59.     EventRecord myEventRecord;
  60.     WindowPtr twindow;
  61.     short fHit;
  62.     windowCHandle tempWCH;
  63.     
  64.     UnloadSeg((Ptr)_DataInit);                              /* throw out setup code */
  65.     InitalizeApp();
  66.     UnloadSeg((Ptr)InitalizeApp);                           /* get rid of my initialization code */
  67.     do {
  68.         WaitNextEvent(everyEvent, &myEventRecord, gMySleep, nil);
  69.         switch (myEventRecord.what) {
  70.             case nullEvent:
  71.                 
  72.                 /* no nul processing in this sample */
  73.                 break;
  74.             case updateEvt:
  75.                 /* always check to see if it's my window */
  76.                 /* this may not seem necessary under 7.0, where it's unlikely or impossible for */
  77.                 /* a DA to be in your layer, but there are others  */
  78.                 /* who can stick themselves into your window list, */
  79.                 /* BalloonWriter comes quickly to mind */
  80.                 if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  81.                     tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message);
  82.                     ((*tempWCH)->drawMe)((WindowPtr)myEventRecord.message);
  83.                 }
  84.                 break;
  85.             case mouseDown:
  86.                 /* first see where the hit was */
  87.                 fHit = FindWindow(myEventRecord.where, &twindow);
  88.                 switch (fHit) {
  89.                     Rect limitRect;
  90.                     Str255 tempString;
  91.                     long back;
  92.                     case inDesk:                            /* if they hit in desk, then the process manager */
  93.                         break;                              /* will switch us out, we don't need to do anything */
  94.                     case inMenuBar:
  95.                         DoSelected(MenuSelect(myEventRecord.where));
  96.                         break;
  97.                         
  98.                     case inSysWindow:
  99.                         /* pass to the system */
  100.                         SystemClick(&myEventRecord, twindow);
  101.                         break;
  102.                     case inContent:
  103.                         /* Handle content and control clicks here */
  104.                         if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) { /* don't do this unless we have a window open, silly */
  105.                             windowCHandle clicker;
  106.                             clicker = (windowCHandle)GetWRefCon(twindow);
  107.                             /* jump to the content function stored for this window */
  108.                             HLock((Handle)clicker);         /* lock it down so things don't get stupid */
  109.                             ((*clicker)->clickMe)(twindow, &myEventRecord);
  110.                             HUnlock((Handle)clicker);       /* all done */
  111.                         }
  112.                         break;
  113.                     case inDrag:
  114.                         DragWindow(twindow, myEventRecord.where, &qd.screenBits.bounds);
  115.                         break;
  116.                     case inGrow:
  117.                         /* Call GrowWindow here if you have a grow box */
  118.                         SetPort(twindow);
  119.                         limitRect = qd.screenBits.bounds;
  120.                         limitRect.top = kMinHeight;
  121.                         GetWTitle(twindow, tempString);
  122.                         /* I'm not letting the user shrink the window so */
  123.                         /* small that the title is truncated */
  124.                         limitRect.left = StringWidth(tempString) + 120;
  125.                         back = GrowWindow(twindow, myEventRecord.where, &limitRect);
  126.                         
  127.                         if (back) {
  128.                             if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  129.                                 windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
  130.                                 Rect sizeRect = ((WindowPtr)twindow)->portRect;
  131.                                 InvalRect(&sizeRect);
  132.                                 sizeRect.top = sizeRect.bottom - 16;
  133.                                 sizeRect.left = sizeRect.right - 16;
  134.                                 EraseRect(&sizeRect);
  135.                                 InvalRect(&sizeRect);
  136.                                 SizeWindow(twindow, back & 0xffff, back >> 16, true);
  137.                                 ((*tempWCH)->sizeMe)(twindow, fHit);
  138.                             }
  139.                         }
  140.                         InvalRect(&twindow->portRect);
  141.                         
  142.                         break;
  143.                     case inGoAway:
  144.                         /* Click in Close box */
  145.                         if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  146.                             if (TrackGoAway(twindow, myEventRecord.where))
  147.                                 ((*(windowCHandle)((WindowPeek)twindow)->refCon)->closeMe)(twindow);
  148.                         }
  149.                         break;
  150.                     case inZoomIn:
  151.                     case inZoomOut:
  152.                         if (TrackBox(twindow, myEventRecord.where, fHit)) {
  153.                             if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  154.                                 windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
  155.                                 SetPort(twindow);
  156.                                 
  157.                                 ZoomWindow(twindow, fHit, true);
  158.                                 InvalRect(&twindow->portRect);
  159.                                 ((*tempWCH)->sizeMe)(twindow, fHit);
  160.                             }
  161.                         }
  162.                 }
  163.             case mouseUp:
  164.                 /* don't care */
  165.                 break;
  166.                 /* same action for key or auto key */
  167.             case keyDown:
  168.             case autoKey:
  169.                 if (myEventRecord.modifiers & cmdKey)
  170.                     DoSelected(MenuKey(myEventRecord.message & charCodeMask));
  171.                 break;
  172.             case keyUp:
  173.                 /* don't care */
  174.                 break;
  175.             case diskEvt:
  176.                 /* I don't do anything special for disk events, this just passes them */
  177.                 /* to a function that checks for an error on the mount */
  178.                 DoDiskEvents(myEventRecord.message);
  179.                 break;
  180.             case activateEvt:
  181.                 if (myEventRecord.modifiers & activeFlag &&
  182.                     ((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  183.                     tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message);
  184.                     ((*tempWCH)->drawMe)((WindowPtr)myEventRecord.message);
  185.                 }
  186.                 break;
  187.             case networkEvt:
  188.                 /* don't care */
  189.                 break;
  190.             case driverEvt:
  191.                 /* don't care */
  192.                 break;
  193.             case app4Evt:
  194.                 switch ((myEventRecord.message >> 24) & 0x0FF) {        /* high byte of message */
  195.                     case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  196.                         gInBackground = (myEventRecord.message & kResumeMask) == 0;
  197.                         if (!gInBackground) {
  198.                             
  199.                         }
  200.                         break;
  201.                 }
  202.                 break;
  203.             default:
  204.                 break;
  205.                 /* This dispatches high level events (AppleEvents, for example) */
  206.                 /* to our dispatch routine.  This is NEW in the event loop for */
  207.                 /* System 7 */
  208.             case kHighLevelEvent:
  209.                 DoHighLevel(&myEventRecord);
  210.                 break;
  211.                 
  212.         }
  213.     }
  214.             while (gQuit != true);
  215.     
  216. }
  217.  
  218. /* DoDaCall opens the requested DA.  It's here as a seperate routine if you'd */
  219. /* like to perform some action or just know when a DA is opened in your */
  220. /* layer.  Can be handy to track memory problems when a DA is opened */
  221. /* with an Option-open */
  222. void DoDaCall(MenuHandle themenu, long theit)
  223. {
  224.     long qq;
  225.     char DAname[255];
  226.     GetItem(themenu, theit, &DAname);
  227.     qq = OpenDeskAcc(DAname);
  228. }
  229.  
  230. /* end DoDaCall */
  231.  
  232. /* DoDiskEvents just checks the error code from the disk mount, */
  233. /* and puts up the 'Format' dialog (through DIBadMount) if need be */
  234. /* You can do much more here if you care about what disks are */
  235. /* in the drive */
  236. void DoDiskEvents(long dinfo)                               /* hi word is error code, lo word is drive number */
  237. {
  238.     short hival, loval, tommy;
  239.     Point fredpoint =  {
  240.         40, 40
  241.     };
  242.     hival = HiWord(dinfo);
  243.     loval = LoWord(dinfo);
  244.     if (hival != noErr)                                     /* something happened */ {
  245.         tommy = DIBadMount(fredpoint, dinfo);
  246.     }
  247. }
  248.  
  249. /* draws my window.  Pretty simple */
  250. void DrawMain(WindowPtr drawIt)
  251. {
  252.     RgnHandle tempRgn;
  253.     Rect scratchRect;
  254.     BeginUpdate(drawIt);
  255.     SetPort(drawIt);
  256.     MoveTo(20,20);
  257.     DrawString("\p Select NoResDialog from the Test Stuff menu");
  258.     scratchRect = drawIt->portRect;
  259.     scratchRect.top = scratchRect.bottom - 15;
  260.     scratchRect.left = scratchRect.right - 15;
  261.     tempRgn = NewRgn();
  262.     GetClip(tempRgn);
  263.     ClipRect(&scratchRect);
  264.     DrawGrowIcon(drawIt);
  265.     SetClip(tempRgn);
  266.     DisposeRgn(tempRgn);
  267.     
  268.     EndUpdate(drawIt);
  269. }
  270.  
  271. /* my menu action taker.  It returns a Boolean which I usually ignore, but it */
  272. /* mught be handy someday */
  273. /* I usually use it in an application to determine if a keystroke was accepted */
  274. /* by a menu or whether it should be passed along to any other key acceptors */
  275. Boolean DoSelected(long val)
  276. {
  277.     short loval, hival;
  278.     Boolean returnVal = false;
  279.     loval = LoWord(val);
  280.     hival = HiWord(val);
  281.     
  282.     switch (hival) {                                        /* switch off the menu number selected */
  283.         case kAppleMenu:                                    /* Apple menu */
  284.             if (loval != 1) {                               /* if this was not About, it's a DA */
  285.                 DoDaCall(GetMHandle(kAppleMenu), loval);
  286.             } else {
  287.                 Alert(kAboutBox, nil);                      /* do about box */
  288.             }
  289.             returnVal = true;
  290.             break;
  291.         case kFileMenu:                                     /* File menu */
  292.             switch (loval) {
  293.                 case kQuitItem:
  294.                     gQuit = true;                           /* only  item */
  295.                     returnVal = true;
  296.                     break;
  297.                 default:
  298.                     break;
  299.             }
  300.             break;
  301.         case kEditMenu:
  302.             /* edit menu junk */
  303.             /* don't care */
  304.             switch (loval) {
  305.             default:
  306.                 break;
  307.             }
  308.             break;
  309.         case kToolsMenu:
  310.             /* add all your test stuff here */
  311.             NoResDialog();
  312.             switch (loval) {
  313.             default:
  314.                 break;
  315.             }
  316.             break;
  317.         case kHMHelpMenuID:                                 /* Defined in Balloons.h */
  318.             /* I only care about this item.  If anything else is returned here, I don't know what */
  319.             /* it is, so I leave it alone.  Remember, the Help Manager chapter says that */
  320.             /* Apple reserves the right to add and change things in the Help menu */
  321.             if (loval == gHelpItem)
  322.                 SampleHelpDialog();
  323.             break;
  324.             
  325.     }
  326.     HiliteMenu(0);
  327.     return(returnVal);
  328. }
  329.  
  330. void DoDocumentClick(WindowPtr theWindow, EventRecord *theEvent)
  331. {
  332. #pragma unused ( theWindow,theEvent)    
  333. }
  334.  
  335. /* InitAEStuff installs my appleevent handlers */
  336. void InitAEStuff(void)
  337. {
  338.     AEinstalls HandlersToInstall[] =  {
  339.         {
  340.             kCoreEventClass, kAEOpenApplication, AEOpenHandler
  341.         },  {
  342.             kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler
  343.         },  {
  344.             kCoreEventClass, kAEQuitApplication, AEQuitHandler
  345.         },  {
  346.             kCoreEventClass, kAEPrintDocuments, AEPrintHandler
  347.         }, 
  348.         /* The above are the four required AppleEvents. */
  349.         
  350.     };
  351.     
  352.     OSErr aevtErr = noErr;
  353.     long aLong = 0;
  354.     Boolean gHasAppleEvents = false;
  355.     /* Check this machine for AppleEvents.  If they are not here (ie not 7.0)
  356.     *   then we exit */
  357.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  358.     /* The following series of calls installs all our AppleEvent Handlers.
  359.     *   These handlers are added to the application event handler list that 
  360.     *   the AppleEvent manager maintains.  So, whenever an AppleEvent happens
  361.     *   and we call AEProcessEvent, the AppleEvent manager will check our
  362.     *   list of handlers and dispatch to it if there is one.
  363.     */
  364.     if (gHasAppleEvents) {
  365.         register qq;
  366.         for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
  367.             aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
  368.                                             HandlersToInstall[qq].theProc, 0, false);
  369.             if (aevtErr) {
  370.                 ExitToShell();                              /* just fail, baby */
  371.             }
  372.         }
  373.     } else {
  374.         ExitToShell();
  375.     }
  376. }
  377.  
  378. /* end InitAEStuff */
  379. /* I'm not doing error handling in this sample for clarities sake, you should. Hah, */
  380. /* easy for me to say, huh? */
  381. void DoHighLevel(EventRecord *AERecord)
  382. {
  383.     OSErr myErr;
  384.     myErr = AEProcessAppleEvent(AERecord);
  385.     
  386. }
  387.  
  388. /* end DoHighLevel */
  389.  
  390. /* This is the standard Open Application event.  */
  391. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  392. {
  393.     WindowPtr myWindow;
  394.  
  395. #pragma unused (messagein,reply,refIn)
  396.     /* we of course don't do anything here in this simple app */
  397.     /* except open our window */
  398.     myWindow = AddNewWindow(kDocWindowResID);
  399.     
  400.     return(noErr);
  401. }
  402.  
  403. /* end AEOpenHandler */
  404.  
  405. /* Open Doc, opens our documents.  Remember, this can happen at application start AND */
  406. /* anytime else.  If your app is up and running and the user goes to the desktop, hilites one */
  407. /* of your files, and double-clicks or selects Open from the finder File menu this event */
  408. /* handler will get called. Which means you don't do any initialization of globals here, or */
  409. /* anything else except open then doc.  */
  410. /* SO-- Do NOT assume that you are at app start time in this */
  411. /* routine, or bad things will surely happen to you. */
  412.  
  413. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  414. {
  415. #pragma unused (messagein,refIn,reply)
  416.     /* we of course don't do anything here */
  417.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  418. }
  419.  
  420. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  421. {                                                           /* no printing handler in yet, so we'll ignore this */
  422.     /* the operation is functionally identical to the ODOC event, with the additon */
  423.     /* of calling your print routine.  */
  424. #pragma unused (messagein,refIn,reply)
  425.     /* we of course don't do anything here */
  426.     return(errAEEventNotHandled);                           /* we have no docs, so no pdoc events should come to us */
  427. }
  428.  
  429. /* Standard Quit event handler, to handle a Quit event from the Finder, for example.  */
  430. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life.  */
  431. /* OK, it's a few months after I wrote that comment, and I've seen a lot of code */
  432. /* come through DTS that calls ExitToShell from quit handlers.  Let me explain... */
  433. /* When an AppleEvent Handler is called (like this quit handler) you are ALMOST */
  434. /* 100% in your application world.  A5 is right, you can call any toolbox function, */
  435. /* you can call your own routines, everything _seems_ like you are in complete  */
  436. /* control.  Well, almost but not quite.  The routine has been dispatch to from the */
  437. /* AppleEvent Manager's space, so you _must_ return to that at some point! */
  438. /* Which is why you can't call ETS from here.  When you call ExitToShell from an */
  439. /* AE Handler, the most likely thing that happens is the FInder quits, and your  */
  440. /* application keeps running.  Which ain't what you want, y'know? */
  441. /* so, DON'T CALL EXITTOSHELL FROM AN APPLEEVENT HANDLER!!!!!!!!!!!!!! */
  442. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  443. {
  444. #pragma unused (messagein,refIn,reply)
  445.     gQuit = true;
  446.     return(noErr);
  447. }
  448.  
  449.  
  450. /* This is my sample help dialog.  Does not do anything, expand as you need */
  451. void SampleHelpDialog(void)
  452. {
  453.     DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1);
  454.     short itemhit = 0;
  455.     while (itemhit != 1) {
  456.         ModalDialog((ModalFilterProcPtr)nil, &itemhit);
  457.     }
  458.     DisposDialog(tdial);
  459. }
  460.  
  461.  
  462. #pragma segment Initialize
  463. void InitalizeApp(void)
  464. {
  465.     Handle myMenu;
  466.     MenuHandle helpHandle, appleMenuHandle;
  467.     StringHandle helpString;
  468.     short count;
  469.     long vers;
  470.  
  471.     MaxApplZone();
  472.     InitGraf((Ptr)&qd.thePort);
  473.     InitFonts();
  474.     InitWindows();
  475.     InitMenus();
  476.     TEInit();
  477.     InitDialogs(nil);
  478.     InitCursor();
  479.     /* Check system version */
  480.     Gestalt(gestaltSystemVersion, &vers);
  481.     vers = (vers >> 8) & 0xf;                               /* shift result over and mask out major version number */
  482.     if (vers < 7) {
  483.         StopAlert(kBadSystem, nil);
  484.         ExitToShell();
  485.     }
  486.     InitAEStuff();
  487.     /* set up my menu junk */
  488.     myMenu = GetNewMBar(kMBarID);
  489.     SetMenuBar(myMenu);
  490.     appleMenuHandle = GetMHandle(kAppleMenu);
  491.     AddResMenu(appleMenuHandle, 'DRVR');
  492.     /* now install my Help menu item in the Help Manager's menu */
  493.     HMGetHelpMenuHandle(&helpHandle);                       /* Get the Hlpe menu handle */
  494.     count = CountMItems(helpHandle);                        /* How many items are there? */
  495.     helpString = GetString(kHelpString);                    /* get my help string */
  496.     DetachResource(helpString);                             /* detach it */
  497.     HNoPurge(helpString);
  498.     MoveHHi((Handle)helpString);
  499.     HLock((Handle)helpString);
  500.     InsMenuItem(helpHandle, (Ptr)*helpString, count + 1);       /* insert my item in the Help menu */
  501.     gHelpItem = CountMItems(helpHandle);                    /* The number of the item */
  502.     
  503.     InsertMenu(GetMenu(90), -1);
  504.     DrawMenuBar();
  505.     GetCurrentProcess(&gOurSN);                             /* Get our process serial number for later use, if needed */
  506.     
  507. }
  508.  
  509.  
  510. #pragma segment Main
  511. WindowPtr AddNewWindow(short theID)
  512. {
  513.     windowCHandle setControls;
  514.     WindowPtr tempWP;
  515.     short cnt = 0;
  516.     tempWP = GetNewWindow(theID, 0, (WindowPtr)-1);         /* get a new window */
  517.     ((WindowPeek)tempWP)->windowKind = kMyDocumentWindow;       /* mark it as my document window */
  518.     setControls = (windowCHandle)NewHandleClear(sizeof(windowControl));     /* add our control structure to it */
  519.     SetWRefCon(tempWP, (long)setControls);                  /* stop stuffing refCon directly <ckh 1.0.3> */
  520.     HLock((Handle)setControls);                             /* lock it down while we fill it*/
  521.     
  522.     /* add pointers to our procedures for drawing, saving, and closing */
  523.     /* This way, all I need is one dispatch point for drawing, closing */
  524.     /* or whatever, I don't have to case off the window kind to go to the  */
  525.     /* correct routine.  Kinda like object-oriented programming, but I won't */
  526.     /* admit that. */
  527.     (*setControls)->drawMe = DrawMain;
  528.     (*setControls)->clickMe = DoDocumentClick;
  529.     (*setControls)->sizeMe = SizeMain;
  530.     (*setControls)->generalData = NewHandle(0);
  531.     return(tempWP);
  532. }
  533.  
  534. void SizeMain(WindowPtr theWindow, short how)
  535. {
  536. #pragma unused (how )
  537.     WindowPtr tempWP;
  538.     GetPort(&tempWP);
  539.     InvalRect(&theWindow->portRect);
  540.     SetPort(tempWP);
  541. }
  542.  
  543. void NilProc(void)
  544. {
  545.     
  546. }
  547.  
  548. /* This is a structure I defined to make it easier for me to add a new */
  549. /* dialog item to a DITL  */
  550. /* The definition of this comes from Inside Mac volume I, page 427 */
  551. /* or Inside Mac: Mac Toolbox  Essentials page 6-153 */
  552. typedef struct ditlItemTemplate {
  553.     long placeHolder;
  554.     Rect boundsRect;
  555.     Byte itemType;
  556.     Byte followingCount;
  557. } ditlItemTemplate;
  558.  
  559. /* My function for creating a DITL, creating a dialog, and running the dialog */
  560. /* without using resources */
  561. void NoResDialog(void)
  562. {
  563.  
  564. DialogPtr myDialog;
  565. short hitItem = 0;
  566.  
  567. /* rectangle for our dialog */
  568. Rect theBounds =  { 40, 40, 250, 300};
  569.  
  570. /* rectangles for our two dialog items */
  571.  
  572. Rect theOKRect =  { 100, 100, 120, 160 };
  573.  
  574. Rect thenotOKRect =  {130, 100, 150, 160  };
  575.  
  576.  
  577.     Rect tempRect;                                          /* these  three are here for all the GetDItem/SetDItem calls*/
  578.     short tempItem;
  579.     Handle tempHandle;
  580.  
  581. /* An empty handle that we will build our dialog item list (DITL) in */
  582. Handle ditlList = NewHandle(0);
  583.  
  584. /* scratch variables */
  585. Size currentSize;
  586. Size stringCount;
  587. Str15 theOKword = "\pOK";
  588. short *theDPtr;
  589.  
  590. /* The item template (based on our structure above) that we'll use to create our DITL */
  591. ditlItemTemplate currentItem;
  592.  
  593.  
  594. /* add an OK button to the dialog by hand-building  */
  595. /* a DITL */
  596.  
  597. /* first add the count of items that will be in the DITL */
  598. SetHandleSize(ditlList, 2);
  599. theDPtr = (short *)*ditlList;
  600.  
  601. /* I'm creating a two item list, one for the OK button, the other for the Not OK button */
  602. *theDPtr = 1;
  603.  
  604. /* Set up our first item, the OK button */
  605. currentItem.placeHolder = 0;                            /* always 0 */
  606. currentItem.boundsRect = theOKRect;                     /* rectangle to use */
  607. currentItem.itemType = ctrlItem;                        /* what type of item it is, it's a button */
  608. currentItem.followingCount = theOKword[0];              /* how long the button title is in bytes */
  609.  
  610. /* get the current size of the item list, and append this item definition to the handle */
  611. currentSize = GetHandleSize(ditlList);
  612. SetHandleSize(ditlList, currentSize + sizeof(currentItem));
  613. BlockMove((Ptr)¤tItem, (Ptr)(*ditlList + currentSize), sizeof(currentItem));
  614.  
  615. /* now move the text of the OK word into the handle */
  616. /* NOTE:  It's got to be even, so if the string is odd */
  617. /* I'll actually move one more byte than is there */
  618.  
  619. /* Obviosly I know what it is in this case, I'm just doing this so you'll see */
  620. /* what would need to be done in the generic case */
  621.  
  622. stringCount = theOKword[0];
  623. if (stringCount & 0x1)   /* if odd */
  624.     stringCount++;        /* make even */
  625. currentSize = GetHandleSize(ditlList);
  626. SetHandleSize(ditlList, currentSize + stringCount);    
  627. BlockMove((Ptr)&theOKword[1], (Ptr)(*ditlList + currentSize), stringCount);
  628.  
  629. /* Now add another button, the Not OK button */
  630. currentItem.placeHolder = 0;                            
  631. currentItem.boundsRect = thenotOKRect;              
  632. currentItem.itemType = userItem;                      
  633. currentItem.followingCount =0;                   
  634.  
  635. /* get the current size of the item list, and append this item definition to the handle */
  636. currentSize = GetHandleSize(ditlList);
  637. SetHandleSize(ditlList, currentSize + sizeof(currentItem));
  638. BlockMove((Ptr)¤tItem, (Ptr)(*ditlList + currentSize), sizeof(currentItem));
  639.  
  640.  
  641. /* So, we've built a DITL.  Now we can create the dialog, since we have something to  */
  642. /* pass to it */
  643. /* we're creating it invisibly, since we have to add the drawing proc */
  644. /* for the user item after we create the dialog */
  645. myDialog = NewDialog(nil, &theBounds, nil, false, dBoxProc, (WindowPtr)-1, false, nil, ditlList);
  646.  
  647.             GetDItem(myDialog, 2, &tempItem, &tempHandle, &tempRect);
  648.             SetDItem(myDialog, 2, tempItem, (Handle)BorderDefault, &tempRect);
  649. ShowWindow(myDialog);
  650. /* run it with ModalDialog! */
  651. do {
  652.     ModalDialog((ModalFilterProcPtr)nil, &hitItem);
  653. }
  654.         while (hitItem != 1);
  655. DisposeDialog(myDialog);
  656. // the Dialog manager has deleted the DITL handle for us
  657. }
  658.  
  659. /* BorderDefault draws a heavy border around the default button (in this case the OK button ) */
  660. /* Again, not necessary if the new DM calls are in */
  661. pascal void BorderDefault(DialogPtr dwind, short dinum)
  662. {
  663. #pragma unused (dinum)
  664.     short itemtype;
  665.     Handle itemhandle;
  666.     Rect borderRect;
  667.     GetDItem(dwind, ok, &itemtype, &itemhandle, &borderRect);
  668.     /* ok is defined as 1 in the interfaces.  If you'd like another item outlined, */
  669.     /* change this number, of course. */
  670.     InsetRect(&borderRect, -4, -4);
  671.     PenSize(3, 3);
  672.     FrameRoundRect(&borderRect, 16, 16);
  673.     PenSize(1, 1);
  674. } /* end BorderDefault */
  675.