home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / Information / CSMP Digest / volume 2 / csmp-v2-015.txt < prev    next >
Encoding:
Text File  |  1994-12-08  |  35.3 KB  |  895 lines  |  [TEXT/R*ch]

  1. C.S.M.P. Digest             Tue, 23 Feb 93       Volume 2 : Issue 15
  2.  
  3. Today's Topics:
  4.  
  5.     Disabling editBox items (long)
  6.     setwindowpic
  7.     Modifying width of PopUp menus in System 7.1
  8.     Finding Application to Launch
  9.     Slow drawing under System 7
  10.     Color animation in After Dark...HELP!
  11.  
  12.  
  13.  
  14. The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
  15.  
  16. The digest is a collection of article threads from the usenet newsgroup
  17. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  18. regularly and want an archive of the discussions.  If you don't know what a
  19. newsgroup is, you probably don't have access to it.  Ask your systems
  20. administrator(s) for details.  If you don't have access to news, you can
  21. post articles to any newsgroup by mailing your article to
  22.     newsgroup@cs.utexas.edu
  23. So, to post an article to comp.sys.mac.programmer, mail your article to
  24.     comp-sys-mac-programmer@cs.utexas.edu
  25. Note the '-' instead of '.' in the newsgroup name.  Be sure to ask that
  26. replies be emailed to you instead of posted to the group, and give your
  27. email address.
  28.  
  29. Each issue of the digest contains one or more sets of articles (called
  30. threads), with each set corresponding to a 'discussion' of a particular
  31. subject.  The articles are not edited; all articles included in this digest
  32. are in their original posted form (as received by our news server at
  33. cs.uoregon.edu).  Article threads are not added to the digest until the last
  34. article added to the thread is at least one month old (this is to ensure that
  35. the thread is dead before adding it to the digest).  Article threads that
  36. consist of only one message are generally not included in the digest.
  37.  
  38. The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu
  39. [128.223.8.8] in the directory /pub/mac/csmp-digest.  Be sure to read the
  40. file /pub/mac/csmp-digest/README before downloading any files.  The most
  41. recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the
  42. directory /info-mac/digest/csmp.  If you don't have ftp capability, the sumex
  43. archive has a mail server; send a message with the text '$MACarch help' (no
  44. quotes) to LISTSERV@ricevm1.rice.edu for more information.
  45.  
  46. The digest is also available via email.  Just send a note saying that you
  47. want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
  48. automatically receive each new issue as it is created.  Sorry, back issues
  49. are not available through the mailing list.
  50.  
  51. Send administrative mail to mkelly@cs.uoregon.edu.
  52.  
  53.  
  54. -------------------------------------------------------
  55.  
  56. From: jesjones@stein.u.washington.edu (Jesse Jones)
  57. Subject: Disabling editBox items (long)
  58. Date: 22 Jan 1993 03:59:27 GMT
  59. Organization: University of Washington, Seattle
  60.  
  61.  
  62.    There have been several posts asking how to disable editBox's in the last
  63. year or so. I had some code that did the trick for a dialog with one editBox,
  64. but it was a bit of a hack involving a userItem and a hidden editBox. A few
  65. days ago I modified another of the dialogs in my program so that it required
  66. two editBox's to be disabled. Naturaly I took the opportunity to rewrite my
  67. code in a more general fashion. 
  68.  
  69.    The new code requires that the dialog procedure call only two procedures,
  70. works with any number of editBox's, can disable/enable any number of editBox's,
  71. and doesn't require any modifications to the DITL list. The two required
  72. procedures are listed below:
  73.  
  74. PROCEDURE EnableEditBox (dptr: DialogPtr; item: INTEGER; enable: BOOLEAN);
  75.  
  76. PROCEDURE GreyFilter (dptr: DialogPtr; VAR Event: EventRecord; 
  77.                              VAR item: INTEGER): BOOLEAN;
  78.                              
  79. EnableEditBox should be called once at the start of the dialog procedure to
  80. either disable the item or enable it (it may have been disabled the last
  81. time the dialog procedure was called). The GreyFilter is a filter proc passed 
  82. to ModalDialog. It's used to grey out the editBox's when an update event occurs.
  83. You can, of course, use your own filter proc as long as you also call 
  84. GreyFilter. And that's all there is to using the code! 
  85.  
  86.    The code itself is a bit more complex. To keep track of the disabled 
  87. editBox's I place a handle to an array of booleans in the dialog's window refCon.
  88. The size of the array is determined by the number of items in the dialog. If an 
  89. element in the array is TRUE then the editBox with corresponding item number is 
  90. disabled. The type declaration for the array is shown below.
  91.  
  92. TYPE
  93.     GreyHand = POINTER TO GreyPtr;
  94.     GreyPtr  = POINTER TO GreyList;
  95.     GreyList = ARRAY [1..1000] OF BOOLEAN;        
  96.     
  97.    When the EnableEditBox procedure disables an editBox it first checks to see
  98. if the editBox is the currently selected editBox. If it is selected the below
  99. procedure is called to find another editBox to select.
  100.  
  101. PROCEDURE GetAnotherEditBox (dptr: DialogPtr; item: INTEGER): INTEGER;
  102.     VAR
  103.         peek : DialogPeek;
  104.         index: INTEGER;
  105.         type : INTEGER;
  106.         data : HANDLE;
  107.         box  : Rect;
  108. BEGIN
  109.     peek := DialogPeek(dptr);
  110.     FOR index := 1 TO INT(peek^.items^^)+1 DO
  111.         GetDItem(dptr, index, type, data, box);
  112.         type := And(type, 127);                (* mask out itemDisable flag *)
  113.         IF (type = editText) AND (index <> item) THEN RETURN index END;
  114.     END;
  115.     RETURN 0;                                    (* return 0 if can't find an editBox *)
  116. END GetAnotherEditBox;
  117.  
  118.    And now we come to the central procedure, EnableEditBox. This procedure does 
  119. the following:
  120.     1) Init the array of disabled editBox's. NewHandleClear is used so that all
  121.         the of the elements start out FALSE.
  122.     2) GetDItem is called to find the type for the item. The itemDisable flag
  123.         is then masked out so that we can use a simple equality test with editBox.
  124.     3) To disable an editBox it is first changed to a staticText item. This 
  125.         prevents the user from selecting or tabbing to the disabled editBox. If
  126.         the editBox is the currently selected editBox we either select a different
  127.         editBox or tell the Dialog Manager that there are no longer any editBox's 
  128.         by setting editField to -1.
  129.     4) Enabling an editBox is simpler: its type is set back to editText and its
  130.         text is selected (which resets editField). Both enable and disable 
  131.         invalidate the items rectangle so that the Dialog Manager and GreyFilter
  132.         can redraw the item.
  133.  
  134. PROCEDURE EnableEditBox (dptr: DialogPtr; item: INTEGER; enable: BOOLEAN);
  135.     VAR
  136.         type : INTEGER;
  137.         new  : INTEGER;
  138.         data : HANDLE;
  139.         box  : Rect;
  140.         list : GreyHand;
  141.         peek : DialogPeek;
  142.         sPort: GrafPtr;
  143. BEGIN
  144.     GetPort(sPort);
  145.     SetPort(dptr);
  146.     peek := DialogPeek(dptr);
  147.     list := GetWRefCon(dptr);
  148.     IF list = NIL THEN                        (* create the array *)
  149.         list := NewHandleClear(LONG(peek^.items^^)+1);    
  150.         SetWRefCon(dptr, list);
  151.     END;
  152.     GetDItem(dptr, item, type, data, box);    (* get the item type *)
  153.     type := And(type, $7F);                   (* remove itemDisable flag *)
  154.     IF (enable = FALSE) AND (type = editText) THEN     
  155.         SetDItem(dptr, item, statText+itemDisable, data, box);    
  156.         IF peek^.editField = item-1 THEN      (* is it the selected editBox? *)
  157.             new := GetAnotherEditBox(dptr, item);        
  158.             IF item > 0 THEN
  159.                 SelIText(dptr, new, 0, 20);   (* select a different editBox *)        
  160.             ELSE                                                        
  161.                 SelIText(dptr, item, 0, 0);                    
  162.                 peek^.editField := -1;        (* there are no more editBox's! *)        
  163.             END;                                                        
  164.         END;
  165.         InvalRect(box);                                            
  166.         list^^[item] := TRUE;                                    
  167.     ELSIF enable AND list^^[item] THEN                            
  168.         SetDItem(dptr, item, editText, data, box);        
  169.         SelIText(dptr, item, 0, 20);                        
  170.         InvalRect(box);                                            
  171.         list^^[item] := FALSE;                                    
  172.     END;
  173.     SetPort(sPort);
  174. END EnableEditBox;
  175.  
  176.     GreyFilter calls the below procedure to grey out the text in a disabled
  177. editBox. GetBounds is a utility procedure I wrote to get the bounds for
  178. a dialog item. You can just as easily use GetDItem.
  179.  
  180. PROCEDURE GreyEditBox (dptr: DialogPtr; item: INTEGER);
  181.     VAR
  182.         box  : Rect;
  183.         sPen : PenState;
  184.         sPort: GrafPtr;
  185. BEGIN    
  186.     GetPort(sPort);
  187.     SetPort(dptr);
  188.     GetPenState(sPen);
  189.     box := GetBounds(dptr, item);
  190.     InsetRect(box, -3, -3);        (* grey out the text *)
  191.     PenPat(gray);
  192.     PenMode(patBic);
  193.     PaintRect(box);
  194.     PenPat(black);                    (* draw the frame *)
  195.     PenMode(patCopy);
  196.     FrameRect(box); 
  197.     SetPenState(sPen);
  198.     SetPort(sPort);
  199. END GreyEditBox;
  200.  
  201.     All of my dialogs use a filter proc called DefaultFilter. If the dialog
  202. needs to do some extra filtering it uses a different filter proc that first
  203. calls DefaultFilter. GreyFilter is no exception: it calls DefaultFilter and
  204. takes action only when DefaultFilter returns FALSE.
  205.     The DefaultFilter is used to keep my dialogs consistent: Return/Enter always
  206. work like a click on the OK button, and Escape/Tilde work like a click on the
  207. Cancel button. Even more important, DefaultFilter updates the windows in my
  208. application. If this isn't done its possible that applications in the background
  209. will get no time while the dialog is up (see TechNote 304 for details). 
  210.  
  211. PROCEDURE DefaultFilter (dptr: DialogPtr; VAR Event: EventRecord; 
  212.                                  VAR item: INTEGER): BOOLEAN;
  213.     VAR 
  214.         ch, key: CHAR;
  215.         wptr   : WindowPtr;
  216.         control: ControlHandle;
  217.         button : INTEGER;
  218.         handled: BOOLEAN;
  219. BEGIN
  220.     handled := FALSE;
  221.     IF Event.what = keyDown THEN
  222.         ch := Event.msgChars[3];
  223.         key := Event.msgChars[2];
  224.         IF (key = ReturnKey) OR (key = EnterKey) THEN 
  225.             button := 1;
  226.             handled := TRUE;
  227.         ELSIF (key = TildeKey) OR (key = EscapeKey) THEN 
  228.             button := 2;
  229.             handled := TRUE;
  230.         ELSIF (cmd IN Event.modiFlags) AND (ch = '.') THEN 
  231.             button := 2;
  232.             handled := TRUE;
  233.         END;
  234.         IF handled THEN                    (* make sure the button is enabled *)
  235.             control := GetControl(dptr, button);
  236.             IF control^^.contrlHilite = 0 THEN item := button END;
  237.         END;
  238.     ELSIF Event.what = updateEvt THEN
  239.         wptr := Event.message;
  240.         IF wptr <> dptr THEN
  241.             WindEvent(Event);                        (* update my windows *)
  242.         END;
  243.     END;
  244.     RETURN handled;
  245. END DefaultFilter;
  246.  
  247.    The GreyFilter takes care of greying out all of the disabled editBox's. This
  248. is a simple matter except for one minor detail: filter procs are called before
  249. the Dialog Manager takes any action. So, it's not sufficient to just grey out 
  250. the editBox when we get an updateEvt. What we would have to do is first draw
  251. the text in the editBx, grey it out, and then validate the editBox so the
  252. Dialog Manager doesn't overwrite all of our work.
  253.    The GreyFilter procedure takes a simpler approach. Update events are handled
  254. normally by the Dialog Manager, but when an update event occurs GreyFilter adds
  255. a special key to the Event queue to signal that an update occured. After the
  256. Dialog Manager processes the update event it will call GreyFilter again with
  257. the special key so that the editBox's may be greyed out.
  258.  
  259. PROCEDURE GreyFilter (dptr: DialogPtr; VAR Event: EventRecord; 
  260.                              VAR item: INTEGER): BOOLEAN;
  261.     VAR 
  262.         list   : GreyHand;
  263.         peek   : DialogPeek;
  264.         index  : INTEGER;
  265.         handled: BOOLEAN;
  266.         err    : OSErr;
  267. BEGIN
  268.     handled := DefaultFilter(dptr, Event, item);
  269.     IF NOT handled THEN
  270.         IF Event.what = updateEvt THEN        
  271.             err := PostEvent(keyDown, 0);        
  272.         ELSIF Event.what = keyDown THEN
  273.             IF LoWord(Event.message) = 0 THEN
  274.                 list := GetWRefCon(dptr);        
  275.                 peek := DialogPeek(dptr);
  276.                 IF list <> NIL THEN
  277.                     FOR index := 1 TO INT(peek^.items^^)+1 DO
  278.                         IF list^^[index] THEN GreyEditBox(dptr, index) END;
  279.                     END;
  280.                 END;
  281.                 handled := TRUE;                            
  282.             END;
  283.         END;                                
  284.     END;
  285.     RETURN handled;
  286. END GreyFilter;
  287.  
  288.   --Jesse Jones
  289.   
  290. jesjones@u.washington.edu
  291.  
  292. ---------------------------
  293.  
  294. From: rmaag@iiic.ethz.ch (Rolf Maag)
  295. Subject: setwindowpic
  296. Organization: Dept. Informatik, Swiss Federal Institute of Technology (ETH), Zurich, CH
  297. Date: Thu, 21 Jan 1993 14:59:25 GMT
  298.  
  299. Hi there...
  300.  
  301. i have some questions about getwindowpic and setwindowpic.
  302.  
  303. so far, i have done all my updating the 'old fashioned' way,
  304. using update events...
  305. now, with my latest application redrawing would be awfully complicated...
  306.  
  307. does the system all the updating when a window picture is set?
  308.  
  309. and when i draw into the window, is the window picture updated automatically?
  310.  
  311. if anybody could send me some sample code showing me how to use
  312. getwindowpic and setwindowpic, i'd be very happy.
  313.  
  314. thanx and regards Rolf
  315.  
  316.  
  317. +++++++++++++++++++++++++++
  318.  
  319. From: stern@comb1.comb.umd.edu (Brian Stern; COMB)
  320. Date: 22 Jan 93 16:33:00 GMT
  321. Organization: University of Maryland, Center of Marine Biotechnology
  322.  
  323. In article <1993Jan21.145925.7504@neptune.inf.ethz.ch>, rmaag@iiic.ethz.ch (Rolf Maag) writes...
  324. >Hi there...
  325. >i have some questions about getwindowpic and setwindowpic.
  326. >
  327. I use the following code in my initialization unit to put up a
  328. splash screen:
  329. var
  330.   aPicHand: PicHandle;
  331.   PicWind: WindowPtr;
  332.   PicWinRect: Rect;
  333.   TempBool: Boolean;
  334.  
  335. {Read in the picture and display it}
  336.   aPicHand := PicHandle(GetResource('PICT', 128));{Read in the picture}
  337.   PicWind := NewWindow(nil, PicWinRect, '', True, altDBoxProc, WindowPtr(-1),False,0);
  338.  
  339.  SetWindowPic(PicWind, aPicHand);{Insert the picture into the window}
  340.   TempBool := CheckUpdate(Event);{Make the win mgr draw the window pic}
  341.  
  342. It normally isn't necessary to call CheckUpdate to draw a picture
  343. in a window but this example draws it immediately. A picture
  344. inserted into the windowPic field of a window record will be
  345. drawn the next time a call is made to WaitNextEvent. What actually
  346. happens is that if there are no other events in the event queue of
  347. a higher priority than an update event, WNE calls CheckUpdate.
  348. CheckUpdate then walks the window list from front to back looking
  349. for visible windows with non-null update regions. If it finds one
  350. that also has a picture associated with it, it draws the picture
  351. in the window. It then continues until it finds a window with a
  352. non-null update region and no picture. It then returns an update
  353. event for that window, which is processed by your program in
  354. the usual way. Note that you will never receive an update event
  355. for a window with a non-null windowPic field. If you insert a
  356. picture into a window with SetWindowPic and later change it and
  357. want it to be redrawn you can do an InvalRect
  358. (theWindow^.portrect). The picture will be redrawn the next time
  359. thru your event loop if no other events are pending. Update events
  360. have the lowest priority except for null events so mouse clicks,
  361. key presses will be processed first.
  362.  
  363. Good Luck,
  364.  
  365. Brian Stern
  366. Stern@mbimail.umd.edu
  367.  
  368. __________________________________________________________________
  369. According to a software licensing notice:
  370. All trademarks are held by their respective owners.
  371. __________________________________________________________________
  372.  
  373. ---------------------------
  374.  
  375. From: andersm@prism.CS.ORST.EDU (Mark Anderson)
  376. Subject: Modifying width of PopUp menus in System 7.1
  377. Date: 19 Jan 93 02:53:19 GMT
  378. Organization: CS Dept, Oregon State University
  379.  
  380. I am writing a program and have a dialog box that contains three popup menus.
  381. I am changing the font used by the popups to Geneva 9 via mucking around with
  382. some low-memory globals.  Anyway, the popup rectangles are wider than the menus
  383. they are linked to, so I wanted to widen the menus before they are displayed.
  384. What I did was check to see if the (**popMenu).menuWidth field was less than
  385. the width of the appropriate rectangle.  If it was then I just set the menuWidth
  386. field to equal the width of the rectangle.  This is done right before my call
  387. to PopUpMenuSelect.  Basically it works fine on my SE running either System 6.08
  388. or System 7.01, but on my neighbors LC running 7.1 the menu widths aren't
  389. being modified, they are just wide enough to contain that menus items.  My 
  390. question is whether or not System 7.1 does anything different with regard to
  391. pop-up menus, has PopUpMenuSelect been patched to do a CalcMenuSize?  Any help
  392. would be appreciated.
  393.  
  394.                             - Mark J. Anderson
  395.                             
  396.                         
  397.  
  398. +++++++++++++++++++++++++++
  399.  
  400. From: absurd@apple.apple.com (Tim Dierks, software saboteur)
  401. Date: 19 Jan 93 10:29:34 GMT
  402. Organization: MacDTS Marauders
  403.  
  404. In article <1jfqevINN244@flop.ENGR.ORST.EDU>, andersm@prism.CS.ORST.EDU
  405. (Mark Anderson) wrote:
  406. > I am writing a program and have a dialog box that contains three popup menus.
  407. > I am changing the font used by the popups to Geneva 9 via mucking around with
  408. > some low-memory globals.  Anyway, the popup rectangles are wider than the menus
  409. > they are linked to, so I wanted to widen the menus before they are displayed.
  410. > What I did was check to see if the (**popMenu).menuWidth field was less than
  411. > the width of the appropriate rectangle.  If it was then I just set the menuWidth
  412. > field to equal the width of the rectangle.  This is done right before my call
  413. > to PopUpMenuSelect.  Basically it works fine on my SE running either System 6.08
  414. > or System 7.01, but on my neighbors LC running 7.1 the menu widths aren't
  415. > being modified, they are just wide enough to contain that menus items.  My 
  416. > question is whether or not System 7.1 does anything different with regard to
  417. > pop-up menus, has PopUpMenuSelect been patched to do a CalcMenuSize?  Any help
  418. > would be appreciated.
  419. >                             - Mark J. Anderson
  420.  
  421. Here's some code to do what you want.  I'm right in the middle of working
  422. on this,
  423. so I can't say it's 100% correct, but I'm pretty sure it's close.  It will
  424. give
  425. you all the essential concepts, anyway.
  426.  
  427. Tim Dierks
  428. MacDTS, but I speak for myself
  429.  
  430. - --- cut here -- 8< ------
  431.  
  432. // type of a pointer to CalcMenuSize
  433. typedef pascal void (*CalcMenuSizeProc)(MenuHandle theMenu);
  434. static pascal void  CalcMenuSizePatch(MenuHandle theMenu);
  435.  
  436. // Record to use to communicate with the patch to CalcMenuSize
  437. typedef struct
  438. {   CalcMenuSizeProc    oldCMS;         // Address of the original
  439. CalcMenuSize()
  440.     MenuHandle          theMenu;        // Menu to set the width of
  441.     short               width;          // The width to set it to
  442. } CMSCommRecord;
  443.  
  444. // The record to communicate with the patch.  Making this a global is
  445. // not the ideal solution for this communication, but should work for
  446. // this particular application.  I would use a better solution, but
  447. // the global is adequate and clearer.
  448.  
  449. CMSCommRecord       gCMSParms;
  450.  
  451. // Call just like PopUpMenuSelect, only you can set the font, size, and
  452. width of the popup menu.
  453. //  Pass 0 for font, size, or width to use the defaults.
  454. long
  455. PopUpMenuSelectWithFontAndWidth(MenuHandle menu,short top,short left,short
  456. popUpItem,short font,short size,short width)
  457. {   long                menuChoice;                     // Stores the
  458. chosen menu & item
  459.     short               saveSysFontFam,saveSysFontSize; // Room for saving
  460. the current system font and size
  461.     GrafPtr             wMgrPort;                       // Pointer to the
  462. window manager port
  463.     CalcMenuSizeProc    oldCalcMenuSize;                // Address of the
  464. old CalcMenuSize procedure
  465.     
  466.     // First, we'll clean up after buggy software.  A number of commercial
  467. products
  468.     // (word processors are most common) screw up the window manager port;
  469. they leave the
  470.     // txSize field set to 12.  It and the txFont field should always be
  471. left set to 0;
  472.     // this makes them the system font and size.  So first thing we do is
  473. clean up
  474.     // after these miscreants.
  475.     
  476.     GetWMgrPort(&wMgrPort);
  477.     SetPort(wMgrPort);
  478.     TextFont(0);
  479.     TextSize(0);
  480.     
  481.     // Now, if we're going to change the font or the size, then we remember
  482. the old
  483.     // system font and size so they can be restored later
  484.     
  485.     if (font != 0 || size != 0)
  486.     {   saveSysFontFam = *(short*)SysFontFam;
  487.         saveSysFontSize = *(short*)SysFontSize;
  488.         
  489.         if (font != 0)
  490.             *(short*)SysFontFam = font;
  491.         if (size != 0)
  492.             *(short*)SysFontSize = size;
  493.         
  494.         *(long*)LastSPExtra = -1;           // This forces the system to
  495. recognize our changes
  496.     }
  497.     
  498.     // Now we need to set the width.  Unfortunately, it's not as easy as
  499. changing the
  500.     // font and size; we need to patch CalcMenuSize so we can fake the
  501. width of the menu
  502.     if (width != 0)
  503.     {   oldCalcMenuSize =
  504. (CalcMenuSizeProc)NGetTrapAddress(0x148,ToolTrap);
  505.         
  506.         gCMSParms.oldCMS = oldCalcMenuSize;
  507.         gCMSParms.theMenu = menu;
  508.         gCMSParms.width = width;
  509.         
  510.         NSetTrapAddress((long)CalcMenuSizePatch,0x148,ToolTrap);
  511.         
  512.         // Now we should zero out the menu's stored width and height to
  513. ensure that
  514.         // its size will be recalculated
  515.         
  516.         (**menu).menuWidth = 0;
  517.         (**menu).menuHeight = 0;
  518.     }
  519.     
  520.     menuChoice = PopUpMenuSelect(menu,top,left,popUpItem);
  521.     
  522.     // Now we restore the original CalcMenuSize if we changed it
  523.     if (width != 0)
  524.         NSetTrapAddress((long)oldCalcMenuSize,0x148,ToolTrap);
  525.     
  526.     // Now we restore the original font and size to their places
  527.     // if we changed them
  528.     if (font != 0 || size != 0)
  529.     {   *(short*)SysFontFam = saveSysFontFam;
  530.         *(short*)SysFontSize = saveSysFontSize;
  531.         *(long*)LastSPExtra = -1;
  532.     }
  533.     
  534.     // return the chosen menu & item
  535.     return menuChoice;
  536. }
  537.  
  538. // This is the patch to CalcMenuSize; first, we call the original
  539. // to calculate the size.  If the menu being calculated is ours,
  540. // we then change the width to our stored width.  Note that this
  541. // is a tail patch; while still frowned upon, these are not as
  542. // bad as they used to be, and it's really the best way to
  543. // accomplish our task.
  544. //
  545. // Our use of a global to store the original CalcMenuSize and
  546. // other data implies we'll be sure that A5 hasn't been changed;
  547. // we can be fairly certain this is true in this particular
  548. // case.
  549.  
  550. static pascal void
  551. CalcMenuSizePatch(MenuHandle theMenu)
  552. {   
  553.     gCMSParms.oldCMS(theMenu);          // Call the original
  554. CalcMenuSize();
  555.     
  556.     if (theMenu == gCMSParms.theMenu)   // If it's our menu, fix up the
  557. width
  558.         (**theMenu).menuWidth = gCMSParms.width;
  559. }
  560.  
  561. +++++++++++++++++++++++++++
  562.  
  563. From: mshields%peruvian.cs.utah.edu@cs.utah.edu (Michael S Shields)
  564. Date: 22 Jan 93 08:18:47 GMT
  565. Organization: University of Utah Computer Science
  566.  
  567. In article <absurd-190193022736@seuss.apple.com> absurd@apple.apple.com (Tim Dierks, software saboteur) writes:
  568. >
  569. >Here's some code to do what you want.  I'm right in the middle of working
  570. >on this,
  571. >so I can't say it's 100% correct, but I'm pretty sure it's close.  It will
  572. >give
  573. >you all the essential concepts, anyway.
  574. >
  575. >Tim Dierks
  576. >MacDTS, but I speak for myself
  577. >
  578.  
  579. [some code deleted]
  580.  
  581. >    // First, we'll clean up after buggy software.  A number of commercial
  582. >products
  583. >    // (word processors are most common) screw up the window manager port;
  584. >they leave the
  585. >    // txSize field set to 12.  It and the txFont field should always be
  586. >left set to 0;
  587. >    // this makes them the system font and size.  So first thing we do is
  588. >clean up
  589. >    // after these miscreants.
  590. >    
  591. >    GetWMgrPort(&wMgrPort);
  592. >    SetPort(wMgrPort);
  593. >    TextFont(0);
  594. >    TextSize(0);
  595. >    
  596. [more code deleted]
  597.  
  598. This section I have a question about. I found out the other day that the system
  599. software for international use(ie. Kanji) doesn't use 0 as the system font.
  600. If I set the SysFontFam global to 0 the menu and titlebar text showed up in
  601. Chicago not Osaka(is this the correct name?). Now does TextFont and TextFace
  602. have the intelligence to use the correct font or does it blindly use Chicago?
  603. This was using Kanji 7.1 on a IIsi.
  604.  
  605. Mike Shields
  606. mshields@peruvian.cs.utah.edu
  607.  
  608. ---------------------------
  609.  
  610. From: jjb@sequent.com (Jeff Berkowitz)
  611. Subject: Finding Application to Launch
  612. Date: 19 Jan 93 07:22:56 GMT
  613. Organization: Sequent Computer Systems, Inc.
  614.  
  615. I'm writing an application that will at times launch a word processor.
  616. I'd like the user to be able to select the word processor so that (at
  617. least in theory) my app will work with any WP.
  618.  
  619. It seems the right way to store the "name" of the WP is to store
  620. its creator.  This could be kept in a pref.
  621.  
  622. When time comes to launch, if the pref hasn't been set then present
  623. the user with a dialog resembling standard file so they can select
  624. the WP; stash the creator away in the pref.
  625.  
  626. Now having the creator, look it up in the desktop database using
  627. PBDTGetAPPL().  Now you have the dirID and name so you can build
  628. up the launchAppSpec.  Yes?
  629.  
  630. One thing I don't understand: the desktop database is per-volume.
  631. The active volume might not be the right place to look - it might
  632. be a floppy with no apps, for example.  So do I have to iterate
  633. the steps above on all mounted volumes?  And then what do I do if
  634. I find two volumes that contain an APPL with the correct creator...
  635. pick the most recent?  Is this what the Finder does?
  636.  
  637. For that matter, how does one "iterate the mounted volumes?"  Call
  638. GetVInfo() with incrementing drvNum's? ...IM-IV implies this won't
  639. work in general (p93).
  640.  
  641. TIA,
  642. - -- 
  643. Jeff Berkowitz, Sequent Computer Systems   jjb@sequent.com  uunet!sequent!jjb
  644.  "The event horizon of a smoking hairy golfball is on the chip" - Jim Gray
  645.  
  646. +++++++++++++++++++++++++++
  647.  
  648. From: d88-jwa@dront.nada.kth.se (Jon Wtte)
  649. Date: 19 Jan 93 12:40:45 GMT
  650. Organization: Royal Institute of Technology, Stockholm, Sweden
  651.  
  652. In <1993Jan19.072256.8502@sequent.com> jjb@sequent.com (Jeff Berkowitz) writes:
  653.  
  654. >It seems the right way to store the "name" of the WP is to store
  655. >its creator.  This could be kept in a pref.
  656.  
  657. You could also store an alias to the selected application for
  658. quick access to file servers and the likes.
  659.  
  660. >Now having the creator, look it up in the desktop database using
  661. >PBDTGetAPPL().  Now you have the dirID and name so you can build
  662. >up the launchAppSpec.  Yes?
  663.  
  664. No, unless the application is available on a presently mounted
  665. volume. You also have to iterate over all available volumes.
  666.  
  667. >For that matter, how does one "iterate the mounted volumes?"  Call
  668. >GetVInfo() with incrementing drvNum's? ...IM-IV implies this won't
  669.  
  670. No, call PBHGetVInfo with the indexed volume mode. Look in
  671. Inside Mac or Think Reference for how to do it.
  672.  
  673. What I do is I create an alias, and when I need the app, I
  674. resolve the alias. If it cannot be resolved, I search all
  675. mounted volumes using PBCatSearch for a file of type APPL
  676. and creator <whatever>.
  677.  
  678. Cheers,
  679.  
  680.                         / h+
  681. - -- 
  682.  -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
  683.  
  684.   Clearly, most humans are not rational beings; they are rationalizing beings.
  685.                      -- Mel Walker
  686.  
  687. ---------------------------
  688.  
  689. From: cegrw@cc.newcastle.edu.au (Dr Garry Willgoose: INTERNET cegrw@cc.newcastle.edu.au)
  690. Subject: Slow drawing under System 7
  691. Organization: University of Newcastle, AUSTRALIA
  692. Date: Tue, 19 Jan 1993 11:25:29 GMT
  693.  
  694. I have a program that basically puts up on screen a huge number of filled
  695. rectangles. Just a plain loop with relevamt QD commands and a call to
  696. WaitNextEvent with wait time set to 0. Well this code has worked fine to ages
  697. on a system 6 machine but when Imoved it recently to a Powerbook 170 running
  698. S7 it runs really slow ... unless I keep moving the mouse around and then it
  699. runs just like before. Actually this same behaviour is shown by another
  700. part of the code where a series of line segments is drawn so its not a 
  701. function of the particular QD calls. The picture is being saved a PICT2 as the
  702. pict is drawn.
  703.  
  704. Any ideas of where I might start to track down this problem? The program is all
  705. in Pascal on MPW (both 3.2).
  706.  
  707. Garry Willgoose
  708. Dept of Civil Eng
  709. Uni of Newcastle
  710. cegrw@cc.newcastle.edu.au
  711.  
  712.  
  713. +++++++++++++++++++++++++++
  714.  
  715. From: rmah@panix.com (Robert Mah)
  716. Organization: PANIX Public Access Unix, NYC
  717. Date: Tue, 19 Jan 1993 16:40:46 GMT
  718.  
  719. In <1993Jan19.222529.1@cc.newcastle.edu.au> cegrw@cc.newcastle.edu.au (Dr Garry Willgoose: INTERNET cegrw@cc.newcastle.edu.au) writes:
  720.  
  721.  
  722. > Just a plain loop with relevamt QD commands and a call to WaitNextEvent
  723. > with wait time set to 0. Well this code has worked fine to ages on a
  724. > system 6 machine but when Imoved it recently to a Powerbook 170 running
  725. > S7 it runs really slow ... unless I keep moving the mouse around and then
  726. > it runs just like before. 
  727.  
  728. Your comment about moving the mouse _may_ suggest that you take a look at
  729. the mouseRgn parameter to WaitNextEvent.  Perhaps you're getting an excessive
  730. amount of mouseMoved events?
  731.  
  732. Cheers,
  733. Rob
  734.  
  735.  
  736. - -- 
  737. [----------------------------------------------------------------------]
  738. [ Robert S. Mah   | Voice: 212-947-6507   | "Every day an adventure,   ]
  739. [ One Step Beyond | EMail: rmah@panix.com |  every moment a challenge" ]
  740. [----------------------------------------------------------------------]
  741.  
  742. +++++++++++++++++++++++++++
  743.  
  744. From: chh9@quads.uchicago.edu (Conrad Halling)
  745. Organization: University of Chicago
  746. Date: Thu, 21 Jan 1993 20:48:55 GMT
  747.  
  748. In article <1993Jan19.222529.1@cc.newcastle.edu.au> 
  749.   cegrw@cc.newcastle.edu.au
  750.   (Dr Garry Willgoose: INTERNET cegrw@cc.newcastle.edu.au) writes:
  751.  
  752. >I have a program that basically puts up on screen a huge number of filled
  753. >rectangles. Just a plain loop with relevant QD commands and a call to
  754. >WaitNextEvent with wait time set to 0. Well this code has worked fine to ages
  755. >on a system 6 machine but when I moved it recently to a Powerbook 170 running
  756. >S7 it runs really slow ... unless I keep moving the mouse around and then it
  757. >runs just like before. Actually this same behaviour is shown by another
  758. >part of the code where a series of line segments is drawn so its not a 
  759. >function of the particular QD calls. The picture is being saved a PICT2 as the
  760. >pict is drawn.
  761.  
  762. The PowerBook goes into resting (idling or processor cycling) mode when
  763. certain activities are not occurring.  (One of the activities that prevents
  764. resting is moving the mouse.)  This is what is causing your
  765. program to slow down.  The net result is that PowerBook behaves as if
  766. the processor were running at 1 MHz.
  767.  
  768. Read chapter 31 of Inside Macintosh Vol VI about the Power Manger.  Your
  769. program needs to call Gestalt() to determine if the Power Manager is
  770. present (p. 31-12).  (The Power Manager is present only for the Portable
  771. and PowerBooks).  If the Power Manager is present, then call IdleUpdate()
  772. (p. 31-19) each time through your event loop when you're doing something
  773. significant.  If you have nothing to do on null events, then don't call
  774. IdleUpdate(), and the PowerBook can go into rest mode, which is a good
  775. thing for battery charging.
  776. - -- 
  777. Conrad Halling
  778. c-halling@uchicago.edu
  779.  
  780.  
  781. +++++++++++++++++++++++++++
  782.  
  783. From: d88-jwa@dront.nada.kth.se (Jon Wtte)
  784. Date: 19 Jan 93 12:46:27 GMT
  785. Organization: Royal Institute of Technology, Stockholm, Sweden
  786.  
  787. In <1993Jan19.222529.1@cc.newcastle.edu.au> cegrw@cc.newcastle.edu.au (Dr Garry Willgoose: INTERNET cegrw@cc.newcastle.edu.au) writes:
  788.  
  789. >on a system 6 machine but when Imoved it recently to a Powerbook 170 running
  790. >S7 it runs really slow ... unless I keep moving the mouse around and then it
  791.  
  792. >Any ideas of where I might start to track down this problem? The program is
  793. >all in Pascal on MPW (both 3.2).
  794.  
  795.  
  796.  
  797. Start by reading the manual for your PowerBook 170. Yes,
  798. the one that came with the computer, that still has the plastic
  799. wrapping on it. It will tell you all about the "rest" mode of
  800. a PowerBook, and how to turn it off using an option-click in
  801. the "portable" control panel.
  802.  
  803. Cheers,
  804.  
  805.                         / h+
  806. - -- 
  807.  -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
  808.  
  809.   Clearly, most humans are not rational beings; they are rationalizing beings.
  810.                      -- Mel Walker
  811.  
  812. ---------------------------
  813.  
  814. From: cantrell@lamar.ColoState.EDU (Carol Cantrell)
  815. Subject: Color animation in After Dark...HELP!
  816. Date: Thu, 21 Jan 1993 05:56:23 GMT
  817. Organization: Colorado State University, Fort Collins, CO  80523
  818.  
  819. I'm writing an After Dark module that uses color table animation.  It copies
  820. repeatedly some object from offscreen graphics worlds, some of which contain
  821. colors to be animated, and some of which don't.  I want to copy the GWorlds to 
  822. the screen color index for color index--that is, color #1 in the GWorld is color
  823. on the screen, etc.  The obvious way to do this is to OR the ctFlags field
  824. with $4000; however, this copies index numbers from the GWorld to index numbers
  825. in the current PALETTE.  After Dark doesn't draw into a WINDOW, and therefore
  826. DOESN'T HAVE A PALETTE!!!   Is there any way to do this?  Help!
  827.  
  828.  Paul Cantrell 
  829.  Cantrell@Lamar.ColoState.EDU
  830.  
  831. +++++++++++++++++++++++++++
  832.  
  833. From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
  834. Organization: Kalamazoo College
  835. Date: Thu, 21 Jan 1993 20:05:41 GMT
  836.  
  837. cantrell@lamar.ColoState.EDU (Carol Cantrell) writes:
  838. >I'm writing an After Dark module that uses color table animation. ...
  839. >I want to copy the GWorlds to the screen color index for color index--
  840. >that is, color #1 in the GWorld is color [#1] on the screen, etc.
  841. >The obvious way to do this is to OR the ctFlags field with $4000;
  842.  
  843. Not _that_ obvious;  it's hidden pretty well in IM VI, actually.  :-)
  844.  
  845. >however, this copies index numbers from the GWorld to index numbers
  846. >in the current PALETTE.  After Dark doesn't draw into a WINDOW, and therefore
  847. >DOESN'T HAVE A PALETTE!!!   Is there any way to do this?  Help!
  848.  
  849. Yep, there are three ways to get the Color Indices You Want up onto the
  850. screen:
  851.     (1) Set bit 14 in ctFlags;
  852.     (2) Make the ctSeeds equal;
  853.     (3) Write directly to the screen.
  854.  
  855. (1) won't work for you, as you say, because AD opens a port not a
  856. palette.  (Actually, does it even do that?  Someone said it uses
  857. SetStdProcs() to redirect QD calls to its own nefarious ends.  I don't
  858. even want to think about that.)
  859.  
  860. (2) is probably your best bet in this case.  If the ctSeed in your
  861. source pixmap's color table is equal to the ctSeed in your dest pixmap's
  862. color table, CopyBits will take this to mean that the color tables are
  863. in fact equal.  It will not run through them and check.  Consequently,
  864. it will just copy the pixel values straight across, which has the effect
  865. you want.  (And, as a side dish, it's also the fastest possible way that
  866. CopyBits can operate.)
  867.  
  868. You can set the ctSeeds yourself, manually, if you like.  Normally,
  869. that's not a good idea, but After Dark is such a snuggly, hand-holding
  870. environment to work in, that I won't even give you the usual "now don't
  871. do this" warning.  All you gotta do is drop a 'clut' in your module with
  872. the appropriate resource ID, set a few flags, maybe check the screen
  873. depth yourself, and you're guaranteed to have the screen you want, with
  874. the colors you want.  So--do the checks, copy the screen's pixmap's
  875. pmTable's ctSeed into your GWorld's pixmap's pmTable's ctSeed, and
  876. CopyBits to your heart's content.
  877.  
  878. Alternatively, you can build a GWorld using the screen's pmTable.  But
  879. I'm not too familiar with GWorlds, so you're on your own there.
  880. - -- 
  881.  Jamie McCarthy      Internet: k044477@kzoo.edu      AppleLink: j.mccarthy
  882.  "We enjoy a patent portfolio second to none in the computer industry,
  883.   with some 30,000 patents worldwide and more than 9,000 in the U.S. alone,
  884.   and growing."                      - An IBM advertisement
  885.  
  886. ---------------------------
  887.  
  888. End of C.S.M.P. Digest
  889. **********************
  890.