[comp.sys.mac.programmer] Programmers' One-Liners

pepke@gw.scri.fsu.edu (Eric Pepke) (09/06/90)

It's been a while since I sent out a copy of these, so here goes.

Here is the latest version of the Macintosh Programmers' One-Liners.  It's now 
two pages long.

The Macintosh One-Liners are intended to condense onto a couple of sheets of 
paper information about some of the most common Macintosh problems and 
programming pitfalls.  Each one-liner is a single line of text, shorter than 80 
characters, which informs about one aspect of Macintosh use or programming.  

The one-liners are brief and do not give complete information about their 
topics.  This is intentional.  Detailed documentation exists elsewhere, mostly
in Inside Macintosh and in the Technical Notes.  If you need more information
than is provided in a one-liner, you should be able to determine it by a little
experimentation or by looking it up using the words in the one-liner as hints.

One-liners give either facts or advice.  The facts may be obvious to some 
people and obscure to others but are important for all.  The advice is 
intended to help keep people from running into the most common nontrivial 
problems.  Like proverbs, the advice may not be absolute and may sometimes be 
more conservative than is strictly neccessary.  However, I have found that a 
little constructive paranoia can go a long way toward avoiding problems, and
more than once I have taken a precaution which seemed extreme at the time but
which saved my skin later on.

The one-liners started as a list I made for myself of things to remember
while writing programs.  I have augmented them with my condensed records of
several years of Info-Mac, Usenet, and Delphi digests and one year of Usenet 
reading.  People who have contributed to the list since its first release are 
mentioned at the end.  The result is very much a gestalt of the Macintosh lore 
I have seen and depends on the wisdom and efforts of many people.  If I have
forgotten to include your name, I apologize.

Send suggestions for additional one-liners to pepke@gw.scri.fsu.edu on the
Internet or PEPKE@FSU on BITNET.  Have fun.

The Main Loop and Events
Call MaxApplZone and MoreMasters when the application starts up.
If you call SetApplLimit, do it before calling MaxApplZone.
Use HT in MacsBug while running to estimate how many times to call MoreMasters.
Don't use SetEventMask to disable mouseUp events.  Better not to use it at all.
SetPort to a known good grafPort once every time through the event loop.
Calling WaitNextEvent with more than 50 ticks will fail on some systems.
Set the cursor on suspend and resume events.
Call GetDblTime to get the maximum time for a double click.
Measure double click time from mouse up to mouse down.
Call either WaitNextEvent or both GetNextEvent and SystemTask.
Call IsDialogEvents and DialogSelect even if GetNextEvent returns false.

Menus
Use SetItem to include meta characters literally in menus.
Never make MENU resources purgeable.

Resources
GetResource never produces resNotFound.  Check for a NIL handle instead.
To create a resource file, call Create, then CreateResFile.
To open a resource file read-only for shared access, use OpenRFPerm.
Don't leave ResLoad set to false.
GetResource on a dctb may return a non-resource copy of the dctb.

Windows, Alerts, and Dialogs
Move and size windows to the bounding box of GetGrayRgn.
Hide scroll bars when deactivating a window.
Call DrawGrowIcon when activating or deactivating a window with a grow region.
DrawGrowIcon does not check to see if the window has a grow region.
Call PenNormal before calling DrawGrowIcon.
itemHit will not be set when a dialog filter is called.
Use a disabled UserItem to draw the roundrect outline around the OK button.
ModalDialog assumes the dialog is already visible and in the front.
Use screenBits . bounds to center dialogs, alerts, etc. below the menu bar.
If you save window locations in files, they may not be valid for all monitors.
DragWindow expects startPt in boundsRect; if not it may not call SelectWindow.
SelectWindow does not automatically call SetPort.  You must do that yourself.
DialogSelect responds to activate events but ignores suspend/resume events.
Call PenNormal before calling DrawControls.
If you use SetOrigin, call SetOrigin(0, 0) before calling DrawControls.
To find the position of a window, use LocalToGlobal on the origin.
The Window Manager erases windows to the WMgr port's bkPat, not the window's.

Drawing
Always set the VisRgn and ClipRgn of offscreen ports.
Set the ClipRgn first when making a picture.
Don't make rowBytes in bitMaps greater than 8191.
To dim text, draw a rectangle with penPat=gray and penMode=patBic over it.
To draw rotated text, draw to an offscreen bitmap, rotate it, and CopyBits it.
Don't use picSize to determine the size of a picture.  Check the handle size.
Never draw outside a window except in XOR mode for temporary effects like drag.
To avoid animation flicker, synchronize drawing to the vertical retrace.
Lock handles to pictures before calling DrawPicture.
CopyBits on more than 3Kb data will work, but it might have to allocate memory.
The small Mac screen is 512 pixels wide by 342 pixels high including menu bar.

Files
Don't write in the application file.  This will fail with read-only devices.  
Use PBGetVInfo to convert a VRefNum to a volume name. 
Delete uses the Poor Man's Search Path, so don't delete blindly.
File Manager routines with dirID=0 use the Poor Man's Search Path.
Truncate and reallocate files before overwriting to reduce fragmentation.
Check/change the creator and type of Save As... files before overwriting.
If you rewrite files by deleting and creating, copy all Finder information.
Directory ID's are longs, not shorts.  Shorts work ALMOST all the time.
If a file version number appears in a file manager call, always set it to 0.
To convert a pathRefNum to a name or file number, use PBGetFCBInfo.
Prevent the creation of files with names that begin with a period.
Write/update the Finder info before writing data or resource forks.

Interrupts and VBL Tasks
Don't call any Memory Manager routines during an interrupt.
Unlocked handles may not be valid during an interrupt.
To synchronize to the vertical retrace on Macs with slots, use SlotVInstall.

Handles and Pointers
Lock handles before passing their dereferenced pointers to any routine.
Lock handles before setting referenced data to expressions containing functions
Put an odd long at location zero on a 68000 to help find NIL handle references.
Call MoveHHi before locking a handle to avoid memory fragmentation.
Use HGetState/HLock/HSetState to lock a handle then put it back as it was.

General
Always use unsigned characters within text and Pascal-format strings.
Save application preferences in a folder named Preferences in the System Folder
Use SysEnvirons to find the System (Blessed) Folder.
Use GetAppParms to get the name of the application.
The high bit of SysParam . volClik enables the alarm clock.
Check the application name at $910 before exiting with ES within MacsBug.
To exit to shell in the mini-debugger, enter SM 0 A9 F4 and then G 0.
In Pascal, don't nest procedures to be passed by procedure pointer.
In Pascal, "with theHandle^^" is unsafe if memory compaction can occur.

Controversy Corner (Don't shoot me; I'm just the messenger.)
Avoid writing tail patches for traps.
There is no official way to tell if MultiFinder is running or not.

Compiled by Eric Pepke
Additional material by Steve Maker, Keith Rollin, Gregory Dudek, Brian Bechtel,
Henry Minsky, Carl C. Hewitt, Jim Lyons, Alex Lau, Kent Borg, Peter W. Poorman,
Ross Yahnke, Mark Fleming, Mark Anderson.

Eric Pepke                                    INTERNET: pepke@gw.scri.fsu.edu
Supercomputer Computations Research Institute MFENET:   pepke@fsu
Florida State University                      SPAN:     scri::pepke
Tallahassee, FL 32306-4052                    BITNET:   pepke@fsu

Disclaimer: My employers seldom even LISTEN to my opinions.
Meta-disclaimer: Any society that needs disclaimers has too many lawyers.