home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Information / Programming / Mac Programming FAQ / csmpFAQ.txt
Encoding:
Text File  |  1995-12-03  |  100.4 KB  |  2,524 lines  |  [TEXT/R*ch]

  1. Mac Programming Frequently Asked Questions Answer Sheet
  2.  Last update: 30 September 1995
  3.  
  4. Please download a copy of this answer sheet and search it before
  5. you post to the 'net, to help reduce bandwidth.  This sheet is
  6. available in two formats for your online viewing enjoyment:
  7.  plaintext (ftp://ftp.best.com/pub/ckt/csmpFAQ.txt) and
  8.  HTML (http://www.best.com/~ckt/csmpFAQ.html).
  9.  
  10. Obsolete questions which have been removed from the FAQ proper
  11. are archived seperately. (http://www.best.com/~ckt/culled.html)
  12.  
  13. Send submissions, questions, suggestions, new links, and corrections
  14. to Chris Thomas (mailto:ckt@best.com), current caretaker of the
  15. FAQ.  All submissions sent will be considered to be in the public
  16. domain unless stated otherwise (in which case they will not be
  17. included in this FAQ sheet).
  18.  
  19. No FAQ can substitute for real documentation (some of which is
  20. mentioned in this FAQ).  If you ask a question in comp.sys.mac.programmer
  21. which has a good answer in one of the important sources, you
  22. will probably not get an answer.  (Inside Macintosh, Macintosh
  23. Technical Notes, and MPTA being important sources).  These sources
  24. are available in  electronic form
  25.   (http://www.info.apple.com/dev/developerservices.html).
  26.  
  27. There is NO or VERY LIMITED error checking in the code examples,
  28. FOR BREVITY ONLY.  You should make sure you ALWAYS check ALL
  29. return codes, and handle any that you are not prepared to deal
  30. with appropriately.
  31.  
  32.  Exciting new stuff: Frameworks update!  HTML->text conversion
  33. process still not entirely wonderful.  Various link fixes.
  34. The usual tweaks.
  35.  
  36.  
  37.  
  38.  Topics:
  39.  [search for *number* to find a topic quickly]
  40.  [topics changed since last edition are marked "+"; new topics
  41. ">"]
  42.  
  43.  
  44.   1. +Development Tools
  45.           getting started, tool-specific issues, frameworks
  46.   2. Memory 
  47.           handles & resources, large arrays
  48.   3. Human Interfacing 
  49.           menus, windows, events, multitasking
  50.   4. Files 
  51.           Mac fopen, wdrefnums, getting full pathnames
  52.   5. Imaging 
  53.           QuickDraw and the means to avoid it
  54.   6. Text 
  55.           Text editing packages, string conversion
  56.   7. Communications and Networking 
  57.           serial ports, TCP/IP, sockets
  58.   8. Interapplication Communication 
  59.           AppleEvents, OSA, Scripting, and You
  60.   9. Dynamic Linking & Code Resources 
  61.           the dynamics of code resources & trap patches  inits
  62.   10. Compatibility 
  63.           gestalt & glue
  64.   11. Optional System Software Technology 
  65.     What else Apple will do for you.
  66.     
  67.     11.1. QuickTime
  68.           codec details and the lack thereof
  69.     11.2. QuickDraw 3D
  70.           happy compilers exist in three dimensions
  71.     11.3. OpenDoc
  72.           recursively searching for OpenDoc
  73.     
  74.   12. Third Party Solutions 
  75.     What Apple won't do for you.
  76.     
  77.     12.1. Databases & ODBC
  78.           client/server solutions
  79.     12.2. Circumventing Toolbox Limitations
  80.           foul baggage begone- List Manager replacements?
  81.     
  82.   13. Dessert 
  83.           yummies the Macintosh way
  84.   14. >Other Answers 
  85.           no faq is an island- other sources for answers
  86.   15. Contributors 
  87.           registered SmartFriends(tm) 
  88.  
  89.  
  90.  
  91. *1* Development Tools
  92.  
  93. 1.1) Q: What do I need to start writing Macintosh software?
  94.  
  95. A: A Mac, a lot of time, and a few hundred $.  Although you can
  96. develop software on a Classic/SE-type machine, it is not to be
  97. attempted by the weak of heart or stressed of time.  If you're
  98. doing paid work and/or work for a company, a Quadra-class machine
  99. is a must; remember that your time costs your employer much more
  100. than just your salary.  A PowerMac is *highly* preferable.  16
  101. MB is a minimum to run at all comfortably (40 MB recommended),
  102. and Virtual Memory (including RamDoubler) is not suited for development
  103. work.  Similarly, if you don't have at least 80 MB free on your
  104. hard disk you need to buy more space.  You will also need a CD-ROM
  105. drive.
  106.  
  107. You need a development system such as CodeWarrior, MPW Pro, Symantec
  108. C++ 8.0 or Prograph, you need at least some of the New Inside
  109. Mac books (Toolbox Essentials, Files, Memory come to mind) and
  110. a good entry-level third-party book may help.
  111.  
  112. Once you are up to speed on the general layout of the Mac and
  113. its toolboxes, you should call APDA and order the monthly developer
  114. mailing, which will give you a CD chock full of documentation,
  115. utilities and system software once a month.  You will also, obviously,
  116. need a CD player.  If you don't have the dough for the monthly
  117. mailing ($250/year) you can order a _develop_ subscription; this
  118. quarterly magazine ($30-$50/year) comes with a CD containing
  119. most Inside Mac documentation.  Another good product to order
  120. is the MacOS SDK, which for $99 gives you a CD with every API
  121. in existence up to and including the 7.5 Mac Toolbox additions.
  122.  It's somewhat redundant if you already have the Developer CD
  123. subscription (mailto:apda@appplelink.apple.com).  Apple's Developer
  124. Web  (http://www.info.apple.com/dev/developerservices.html) has
  125. almost all of the contents of the Developer CD's online.  
  126.  
  127. If you don't know how to program, go learn your language of choice
  128. BEFORE attempting a "real" Mac application.  Programming is a
  129. discipline often requiring different thought processes than your
  130. normal day job.  A beginning book, like Lippman: The C++ Primer,
  131. one of the Teach Yourself (language-of-choice) books, or the
  132. primers available on the CodeWarrior CD, might help.
  133.  
  134. An indispensable Mac programming tool is the Macintosh Programmer's
  135. Toolbox Reference (MPTA), an up-to-date hypertext reference guide
  136. containing reference material on the New Inside Mac-documented
  137. portions of the Toolbox with lightning-fast look-up and mostly
  138. correct usage hints and code snippets.  MPTA can be found on
  139. the Developer CD, and is also offered on a seperate $99 CD. 
  140. Contact APDA (mailto:apda@applelink.apple.com) for further details.
  141.  
  142. 1.2) Q: What is the most used Macintosh development system?
  143.  
  144. A: Currently, the three most widely used are CodeWarrior (CW),
  145. MPW, and Symantec C++, probably in that order, though I don't
  146. have any statistics.  The latest version of any one of these
  147. is adequate for Mac development.
  148.  
  149. CodeWarrior  (http://www.metrowerks.com/) : In early 1994, Metrowerks
  150. CodeWarrior came out of nowhere and grabbed a large share of
  151. the market visibility because they had the fastest compiler and
  152. they generated PowerPC code as well as 68K code from identical
  153. (though seperate) environments.  Today, CodeWarrior has the smoothest
  154. development environment and most complete C++ implementation,
  155. supporting templates, exceptions, and RTTI on all supported platforms.
  156.  CW/7 includes C, C++, and Object Pascal support, and can generate
  157. x86 and CFM-68k binaries, all from a single environment.  A universal
  158. single-machine debugger is included for all Mac runtimes and
  159. a two-machine debugger is included for use with x86.  CW is very
  160. popular because of it's low price, ultra-fast compile time, the
  161. honesty and integrity consistently displayed by Metrowerks employees
  162. (from the president of the company all the way down to the technical
  163. support people), and support that no other company on the planet
  164. has been able to match.   comp.sys.mac.programmer.codewarrior
  165. for more information and CodeWarrior- related praise.   Contact
  166. Metrowerks (mailto:sales@metrowerks.com) for more info.
  167.  
  168. MPW: The grandaddy of all Mac development environments, descended
  169. from the original Mac & Lisa development environment hosted on
  170. the Lisa.  MPW is an extremely flexible, powerful, vaguely Unix-like
  171. command line environment with makefile, multiple windows and
  172. unlimited split-pane support.  Many, if not most, Mac development
  173. tools are MPW-based.  The PowerPC compilers currently optimize
  174. better than either Symantec C++ or Metrowerks.  MPW has in the
  175. past been extremely slow, but shows some signs of redemption.
  176.  MPW Pro comes with C, C++, Pascal, assemblers for both 68k and
  177. PowerPC, various other useful tools, and the C++-based framework
  178. MacApp for a reasonable price.  If you like the development tools
  179. under Unix, you might find MPW pleasant.  While the question
  180. of Apple's commitment to MPW has arisen, it is a fact that the
  181. System Software is still built in MPW, so it can't be abandoned
  182. until at least some point after the release of Copland.  Contact
  183. APDA for more info (mailto:apda@applelink.apple.com).
  184.  
  185.  Symantec  C++ (http://www.symantec.com/lit/dev/macdv/macdv.html):
  186. This is the eighth-generation descendant of the Pascal and C
  187. development environments favored by Mac developers for over five
  188. years.  Symantec C++ 8.0 is a complete, very scriptable, modular
  189. development environment including C, C++, Rez, and soon, a PowerPC
  190. assembler.  The C++ implementation supports templates.  A development
  191. version of a PowerPC C++ compiler supporting exceptions and RTTI
  192. is available at Symantec's devtools site.  SC++ 8.0 doesn't at
  193. this time support 68k Mac development.  For that purpose, you're
  194. required to use the old, decrepit TPM development environment,
  195. which is included.  Symantec has recently fallen out of favor
  196. with Mac developers due to Microsoftian support policies, premature
  197. releases, general apathy in the past, and tendency to favor marketspeak
  198. over technical accuracy.  Contact Symantec for more info.
  199.  (mailto:sales@devtools.symantec.com)
  200.  
  201. Of these three, CodeWarrior is the smoothest overall environment,
  202. with the most attention to detail, MPW is the hardest to use,
  203. (though the compilers provided with it generate the best PPC
  204. code and it's the most flexible), and Symantec C++ tends to be
  205. the most helpful in terms of project browsing features.
  206.  
  207. Motorola (http://www.mot.com/SPS/PowerPC/) has a set of PowerMac
  208. C/C++  Fortran compilers, running under MPW only, which they
  209. claim generate code which is 20% faster than their next fastest
  210. competitor.
  211.  
  212. If you're generating code for 68k Macs, your compiler's codegen
  213. won't be wonderful.  There are no optimizing compilers for 68k
  214. Macintosh.  Think C is slightly behind Metrowerks C in 68k code
  215. quality. 
  216.  
  217. There are also at least two Fortran compilers, at least three
  218. SmallTalk implementations (ObjectWorks, SmallTalk/V and SmallTalkAgents)
  219. and others.  There are ways of stripping SmallTalk apps so they're
  220. smaller and faster as standalone apps than in the environment.
  221.  
  222. Language Systems (http://www.cais.com/langsys/) has Object Pascal
  223. and Fortran for PowerMac.  Absoft has Fortran and C++ for PowerMac.
  224.  These all require MPW.
  225.  
  226. There's also a world-class LISP/CLOS implementation from Apple
  227. called Macintosh Common Lisp.  Recently, Apple announced that DigiTool
  228.  (http://www.digitool.com/) has licensed MCL with the intent
  229. (among other things) to provide a PowerMac version and other
  230. updates.
  231.  
  232. Zedcor has FutureBasic, which seems to be a very popular... 
  233. It also seems to be the only well-supported compiler-based implementation
  234. of BASIC on Macintosh.
  235.  
  236. CSI has MacForth, of which I only know the name and someone who
  237. says it's pretty good.
  238.  
  239. There is another good Common Lisp implementation: Procyon Common
  240. Lisp.  I don't know if it is actively supported, but Procyon
  241. CL is also available for DOS, OS/2 and Windows (as Allegro CL/PC)
  242. and actively developed.
  243.  
  244. A new possible up-and-coming languge  environment is Apple's
  245. Dylan.
  246.  
  247. 1.3) Q: Okay, which is the most used Mac programming languge?
  248.  
  249. A: The existing Macintosh code base is mostly C, with C++ second,
  250. and Pascal finding it's niche in third.  Few people are writing
  251. mainstream software in Pascal anymore, probably because (a) it's
  252. rather hard to move to non-Mac platforms (b) Pascal is only rarely
  253. being taught past the first year in Computer Science.  It's also
  254. been hard in the past to justify something like Borland's Delphi
  255. copyright infringement generator for Windoze.
  256.  
  257. 1.4) Q: Where do I find a free/share/copyleftware C compiler
  258. for the Mac?  Is there a GCC for the mac? What about the FSF
  259. boycott of Apple products?
  260.  
  261. A: There is no really good solution for a "for-free" C development
  262. system for the Mac.  GCC has been ported several times over,
  263. but requires the MPW shell and MPW assembler to run.  There is
  264. a standalone port of GCC 1.37
  265.  (ftp://nic.switch.ch/software/mac/src/think_c) by the same gentleman
  266. who brings you Patmos.
  267.  
  268. A not-entirely-stable port of GCC 2.3.3 
  269.  (ftp://atg.apple.com/pub/MPW_gcc/GCC-2.3.3r12.sea.bin) to MPW
  270. is available for ftp at atg.apple.com.  A much more solid port of
  271. GCC 1.37 is available for MPW as well.
  272.  
  273. Stan Shebs (mailto:shebs@cygnus.com), the driving force behind
  274. all of the GCC -> MPW ports, was working on a new port of GCC
  275. 2.5.8, but seems to have given up.
  276.  
  277. None of these ports is useful for doing real work.
  278.  
  279. For those whose main interest is in developing only text-based
  280. C/C++ programs, using GCC under  MacMiNT
  281.  (ftp://nic.switch.ch/software/mac/src/macmint) might be appropriate.
  282.  MacMiNT is a UNIX like operating system ported from the Atari
  283. ST which supports many freely available UNIX utilities like GCC,
  284. GDB, make, tcsh, byacc, perl, and more.
  285.  
  286. The FSF/LPF boycott of Apple products is over as of January 1995,
  287. which means they will now incorporate changes made for Macintosh
  288. into the GNU (http://web.kaleida.com/u/hopkins/text/festo.html)
  289. main code base, if such changes are easily incorporated, and
  290. they won't be any more antagonistic to Mac programmers than they
  291. would be to any other non- Unix
  292.  (http://web.kaleida.com/u/hopkins/unix-haters.html) programmers.
  293.  
  294. 1.5) Q: Are there any other free Mac development platforms?
  295.  
  296. A: The best source for information on free compilers/interpreters
  297. is the Free Development Tools on the Mac FAQ
  298.  (http://www.europa.com/~sf/fdsm.html) maintained by Brian Conners.
  299.  
  300. 1.7) Q: What good programmer’s text editors exist on the Mac?
  301.  
  302. A:  Several.  You'll have to make up your mind as to which you
  303. prefer, as they differ widely in versatility, power, ease-of-use,
  304. and price.
  305.  
  306. Alpha (http://www.cs.umd.edu/~keleher/alpha.html): This is the
  307. most powerful text editor, based on Dr.  Ousterhout's Tcl scripting
  308. language with several extensions for text editing.  Because Alpha's
  309. menus and all of the basic editing functions are controlled by
  310. Tcl procs, you can customize Alpha to do just about anything.
  311.  Alpha supports editing modes for C, C++, Fortran, Pascal, HTML,
  312. PostScript, SQL, MPW Shell, Unix C shell, Perl, Tcl, (La)TeX
  313. and plain text.  Keyword coloring is optional but the colors
  314. are fixed and rather dull.  A generous library of Tcl routines
  315. is included, as is complete documentation.  Alpha allows user
  316. scripts to build and send arbitrary AppleEvents.  Frequent updates
  317. and support direct from the author.  Limited split pane support.
  318.  Alpha is $30 shareware.
  319.  
  320. BBEdit (mailto:bbsw@netcom.com): This text editor has the slickest
  321. interface (easiest to use) and comes in two flavors, BBEdit Lite
  322. and the full commercial BBEdit.  BBEdit, while only partially
  323. PowerMac native, is fast.  BBEdit Lite is free and contains a
  324. large subset of the full BBEdit's features.  BBEdit is fully
  325. scriptable and supports "soft" text wrapping, which allows one
  326. to have text wrapped automatically with hard returns while typing.
  327.  External code module extensions are supported through a powerful
  328. parameter block interface.  BBEdit contains fast navigation facilities
  329. for Pascal, C, C++, Rez, 68K Assembler, FORTRAN, HTML, CodeWarrior
  330. projects, SPM projects, and online volumes but does not currently
  331. support syntax coloring.  BBEdit supports limited split panes.
  332.  $119 - $79 ($39 for students).
  333.  
  334. 1.8): Q: What kind of cross-platform solutions exist?
  335.  
  336. Microsoft Visual C++ for Macintosh: a Windows NT or Windows 4.0
  337. hosted IDE which allows you to generate Mac applications from
  338. an Intel box.  Microsoft Word was ported to Macintosh using VC++
  339. for version 6.0.  Microsoft employees have claimed publicly that
  340. VC++ 4.0 will generate better code than all current Mac compilers.
  341.  
  342. Altura (http://www.altura.com)'s Mac2Win: Altura's cross-platform
  343. solution, on the other hand, allows you to write a Macintosh
  344. application and then put an API translation layer on the Windows
  345. side.  Very expensive, but a much improved end-result and happier
  346. users.  4D was ported to Windows using Mac2Win.
  347.  
  348. Galaxy, Zapp, et cetra: [...working on this section, text contributions
  349. welcome!...]
  350.  
  351. Doing the right thing on all platforms (providing the user interface
  352. expected by the user, including the use of features specific
  353. to each platform), requires you to use solutions built specifically
  354. for those platforms.  One solution is to isolate platform-neutral
  355. code and use frameworks native to each platform.  An example
  356. of a product built this way is Netscape Navigator.  This assumes
  357. that you value your user's satisfaction above all else, which
  358. is the essence of programming Macintosh.
  359.  
  360. 1.9): Q: Is there an Emacs port?  Vi?  EDT?
  361.  
  362. A: Emacs: Yes.  Marc Paquet has an excellent, mature, stable,
  363. and fat Emacs port.  All the Unix geeks on Macintosh who I know
  364. use it.  If you're looking for a more Maclike Emacs, try Alpha's
  365. Emacs bindings.  (see 1.7).  But Alpha doesn't have M-x doctor.
  366.  
  367. Vi: There's a port called Stevie and a port called vim.  If you
  368. know where to find these, tell me (mailto:ckt@best.com)!  Again,
  369. Alpha has vi key bindings.  But you don't get vi's wonderful
  370. lack of multiple on-screen buffers with Alpha.  
  371.  
  372. EDT: ?  Does anyone care?
  373.  
  374. 1.10) Q: What is a good low-level debugger for the Mac?
  375.  
  376. A: MacsBug is freely available for ftp from ; log in as user
  377. anonymous and give your FULL e-mail address as password.  MacsBug
  378. is your basic monitor-type debugger that takes a few hundred
  379. Ks of memory, and lets you break, step, disassemble, look at
  380. the stack etc of most anything running on your Mac.  Since it's
  381. free (it's also on the developer CDs) and provides most of the
  382. functionality you need, this is a popular choice.  As of 6.5d10,
  383. Macsbug supports PowerPC debugging.
  384.  
  385. Jasik Designs (http://www.jasik.com/) has a debugger called The
  386. Debugger which can do both low- and high-level debugging, with
  387. or without source and for all types of code, application, code
  388. resources, everything.  This is the debugger of choice for many
  389. large developers because of its high power and many features
  390. not found anywhere else.  However; newcomers beware!  This is
  391. the Lamborghini of debuggers; if you know how to drive it, it
  392. is the fastest way from A to B; if you don't, you'll just end
  393. up in the ditch.  The Debugger is PowerMac native and supports
  394. PowerPC disassembly.  It includes an excellent code coverage
  395. tool and MacNosy, a general disassembler.  Support is direct
  396. from the author and generally great.
  397.  
  398. 1.11) Q: Are there any visual developments environments for the
  399. Mac (comparable to Visual C++)?
  400.  
  401. A: There is no Visual C++ as such.  However, there is a C++ parser/editor
  402. called ObjectMaster which provides good browsing and editing
  403. capabilities if you already have a C++ compiler.  A demo is available
  404. on the CodeWarrior CD.  Symantec C++ comes with a browser built-in,
  405. and you can edit dialogs/windows using plain old ResEdit, even
  406. for your custom view types.
  407.  
  408. Symantec C++ >= 7.0 also bundles a view editor/code generator
  409. called Visual Architect; it is fairly complete and has a good
  410. level of integration into the Think Project Manager.
  411.  
  412. AppMaker is a GUI builder/code generator.  Granted, it's not
  413. as nice as VC++, but it's quite a product in any case.
  414.  
  415. MarksMan version 3.0 has totally revised TCL templates, and now
  416. generates well-thought-out TCL code.  It can also generate ANSI
  417. C code etc.
  418.  
  419. Also, Neuron Data has their UI tool called Open Interface, which
  420. is better than VC++ and creates code portable across 35 platforms.
  421.  Unfortunately it's $2500 per developer per platform.  There's
  422. also two other cross-platform products called XVT and Galaxy,
  423. the former has gotten flak on UseNet while the latter reportedly
  424. is the premier cross-platform application builder framework;
  425. with everything from styled text to network support.
  426.  
  427. There is a fully visual, dynamic, object oriented data-flow-driven
  428. programming language for the Mac called Prograph CPX.  It features
  429. a full-featured class library, a powerful, user-extensible GUI
  430. Builder, full access to the entire Mac toolbox, a database engine,
  431. high-level interfaces to SQL, Oracle, etc.  But the coolest thing
  432. about Prograph is its interpretative debugger, fully integrated
  433. with the visual code editor, which lets you write your code _while
  434. it's running_.  Execution automatically rolls back to where changes
  435. you make have relevance.  A PowerMac-native compiler and a Windoze
  436. version are expected in '95.  A complete demo version is available.
  437.   Contact Prograph (mailto:sales@prograph.com) for more information.
  438.  Cost is $695 ($395 for students).
  439.  
  440. SmalltalkAgents comes with a GUI builder, which lets you draw
  441. your interface, and then outputs the code for you.
  442.  
  443. If you'd rather do Common Lisp, Macintosh Common Lisp offers
  444. a Common Lisp Object System with support for most Mac interface
  445. items; you can edit code while it is running and build stand-alone
  446. applications.
  447.  
  448. However, all of these tools generate rather larger binaries with
  449. larger system demands than a program written in C.  On the other
  450. hand, C programs require more memory and disk space than programs
  451. written in assembly.  It's a trade-off, and I believe this type
  452. of tool is the wave of the near future.
  453.  
  454. 1.12) Q: What application frameworks exist for the Mac?
  455.  
  456. A:  In no particular order:
  457.  
  458.  MacApp (http://www.info.apple.com/dev/devinfo/macapp/macapp.html),
  459. Apple's framework, comes in two popular flavors, 2.x and 3.x.
  460.  MacApp 2.x is grounded in Object Pascal, and is not being actively
  461. supported by Apple.  3.x is written in C++, retaining some Object
  462. Pascalisms which are somewhat weird from a C++ point-of-view.
  463.  MacApp is very mature, with much support and many dependent
  464. applications outside of Apple, and is a good choice if you're
  465. not concerned about memory footprint.  MacApp suffers in that
  466. it hasn't kept up with modern features such as threads, AOCE
  467. and the drag manager, resulting from a period of neglect, but
  468. has since been fully restaffed, and is well on the way to modern
  469. MacOS.  MacApp is ideal for the developer looking for a very-low-risk,
  470. well-supported solution.  A number of visual interface editors
  471. are available for MacApp.  MacApp runs on all Mac C++ compilers,
  472. and CodeWarrior, as of CW/6, includes both MacApp 2 and 3.  comp.sys.mac.oop.macapp3
  473. is a newsgroup dedicated to MacApp.
  474.  
  475. The Think Class Library, originally written for Think C with
  476. Objects by the same gentleman who is now the PowerPlant lead
  477. architect, is a healthy, mature framework, with much third-party
  478. documentation and an active user community.  TCL is included
  479. with Symantec C++, which also integrates Visual Architect, a
  480. customizable visual interface builder, into it's IDE.  Other
  481. visual tools are available with TCL support.  TCL, as of 2.0,
  482. is written in true C++. comp.sys.mac.oop.tclis a newsgroup dedicated
  483. to TCL discussion and support.  
  484.  
  485.  PowerPlant (http://www.metrowerks.com/products/newcw7.shtml#powerplant):
  486. Distributed with Metrowerks' CodeWarrior development environment,
  487. PowerPlant is second-newest C++ framework, and takes advantage
  488. of the clean slate this affords it.  PowerPlant is highly modular,
  489. being based on a number of mix-in classes, and contains support
  490. for many modern MacOS features, including the Open Scripting
  491. Architecture, PowerTalk/AOCE, Drag Manager, threads, and others.
  492.  Because of the modern design It's still a work-in-progress,
  493. with many rough edges.  PowerPlant is ideal for the developer
  494. who desires a clean, modern architecture and is willing to put
  495. up with the aforementioned holes.   CodeWarrior ships with PowerPlant
  496. Constructor, a view editor.
  497.  
  498. ODF: The OpenDoc Parts Framework, another Apple framework, is
  499. intended solely for (surprise!) OpenDoc part development.  ODF
  500. recycles chunks of the failed cross-platform Bedrock project.
  501.  Although the other frameworks will probably support OpenDoc
  502. to varying degrees at some point, only ODF is committed to supporting
  503. all of OpenDoc, with cross-platform support encompassing MacOS,
  504. Windows, and probably other platforms in the future.  Both Metrowerks
  505. and Symantec have licensed ODF and will include it in their products
  506. at some point in the future.  Currently, no tools exist for human
  507. interface construction with ODF.
  508.  
  509. Sprocket (http://www.mactech.com/sprocket.html):  Sprocket is
  510. a very simple class library, using MacApp coding style  organization,
  511. but supporting relatively bleeding-edge features such as AOCE
  512. mailer support, threaded AppleEvent futures, threads in general,
  513. Drag Manager support, and multiple floating palette support.
  514.  Sprocket was written by Dave Falkenburg of Apple for an article
  515. in  MacTech, and serves as a testbed for new technologies presented
  516. therein.  Ideal for those looking for a small, easy to understand
  517. class framework with support for some modern MacOS features.
  518.  
  519. TransSkel: A solid C framework, TransSkel is very easy to program,
  520. is well-documented, and lends itself to small-footprint/small-resource-
  521. requirement applications.  An unsupported Pascal version is available.
  522.  
  523. 1.13) Q: How should I debug and test my software?
  524.  
  525. A: Get ahold of, and install, the extensions DoubleTrouble, DisposeResource
  526. and EvenBetterBusError.  They will catch 80% of any memory related
  527. bugs you may have, including many bugs that follow NULL handles
  528. or pointers.  (Jasik's Debugger (see above) obviates the need
  529. for these, as does a control panel called QC (mailto:OnyxTech@aol.com).)
  530.  
  531. A low-level debugger is required, and while you install it, install
  532. the "leaks" dcmd which will help you catch memory leaks in your
  533. application.  Check out Apple's developer site for most of these
  534. tools. (ftp://www.info.apple.com/).
  535.  
  536. 1.14) Q: Are there any good Mac programming magazines?
  537.  
  538. A: One Mac programming magazine I know of is MacTech Magazine
  539.  (mailto:custservice@xplain.com) (formerly MacTutor).  It covers
  540. a variety of Mac programming topics on various levels.  Operating
  541. independently from Apple, it has a lot of stuff for the beginning
  542. Mac programmer, as well as occasional nuggets for the more experienced
  543. of us. 
  544.  
  545. Another excellent magazine is  _develop_
  546.  (mailto:dev.subs@applelink.apple.com) which is put out by Apple
  547. four times a year; it comes with a CD containing all past issues
  548. of _develop_ in electronic form, all source code included with
  549. those issues, and a rotating set of electronic Inside Macintosh
  550. books.  $30/year in the US.
  551.  
  552. MacTech tends to lean toward a general Mac programming  folklore
  553. feel; _develop_ tends to lean towards Apple employees writing
  554. articles which show how to implement the latest cool technology,
  555. with occasional new System Software technical preview.  The Developer
  556. CD includes _develop_ in electronic form, and _develop_ is also
  557. available free from Apple's various online sites.
  558.  
  559. 1.15) Q: What about protected memory? I'm sick and tired of re-booting
  560. when my application crashes.
  561.  
  562. A: Write better software!
  563.  
  564. Or install The Debugger from Jasik Designs, which can provide
  565. your application with write-protection of critical parts of memory,
  566. if you have a 68030-equipped Mac.
  567.  
  568. Making the Mac OS memory-protected is tricky, because applications
  569. expect to be able to write to low memory, the system heap, temporary
  570. memory, window lists, and even each other's heaps in some interapplication
  571. communication solutions that date back to before AppleEvents
  572. and the PPC Toolbox.
  573.  
  574. But fear not, Mac fans!  Jonathan Kimmitt has written   Patmos
  575.  (ftp://nic.switch.ch/software/mac/src/patmos), the "Protected
  576. address translation mode operating system".  It is an application
  577. that brings the advantages of protected mode programs to your
  578. Quadra class Macintosh by the simple expedient of taking over
  579. the memory management unit of the 68040 in a very simple kernel
  580. ( less than 100K in size), we immediately gain compatibility
  581. with the BSD unix program environment.
  582.  
  583. The downside is that not all macs use the memory management unit
  584. in the same way, or even have the same kind of MMU, so Patmos
  585. may not run on your particular mac model.  However, since the
  586. kernel source code is very small, the task of adapting it to
  587. a new environment is very simple, and once achieved, all application
  588. programs running in user mode are enabled to run without even
  589. recompiling.
  590.  
  591. 1.16) Q: What are some good books on the subject of learning
  592. the Mac Toolbox?
  593.  
  594. A: Any of Dan Parks Sydow's numerous books on the subject.  Recommended
  595. also is Dave Mark's _Ultimate Mac Programming_ (a Macworld book,
  596. for some odd reason).  Stay away from Dave Mark's _Learn C on
  597. the Mac_ and _Learn C++ on the Mac_, as these don't teach the
  598. Mac toolbox, and better books exist for learning straight C or
  599. C++.
  600.  
  601. See also Nick DeMello's books review, posted in c.s.m.p.info
  602. from time to time.
  603.  
  604. 1.17) Q:  Where can I find some source code?
  605.  
  606. A: Celestin Company, Inc.  sells the Apprentice CD-ROM
  607.  (ftp://ftp.teleport.com/vendors/cci/apprentice/apprentice.hqx).
  608.  Apprentice contains over 600 megabytes of programmer utilities
  609. and up-to-date source code in CodeWarrior, Symantec, and MPW
  610. projects for C, C++, Pascal, and assembler.
  611.  
  612. Also, the  alt.sources.mac archive
  613.  (ftp://ftp-2.amug.org/pub/demos/alt.sources.mac/) contains a
  614. lot of miscellaneous source code and snippets not found elsewhere.
  615.  
  616. SWITCHinfo (ftp://nic.switch.ch/pub/mac/src) is another good
  617. source for unique source code.
  618.  
  619. Your local info-mac mirror is a good source for source, info-mac/dev/src.
  620.  
  621. 1.18) Q: I keep getting dumped into  Macsbug with a "PowerPC Memory
  622. Access Exception," and I can't get rid of it by typing G or ES.
  623.  
  624. A:  This means one of two things:
  625.  
  626. 1.  Something invalid was passed to the Memory Manager, and will
  627. be ignored. You can just go ahead and type GP (might be necessary
  628. to do this several times.)
  629.  
  630. 2.  A program is really trying to access memory that it can't.
  631.  Type GP;ES and press return.
  632.  
  633. 1.19) Q: ResEdit is useless.  Where can I find a professional
  634. resource editor?
  635.  
  636. Resorcerer (mailto:resorcerer@aol.com), the only professional
  637. Resource Editor for Macintosh, happens to be an excellent replacement
  638. for ResEdit.  Aside from a few interface quirks, the template
  639. facilities put ResEdit to shame, as does the dialog editor, and
  640. just about everything else.  $256 commercial.  Student discounts
  641. are available.
  642.  
  643. There are no PowerPC-native resource editors at the moment.
  644.  
  645. 1.20) Q: What source code/revision control tools are available
  646. for Macintosh.
  647.  
  648. A: Text-based?
  649.  
  650. RCS and SCCS ports: available.  Check info-mac/dev/src for these.
  651.  
  652. MPW Projector: Projector is a simple text-based MPW tool included
  653. with MPW.  Supports experimental branches.  Will be phased out
  654. at some point.
  655.  
  656. SourceServer: a standalone version of Projector using an AppleEvent-based
  657. interface to communicate with clients.
  658.  
  659. SourceSafe: another text-based source code control system.  Microsoft
  660. owns this now, but Metrowerks licensed the right to develop and
  661. sell the Mac version, and announced plans to give it a true graphical
  662. interface.  Expect to hear more around late '95/spring '96.
  663.  
  664. or Graphical?
  665.  
  666. Voodoo (mailto:chrei@unisoft.co.at): Versions Of Outdated Documents
  667. Organized Orthogonally is a system which supports the storage
  668. of both multiple revisions of a single component and different
  669. variants of that component.  Additionally, Voodoo only stores
  670. data which is different in each variant, thereby potentially
  671. saving much disk space.  Users have given Voodoo (and it's shareware
  672. sibling, Voodoo Lite) glowing reviews in c.s.m.p.tools.
  673.  
  674. Source Manager is an easy-to-use graphical front-end to Projector,
  675. SourceServer, and SourceSafe.  A demo of the most recent version
  676. is available at info-mac/dev/.  Source Manager is shareware.
  677.  
  678.  *2* Memory 
  679.  
  680. 2.1) Q: What is a handle?
  681.  
  682. A: A handle is a pointer to a pointer to something.  However,
  683. it is more than that; creating a handle by taking the address
  684. of one of your own pointers does NOT create a Handle; the Memory
  685. Manager will only deal properly with Handles that are created
  686. using NewHandle or something that calls it (such as NewRgn or
  687. GetResource).
  688.  
  689. 2.2) Q: When do I have to lock a Handle?
  690.  
  691. A: The contents of a Handle may move, and when it does, the pointer
  692. your handle is pointing to is changed to point to the new address
  693. so your handle is always valid.  The toolbox may call the memory
  694. manager to allocate more memory pretty much anytime you call
  695. it (the toolbox) and when memory is allocated, your handle may
  696. move in memory.  Don't dereference a handle into a pointer (or
  697. take the address of a field in a record a handle is double-pointing
  698. to) and then call the toolbox and expect the pointer to still
  699. be valid.  The only way to ensure that the pointer will still
  700. be valid is to call HLock on the handle to lock it.
  701.  
  702. Use HGetState and HSetState to save & restore the "locked" state
  703. of a handle when you lock it.
  704.  
  705. 2.3) Q: How do I dispose of Handles?
  706.  
  707. A: DisposeHandle (formerly called DisposHandle) once and ONLY
  708. once will do the trick.  Trying to dispose of an already disposed
  709. Handle is an error.  DoubleTrouble (see above) will catch such
  710. bugs when they do occur.
  711.  
  712. 2.4) Q: What about resources?
  713.  
  714. A: Calling GetResource returns NULL if the resource is not found
  715. or there is not enough memory, else it returns a handle to the
  716. resource.  This handle may be moved or locked like any other
  717. handle, but DO NOT call DisposeHandle to get rid of a resource
  718. handle - call ReleaseResource.  DisposeResource (see above) will
  719. catch this kind of bug.
  720.  
  721. Remember that AddResource makes a resource handle out of an ordinary
  722. handle, and RemoveResource or DetachResource makes an ordinary
  723. handle out of a resource handle.  You cannot call AddResource
  724. with a resource handle; you have to DetachResource it first.
  725.  
  726. Remember also that once a resource has been detached with DetachResource,
  727. it becomes a handle like any other handle, and must be disposed
  728. via DisposeHandle.
  729.  
  730. Resource handles are automagically disposed when the resource
  731. file they belong to is closed.
  732.  
  733.  *3* User / Machine interaction
  734.  
  735. 3.1) Q: How do I read the modifier keys of the keyboard?
  736.  
  737. A: Just call EventAvail and check the event.modifiers field.
  738. Only works when you are in the foreground. You can also use GetKeys(),
  739. or (as a last resort) check the lo-mem global KeyMap directly.
  740.  
  741. 3.2) Q: How do I move the mouse cursor to a specific position?
  742.  
  743. A: Wait! Don't do it! There has to be a better way!
  744.  
  745. If you feel you HAVE to do it (for a game or VERY special simulation
  746. situation) you can use the Cursor Device Manager documented in
  747. the  tech notes .  If that manager is not installed, as it's
  748. not on older Macs, you can use the following code:
  749.  
  750. You need to have some low-memory globals defined.  they may be
  751. defined in SysEqu.h.
  752.  
  753.  
  754.  #define MTemp 0x828
  755.  #define RawMouse 0x82c
  756.  #define CrsrNewCouple 0x8ce 
  757.  
  758. Note that CrsrNewCouple is actually a combination of two globals,
  759. just to make our life slightly easier.
  760.  
  761. The code I use to move the mouse is:
  762.  
  763. void MoveMouseTo ( Point where )
  764.  {
  765.  
  766.     HideCursor ( ) ;
  767.     * ( Point * ) RawMouse = where ;
  768.     * ( Point * ) MTemp = where ;
  769.     * ( short * ) CrsrNewCouple = -1 ;
  770.     ShowCursor ( ) ;
  771.  }
  772.  
  773. You need to hit a couple more global variables if you want this
  774. to work properly in a multiple-monitor system, but i forget what
  775. they are offhand.  poke through SysEqu.h, and you should be able
  776. to figure it out without a problem.
  777.  
  778. On the PowerPC, these lo-mem globals may not be available for
  779. native applications; however, all Power Macintoshes implement
  780. the Cursor Device Manager.  68k Macs implement it beginning with
  781. the Centrises.
  782.  
  783. There is also a file on nada.kth.se:pub/hacks/mac-faq/MoveMouse.c
  784. which shows how to use the Cursor Device Manager, written by
  785. an excellent Apple engineer.  Grab!
  786.  
  787. Careful, version 1.0 of the Universal Header "CursorDevices.h"
  788. file was completely incorrect.  Use 2.0a3 or later.
  789.  
  790. 3.3) Q: My menus don't show up in the menu bar.
  791.  
  792. A: If your menus are hiearchical, you'll have to install them
  793. manually; GetNewMBar won't do it for you.  See also 3.5.
  794.  
  795. 3.4) Q: When the user selects my menus, I get strange results
  796. back; they seem to have different menu IDs than my menus?
  797.  
  798. A: The Menu ID as used by the menu manager is NOT the same thing
  799. as the MENU resource ID (used in the MBAR resource and with GetMenu())
  800. When you create a MENU, ResEdit sets the menu ID to the MENU
  801. resource ID, but if you re-number the resource, you will have
  802. to open the menu in ResEdit and change the menu ID using the
  803. "Edit MENU ID" menu item.
  804.  
  805. 3.5) Q: I use GetMenu() to find a menu in the menu bar, and then
  806. change it, but it seems I have a memory leak OR my changes don't
  807. "punch through"
  808.  
  809. A: GetMenu() is only intended if you don't already have the menu
  810. "in memory." The call you should use almost all the time is GetMHandle()
  811. which gets the handle to a menu in the current menu bar by its
  812. menu ID (not resource id).
  813.  
  814. 3.6) Q: What about pre-emptive multitasking?
  815.  
  816. A: To the user, the Mac multitasking method, which builds upon
  817. each application calling WaitNextEvent, GetNextEvent or EventAvail
  818. every so often and the Process Manager/MultiFinder switching
  819. applications only at such calls, is at least as good as preemptive
  820. multitasking, because the present system priotitizes user interface
  821. responsiveness over everything else.  The only shortfall about
  822. this is formatting floppies which on most 68k Macs locks up the
  823. CPU.  This is because the 68k Mac floppy controller is really
  824. stupid, and would happen even if the 68k Mac multitasked preemptively.
  825.  
  826. There IS "real" pre-emptive multitasking available for use in
  827. Mac applications; the expensive way is buying A/UX 3.0 which
  828. can have Mac applications written as UNIX processes; the cheap
  829. way is installing the Thread Manager which will allow you to
  830. create pre-emptive threads.  However, the restrictions on those
  831. threads are the same as those on Time Manager tasks: don't call
  832. any function in an unloaded segment, and don't call QuickDraw
  833. or any toolbox call which may move memory (which are most ToolBox
  834. calls; paradoxally, BlockMove is safe :-) as are, surprisingly,
  835. FSRead and FSWrite).  The latest word from Apple is that this
  836. preemptive support is going away, to be replaced by preemptive,
  837. memory-protected kernel tasks in Copland.  You should thread
  838. your applications now to prepare for the move to Copland.
  839.  
  840. There are several problems with making the Mac OS preemptive
  841. with memory protection; including apps that draw outside their
  842. windows or directly to screen, user dragging and other issues.
  843.  The system is being entirely reimplemented for 8.0 (Copland)
  844. to help solve these problems in a manner compatible with today's
  845. cooperative apps.  System 9.0 will offer full preemptive multitasking.
  846.  
  847.  *4* Files
  848.  
  849. 4.1) Q: How do I tell fopen() to open a file the user has selected
  850. using StandardGetFile?
  851.  
  852. A: The "standard" ANSI C file functions are less than well suited
  853. for the Macintosh way of doing things.  However, if you are doing
  854. a port for your own enjoyment and benefit (or maybe for in-house
  855. work) you can use the following function: (see below about converting
  856. a wdRefNum into a vRefNum/parID pair)
  857.  
  858. FILE * fopen_mac ( short vRefNum , long parID , char * fileName
  859. , char * mode )
  860.  {
  861.  
  862.     short oldVol ;
  863.     short aVol ;
  864.     long aDir , aProc ;
  865.     FILE * ret = NULL ;
  866.  
  867.     /* save old default directory/volume */
  868.     if ( GetVol ( NULL , & oldVol ) ) {
  869.         return NULL ;
  870.     }
  871.     
  872.     /* from working directory->directory/volume */
  873.     if ( GetWDInfo ( oldVol , & aVol , & aDir , & aProc ) ) {
  874.         return NULL  ;
  875.     }
  876.     
  877.     /* change default directory */
  878.     if ( HSetVol ( NULL , vRefNum , parID ) ) {
  879.         return NULL ;
  880.     }
  881.     
  882.     /*call ANSI fopen*/
  883.     ret = fopen ( fileName , mode ) ;
  884.     if ( HSetVol ( NULL, aVol , aDir ) ) {
  885.         /* an error we can't currently handle */
  886.     }
  887.     
  888.     /* restore old volume/directory */
  889.     if ( SetVol ( NULL, oldVol ) ) {
  890.         /* an error we can't currently handle */
  891.     }
  892.     return ret ;
  893.  }
  894.  
  895. All of the above is necessary for one reason or another - if
  896. you are interested, by all means look HSetVol up in MPTA or New
  897. Inside Mac: Files. 
  898.  
  899. In older versions of MPW, this wouldn't work since the MPW libraries
  900. used to do a GetVol and explicitly use that value by itself.
  901.  
  902. 4.2) Q: When can I use the HOpen, HCreate etc file calls? Are
  903. they only System 7 calls?
  904.  
  905. A: All the HXxx calls that take a vRefNum and parID as well as
  906. the file name are implemented in glue that works on any system
  907. that has HFS (meaning 3.2 and up with the HD20 INIT, and all
  908. systems from System 6 and up)
  909.  
  910. The glue is available in MPW 3.2 and up, and Think C 5.0 and
  911. up.  This goes for all HXxx calls except HOpenDF; therefore,
  912. if you are interested in System 6 compatibility, use HOpen instead
  913. and make sure you don't allow file names beginning with a period.
  914.  
  915. 4.3) Q: Why do you say wdRefNum sometimes and vRefNum sometimes?
  916. Why do you say parID sometimes and dirID sometimes?
  917.  
  918. A: When the Mac first made an appearance in 1984, it identified
  919. files by using a vRefNum (volume reference number meaning a floppy
  920. disk or later hard disk) and a name.  Once HFS saw the light
  921. of day, folders within folders became a reality, and you needed
  922. a dirID as well to point out what folder you really meant on
  923. the volume.  However, older programs that weren't being rewritten
  924. still knew nothing about directory IDs, so Apple had SFGetFile
  925. make up "fake" vRefNums that didn't just specify a volume, but
  926. also a parent folder.  These are called wdRefNums (for working
  927. directory) and were a necessary evil invented in 1985.  You should
  928. not create (or, indeed, use) wdRefNums yourself.
  929.  
  930. There is a system-wide table that maps wdRefNums onto vRefNum/parID
  931. pairs.  There is a limit to the size of this table.  A dirID
  932. and a parID is almost the same thing; you say "parID" when you
  933. mean the folder something is in, while you say a "dirID" when
  934. you mean the folder itself.  If you for instance have a folder
  935. called "Foo" with a folder called "Bar" in it, the parID for
  936. "Bar" would be the dirID for "Foo."
  937.  
  938. 4.4) Q: How do I convert a wdRefNum as returned by SFGetFile
  939. into a vRefNum/parID pair to use with the HXxx calls?
  940.  
  941. A: Use GetWDInfo, which is declared as:
  942.  
  943. Pascal OSErr GetWDInfo ( short wdRefNum, short * vRefNum,
  944.                                  long * parID, OSType * procID
  945. ) ;
  946.  
  947. The procID parameter must be non-NULL and point to an OSType
  948. variable, but the value of that variable can and should be ignored.
  949.  
  950. It is recommended that, as soon as you get your hands on a wdRefNum,
  951. for instance from SFGetFile, you directly convert it into a vRefNum/parID
  952. pair and always use the latter to reference the folder.
  953.  
  954. For maximum compatibility with future systems, you should actually
  955. be using the newer StandardGetFile and StandardPutFile functions
  956. that were introduced with System 7.
  957.  
  958. 4.5) Q: How do I select a folder using SFGetFile?
  959.  
  960. A: This requires a custom dialog with a filter proc.  It is too
  961. complicated to show here, but not totally impossible to comprehend.
  962.  There is sample code on ftp.apple.com, in the directory dts/snippets,
  963. on how to do this.
  964.  
  965. 4.6) Q: How do I get the full path of a file referenced by a
  966. vRefNum, parID and name?
  967.  
  968. A: You don't.
  969.  
  970. OK, I cheated you.  There is exactly ONE valid reason to get
  971. the full path of a file (or folder, for that matter) and that
  972. is to display its location to the user in, say, a settings dialog.
  973.  To actually save the location of the file you should do this:
  974. (assuming the file is in an FSSpec called theFile - you can use
  975. FSSpecs in your program even if you don't run under System 7;
  976. just make your own MyFSMakeFSSpec that fills in the FSSpec manually
  977. if it's not implemented)
  978.  
  979.  
  980.  if ( ! aliasManagerAvailable ) { /* System 6 ? */
  981.      GetVolumeName ( theFile -> vRefNum , vName ) ;
  982.      GetVolumeModDate ( vRefNum , & date ) ;
  983.      Save ( vName , date , parID , fileName ) ;
  984.  } else {
  985.      NewAlias ( NULL , theFile , & theAlias ) ;
  986.      Save ( theAlias ) ;
  987.      DisposeHandle ( ( Handle ) theAlias ) ;
  988.  } 
  989.  
  990. If you are really concerned about these issues (of course you
  991. are!) you should save BOTH of these methods when available, and
  992. load back whatever is there that you can handle; since users
  993. may be using your application in a mixed System 6/System 7 environment.
  994.  
  995. To get back to the file is left as an exercise for the reader.
  996.  
  997. To open a file using fopen() or the Pascal equivalent, see above
  998. about using and not using HSetVol.
  999.  
  1000. 4.7) Q: What about actually getting the full path for a file?
  1001. I promise I will only use it to show the location of a file to
  1002. the user!
  1003.  
  1004. A: The easiest way to do this is to grab Jim Luther's excellent
  1005. and complete MoreFiles (1.3 or later), which does all this work
  1006. for you (see 4.15).
  1007.  
  1008. Enter PBGetCatInfo, the Vegimatic of the Mac file system.  Any
  1009. Mac hacker of knowledge has taken this system call to his heart.
  1010.  Note that this sample code isn't all there, but should point
  1011. you in the right direction:
  1012.  
  1013.  Boolean IsFolder(FSSpec *fs) // this function is called later
  1014.  {
  1015.     CInfoPBRec rec;
  1016.  
  1017.     rec.hFileInfo.ioNamePtr    = fs ->    name;
  1018.     rec.hFileInfo.ioVRefNum    = fs ->    vRefNum;
  1019.     rec.hFileInfo.ioDirID =    fs -> parID;
  1020.  
  1021.     if ( !fs ->    name [ 0 ] )
  1022.     {
  1023.         rec    . hFileInfo    . ioFDirIndex =    0 ;
  1024.     }
  1025.     else
  1026.     {
  1027.         rec    . hFileInfo    . ioFDirIndex =    -1 ;
  1028.     }
  1029.  
  1030.     rec    . hFileInfo    . ioFVersNum = 0 ;
  1031.     PBGetCatInfoSync (&rec);
  1032.  
  1033.     return(!rec.hFileInfo.ioFlAttrib & 0x10);
  1034.  }
  1035.  
  1036. OSErr GetFolderParent(FSSpec *fss, FSSpec *parent)
  1037.  {
  1038.     CInfoPBRec rec;
  1039.     short err;
  1040.  
  1041.     *parent = *fss;
  1042.     rec.hFileInfo.ioNamePtr = parent -> name ;
  1043.     rec.hFileInfo.ioVRefNum = parent -> vRefNum ;
  1044.     rec.hFileInfo.ioDirID = parent -> parID ;
  1045.  
  1046.     if ( !parent -> name [ 0 ] )
  1047.     {
  1048.         rec . hFileInfo . ioFDirIndex = 0 ;
  1049.     }
  1050.     else
  1051.     {
  1052.         rec . hFileInfo . ioFDirIndex = -1 ;
  1053.     }
  1054.  
  1055.     rec . hFileInfo . ioFVersNum = 0 ;
  1056.     err = PBGetCatInfoSync ( & rec ) ;
  1057.  
  1058.     if ( ! ( rec . hFileInfo . ioFlAttrib & 0x10 ) ) { /* Not
  1059. a folder */
  1060.         if ( ! err ) {
  1061.             err = dirNFErr ;
  1062.         }
  1063.     } else {
  1064.         parent -> parID = rec . dirInfo . ioDrParID ;
  1065.         BlockMove(rec.dirInfo.ioNamePtr, parent->name, rec.dirInfo.ioNamePtr[0]);
  1066.     }
  1067.     return err ;
  1068.  }
  1069.  
  1070. OSErr GetFullPathHandle ( FSSpec * fss , Handle * h )
  1071.  {
  1072.     Handle  tempH = NULL;
  1073.     FSSpec fs = * fss ;
  1074.     FSSpec sSpec;
  1075.  
  1076.     if(*h == NULL) // allocate a handle if needed
  1077.     {
  1078.         *h = NewHandle(0);
  1079.     }
  1080.  
  1081.     while ( fs . parID > 1 )
  1082.     {
  1083.         tempH = NULL ;
  1084.         PtrToHand ( & fs . name [ 1 ] , & tempH , fs . name [ 0
  1085. ] ) ;
  1086.         PtrAndHand ( ( void * ) ":" , tempH , 1 ) ;
  1087.         HandAndHand ( * h , tempH ) ;
  1088.         SetHandleSize ( * h , 0L ) ;
  1089.         HandAndHand ( tempH , * h ) ;
  1090.         DisposeHandle ( tempH ) ;
  1091.  
  1092.         tempH = NULL ;
  1093.         GetFolderParent ( & fs , & sSpec ) ;
  1094.         fs = sSpec ;
  1095.     }
  1096.     
  1097.     // fs should now contain info about the volume itself
  1098.     PtrToHand ( & fs . name [ 1 ] , & tempH , fs . name [ 0 ] )
  1099. ;
  1100.     PtrAndHand ( ( void * ) ":" , tempH , 1 ) ;
  1101.     HandAndHand ( * h , tempH ) ;
  1102.     SetHandleSize ( * h , 0L ) ;
  1103.     HandAndHand ( tempH , * h ) ;
  1104.     DisposeHandle ( tempH ) ;
  1105.     tempH = NULL ;
  1106.  
  1107.     if (!IsFolder ( fss ) )
  1108.     {
  1109.         SetHandleSize ( * h , GetHandleSize ( * h ) - 1 ) ;
  1110.     }
  1111.  
  1112.     DisposeHandle(tempH);
  1113.     return 0 ;
  1114.  } 
  1115.  
  1116. 4.8) Q: So how do I get the names of the files in a directory?
  1117.  
  1118. A: You use PBGetCatInfo again, but this time you set ioFDirIndex
  1119. to 1 or more (you need to know the dirID and vRefNum of the folder
  1120. you're interested in) You then call PBGetCatInfoSync for values
  1121. of ioFDirIndex from 1 and up, until you get an fnfErr.  Any other
  1122. err means you are not allowed to get info about THAT item, but
  1123. you may be for the next.  Then collect the names in the string
  1124. you made ioNamePtr point to as you go along.  Note that you need
  1125. to fill in the ioDirID field for each iteration through the loop,
  1126. and preferably clear the ioFVersNum as well.
  1127.  
  1128. Note that the contents of a directory may very well change while
  1129. you are iterating over it; this is most likely on a shared folder.
  1130.  
  1131. 4.9) Q: How do I find the name of a folder for which I only know
  1132. the dirID and vRefNum?
  1133.  
  1134. A: You call (surprise!) PBGetCatInfo! Make ioNamePtr point to
  1135. an empty string (but NOT NULL) of length 63 (like, an Str63)
  1136. and ioFDirIndex negative (-1 is a given winner) - this makes
  1137. PBGetCatInfo return information about the vRefNum/dirID folder
  1138. instead of the file/folder specified by vRefNum, parID and name.
  1139.  
  1140. 4.10) Q: How do I make the Finder see a new file that I created?
  1141. Or if I changed the type of it; how do I display a new icon for
  1142. it?
  1143.  
  1144. A: In pre-7.5 Finders, you call (surprise!) PBGetCatInfo followed
  1145. by PBSetCatInfo for the FOLDER the file is in.  Inbetween, you
  1146. should set ioDrMdDat to the current date&time.  Code:
  1147.  
  1148. OSErr TouchFolder ( short vRefNum , long parID )
  1149.  {
  1150.  
  1151.  CInfoPBRec rec ;
  1152.  Str63 name ;
  1153.  short err ;
  1154.  
  1155.     rec . hFileInfo . ioNamePtr = name ;
  1156.     name [ 0 ] = 0 ;
  1157.     rec . hFileInfo . ioVRefNum = vRefNum ;
  1158.     rec . hFileInfo . ioDirID = parID ;
  1159.     rec . hFileInfo . ioFDirIndex = -1 ;
  1160.     rec . hFileInfo . ioFVersNum = 0 ;
  1161.     err = PBGetCatInfoSync ( & rec ) ;
  1162.     if ( err ) {
  1163.         return err ;
  1164.     }
  1165.     GetDateTime ( & rec . dirInfo . ioDrMdDat ) ;
  1166.     rec . hFileInfo . ioVRefNum = vRefNum ;
  1167.     rec . hFileInfo . ioDirID = parID ;
  1168.     rec . hFileInfo . ioFDirIndex = -1 ;
  1169.     rec . hFileInfo . ioFVersNum = 0 ;
  1170.     rec . hFileInfo . ioNamePtr [ 0 ] = 0 ;
  1171.     err = PBSetCatInfoSync ( & rec ) ;
  1172.     return err ;
  1173.  }
  1174.  
  1175. 4.11) Q: Aren't we done with PBGetCatInfo soon?
  1176.  
  1177. A: Well, it turns out that you can also find out whether an FSSpec
  1178. is a file or a folder by calling PBGetCatInfo and check bit 4
  1179. (0x10) of ioFlAttr to see whether it is a folder.  You may prefer
  1180. to call ResolveAliasFile for this instead.
  1181.  
  1182. You can also check the script of the file's title using PBGetCatInfo
  1183. and check the ioFlFndrXInfo field if you want to work with other
  1184. script systems than the Roman system.
  1185.  
  1186. Another common use is to find out how many items are in a folder;
  1187. the modification date of something or the correct capitalization
  1188. of its name (since the Mac file system is case independent BUT
  1189. preserves the case the user uses)
  1190.  
  1191. 4.12) Q: How do I set what folder should initially be shown in
  1192. the SFGetFile boxes?
  1193.  
  1194. A: You stuff the dirID you want to show into the lo-mem global
  1195. CurDirStore, and the NEGATIVE of the vRefNum you want into the
  1196. lo-mem global SFSaveDisk.
  1197.  
  1198. If you are using CustomGetFile and return sfSelectionChanged
  1199. from an "init" message handler, you must remember to clear the
  1200. script code, else the selection will not change.
  1201.  
  1202. 4.13) Q: How do I find the folder my application started from?
  1203. How do I find the application file that's running?
  1204.  
  1205. A: Under System 7, you call GetProcessInformation using the ProcessSerialNumber
  1206. kCurrentProcess with a pointer to an existing FSSpec in the parameter
  1207. block.  This will give you your file, and, by using the vRefNum
  1208. and parID, the folder the application is in.
  1209.  
  1210. OSErr   CurrentProcessLocation(FSSpec *applicationSpec)
  1211.  {
  1212.     ProcessSerialNumber currentPSN;
  1213.     ProcessInfoRec info;
  1214.     
  1215.     currentPSN.highLongOfPSN = 0;
  1216.     currentPSN.lowLongOfPSN = kCurrentProcess;
  1217.     info.processInfoLength = sizeof(ProcessInfoRec);
  1218.     info.processName = NULL;
  1219.     info.processAppSpec = applicationSpec;
  1220.     return ( GetProcessInformation(¤tPSN, &info) );
  1221.  }
  1222.  
  1223. If you want to create a folder or file in your application's
  1224. directory, call FSMakeFSSpec(0, 0, "\pNameOfFolderOrFile" &theSpec).
  1225.  
  1226. Don't write to your applications resource or data forks; the
  1227. former breaks on CDs/write protected floppies/file servers/virus
  1228. checkers, the latter fails on PowerPC as well as in the above
  1229. cases.
  1230.  
  1231. 4.14) Q: When can I use those nifty, easy to use FSSpec calls?
  1232.  
  1233. A: In Systems >= 7, in System 6 with QuickTime installed (with
  1234. limitations), in any system if you use the FSpCompat functions
  1235. provided by MoreFiles [see below].
  1236.  
  1237. 4.15) Q: This low-level file manager stuff is giving me a headache;
  1238. why didn't Apple provide a complete high-level interface using
  1239. FSSpecs?
  1240.  
  1241. A: Good question.  Apple, in the guise of Jim Luther of Mac Developer
  1242. Technical Support, has written a library called MoreFiles
  1243.  (ftp://ftp.info.apple.com/Apple.Support.Area/Developer_Services/Sample_Code/MoreFiles_1.3.1),
  1244. which not only provides a high-level interface to low-level file
  1245. stuff, but provides FSSpec glue for Systems below 7.  MoreFiles
  1246. is available on the Developer CD's (see 1.7) and also at Appple's
  1247. developer web site.  MoreFiles is complete and well-written.
  1248.  Grab!
  1249.  
  1250.  *5* Imaging with QuickDraw
  1251.  
  1252. 5.1) Q: Why is CopyBits so slow?
  1253.  
  1254. A: It is not.  It just requires some hand-holding to get good
  1255. results.  The main rules are: Make sure the source and destination
  1256. pixMaps are of the same depth.
  1257.  
  1258. Make sure the front color is black and the back color is white.
  1259.  
  1260. Use srcCopy and don't use a masking region, unless it's rectangular.
  1261.  
  1262. Copy to an unclipped window (the frontmost window).  Make sure
  1263. the ctSeed values of the source pixMap and dest pixMap match.
  1264.  
  1265. Copying few and large pixMaps is faster than copying many and
  1266. small ones.  Icon-sized sprites count as small ones.
  1267.  
  1268. Make sure your source bitmap or pixelMap has the same alignment,
  1269. when adjusted for the source and destination rect expressed in
  1270. global screen coordinates.  The necessary alignment is 32 bits
  1271. (4 bytes), although 128 bit (16 byte) alignment is probably even
  1272. better on 68040 macs and won't hurt on other macs.
  1273.  
  1274. Example of global alignment:
  1275.  
  1276. Your window is positioned at (42,100) (H,V)
  1277.  
  1278. Your destination rectangle is (10,20)-(74,52)
  1279.  
  1280. The alignment coefficient of the rectangle in global coordinates
  1281. is (42+10)*bitDepth where bitDepth is one of 1,2,4,8,16 or 32.
  1282.  
  1283. Make sure your source pixmap rect has the same coeffecient modulo
  1284. your alignment factor (in bits) For black&white macs, this is
  1285. still true, although bitDepth is fix at 1.  Offscreen pixMaps
  1286. can calculate with a "global posistion" of 0,0 and get correct
  1287. results.
  1288.  
  1289. 5.2) Q: Why is CopyBits still too slow?
  1290.  
  1291. A: Because there is always some overhead involved in calling
  1292. QuickDraw; you have the trap dispatcher, clipping checks, and
  1293. checking whether the CopyBits call is being recorded in a PICT
  1294. handle (if you called OpenPicture)
  1295.  
  1296. If you can't live with this, look at 4.8 below, but PLEASE try
  1297. and make CopyBits work, and retain the CopyBits code in your
  1298. application, so users with special monitors (accellerator cards,
  1299. PowerBook color screens, Radius Pivot screens) can still play
  1300. your game.  (non-game applications don't need more speed than
  1301. CopyBits can give at its max.  Promise!)
  1302.  
  1303. 5.3) Q: What is the fastest way to set one pixel?
  1304.  
  1305. A: NOT SetCPixel()!  Assuming you have the correct ForeColor()
  1306. set, you can set the pen size to (1,0) and call Line (0,1)
  1307.  
  1308. I have heard PaintRect is good for this but requires slightly
  1309. more code.  Using PaintRect eliminates a trap call.
  1310.  
  1311. 5.4) Q: Why do pictures I record suddenly draw as empty space
  1312. or not draw at all?
  1313.  
  1314. A: When recording pictures, you have to set the clipping area
  1315. to exactly the frame of the picture you are recording.  This
  1316. is because it is initally set at -32768,32727 in both directions,
  1317. and offsetting the picture even one pixel when drawing it will
  1318. result in the region wrapping around and becoming empty.
  1319.  
  1320. When recording pictures, do this:
  1321.  
  1322.  PicHandle h = OpenPicture ( & theRect ) ;
  1323.  ClipRect ( & theRect ) ;
  1324.     /* draw the picture */
  1325.  ClosePicture ( ) ;
  1326.  
  1327. 5.5) Q: Where can I find the format of picture files and resources?
  1328.  
  1329. The format of a picture resource version 2 is defined in Inside
  1330. Mac: Imaging with QuickDraw.
  1331.  
  1332. The format of a picture file is the same as that of a picture
  1333. resource with 512 added 0 bytes in front.
  1334.  
  1335. 5.6) Q: GWorlds?
  1336.  
  1337. A: What about them?  They're great.  Look them up in IM: Imaging
  1338. With QuickDraw.  Don't forget to SetGWorld back to what it was
  1339. and unlock the pixmap before calling WaitNextEvent.
  1340.  
  1341. 5.7) Q: How do I find the current depth of the screen?
  1342.  
  1343. A: My question to you is: What screen? Many macs have more than
  1344. one screen attached.  You can use GetDeviceList and walk the
  1345. devices to find the screen you're looking for (use TestDeviceAttribute
  1346. to see whether it's a screen) or you can call GetMaxDevice()
  1347. to find the deepest device your window intersects.
  1348.  
  1349. Once you have the device handle, finding the depth is just a
  1350. matter of looking at the gdPMap pixMapHandle, and dereference
  1351. it to the pmSize field. Done.
  1352.  
  1353. 5.8) Q: Why is it a bad idea to draw directly to screen?
  1354.  
  1355. A: Because of several reasons:
  1356.  
  1357.   You will be incompatible with future display hardware. 
  1358.  
  1359.  You will be incompatible with some present-day display hardware,
  1360. such as Radius Pivots and PowerBook color screens. 
  1361.  
  1362.  You have to think about a lot of things; testing it all on your
  1363. own machine is not possible and the chances of crashing are great.
  1364.  
  1365.  
  1366.  You will be incompatible with future hardware where devices
  1367. may live in some unaccessible I/O space.  
  1368.  
  1369. 5.9) Q: But I really need to do it.  I can't make my animation
  1370. into a QuickTime movie, and CopyBits is too slow, even when syncing
  1371. to the screen retrace and with my source GWorld aligned properly.
  1372.  
  1373. A: You have to prepare yourself, and ask these questions:
  1374.  
  1375.   Do I want to support all screens, or just 8-bit devices?
  1376.  
  1377.  Do I have a few weeks of free time to make it work?
  1378.  
  1379.  Do I want to get nasty mail when I break on some hardware and
  1380.  
  1381.    have to rev the application - even if I may not be able to
  1382. get 
  1383.    ahold of the hardware that makes it break? 
  1384.  
  1385. If all you're doing is rendering an image pixel-by-pixel or line-by-line,
  1386. maybe you can draw directly into an offscreen pixMap/GWorld and
  1387. then CopyBits the entire GWorld to screen. That will be more compatible,
  1388. especially if you use the keepLocal flag when creating the GWorld.
  1389.  
  1390. 5.10) Q: Okay, so how do I get the base address of the screen?
  1391.  
  1392. A: "The" screen? Which screen? There may be several. The base
  1393. address may be on an accellerated screen card. There may be more
  1394. than one screen covering the same desktop area.
  1395.  
  1396. Due to unfortunate circumstances, there is a bug in GetPixBaseAddr()
  1397. that causes it to return incorrect results for early versions
  1398. of System 7. Instead, get the baseAddr directly from the gdPMap
  1399. handle of the GDHandle for the screen you draw to. This address
  1400. may need switching to 32bit mode to be valid.
  1401.  
  1402. 5.11) Q: Quit stalling and give me code!
  1403.  
  1404. A: Okay, but I'll let you sweat over Inside Mac to figure out
  1405. what it does. All of it is important; believe me! To make this
  1406. code run faster, a lot of the things it does can be done once
  1407. before starting to draw.
  1408.  
  1409. Make sure that you have a window that covers the area where you
  1410. are drawing, so other windows will not be overdrawn. Also make
  1411. sure that you do not do direct-to-screen-drawing while you are
  1412. in the background.
  1413.  
  1414. /* This is presently untested code */
  1415.  /* Value is dependent on what depth the screen has */
  1416.  /* This code doesn't work on non-color-quickdraw Macs */
  1417.  /* "where" is in GLOBAL coordinates */
  1418.  
  1419. void SetPixel ( Point where , unsigned long value )
  1420.  {
  1421.     Rect r ;
  1422.     GDHandle theGD ;
  1423.     char * ptr ;
  1424.     long rowBytes ;
  1425.     short bitsPerPixel ;
  1426.     PixMapHandle pmh ;
  1427.     Boolean oldMode ;
  1428.  
  1429.     r . left = where . h ;
  1430.     r . top = where . v ;
  1431.     r . right = r . left + 1 ;
  1432.     r . bottom = r . top + 1 ;
  1433.     theGD = GetMaxDevice ( & r ) ;
  1434.     if ( theGD ) {
  1435.         where . v -= ( * theGD ) -> gdRect . left ;
  1436.         where . h -= ( * theGD ) -> gdRect . top ;
  1437.         pmh = ( * theGD ) -> gdPMap ;
  1438.         rowBytes = ( ( * pmh ) -> rowBytes ) & 0x3fff ;
  1439.         ptr = ( char * ) ( * pmh ) -> baseAddr ;
  1440.         bitsPerPixel = ( * pmh ) -> pixelSize ;
  1441.         oldMode = true32b ;
  1442.         ptr += where . v * rowBytes ;
  1443.         SwapMMUMode ( & oldMode ) ;
  1444.         switch ( bitsPerPixel ) {
  1445.         case 1 :
  1446.             if ( value & 1 ) { 
  1447.                 ptr [ where . h >> 3 ] |= ( 128 >> ( where .
  1448. h & 7 ) ) ;
  1449.             } else {
  1450.                 ptr [ where . h >> 3 ] &= ~( 128 >> ( where .
  1451. h & 7 ) ) ;
  1452.             }
  1453.             break ;
  1454.         case 2 :
  1455.             ptr [ where.h >> 2 ] &= ( 192 >> 2 * ( where.h & 3 )
  1456. ) ;
  1457.             ptr [ where.h >> 2 ] |= ( value & 3 ) << 2 * ( 3 - ( where.h
  1458. & 3 ) ) ;
  1459.             break ;
  1460.         case 4 :
  1461.             ptr [ where.h >> 1 ] &= ( where . h & 1 ) ? 0xf : 0xf0
  1462. ;
  1463.             ptr [ where.h >> 1 ] |= ( value & 15 ) << 4 * ( 1 - (
  1464. where.h & 1 ) ) ;
  1465.             break ;
  1466.         case 8 :
  1467.             ptr [ where.h ] = value ;
  1468.             break ;
  1469.         case 16 :
  1470.             ( ( unsigned short * ) ptr ) [ where . h ] = value
  1471. ;
  1472.             break ;
  1473.         case 32 :
  1474.             ( ( unsigned long * ) ptr ) [ where . h ] = value
  1475. ;
  1476.             break ;
  1477.         default :
  1478.             abort ( ) ; /* Should never get here */
  1479.         }
  1480.         SwapMMUMode ( & oldMode ) ;
  1481.     }
  1482.  } 
  1483.  
  1484. 5.12) Q: What (sprite) animation libraries are available for
  1485. Macintosh?
  1486.  
  1487. A: Several.  All of these are object-oriented, and most are game-oriented,
  1488. though they might be used for other purposes.  Using one of these
  1489. for about-box animations, as one of the authors suggests, is
  1490. akin to using MacApp to write Hello, World.  For more thorough
  1491. uses, any one of these should be great.  If you have anything
  1492. to add, don't hesitate to contact the editor.
  1493.  
  1494. SAT: Written in Pascal and available as PowerPC and 68k binary
  1495. libraries, SAT is what you want if you're looking for simplicity
  1496. and ease-of-programming.  SAT is freeware (or shareware?) and
  1497. the source is available if you can justify your reason for having
  1498. it.  Multiple sample games are included.  At least four released
  1499. games use SAT.
  1500.  
  1501. SpriteWorld: Written in C, SpriteWorld is probably the best known
  1502. of all the sprite libraries.  While programming a game using
  1503. SpriteWorld is more complex compared to doing it with SAT, full
  1504. C source is included.  Multiple sample games are included.  Excellent
  1505. for self-learning.  Freeware, I believe.
  1506.  
  1507. ACL: The Animation Class Library is written in C++.  ACL is commercial,
  1508. and a demo is available online.  ACL is extremely flexible and
  1509. strongly grounded in object-oriented design using C++.
  1510.  
  1511. 3DGM: The only 3D animation library available for Macintosh of
  1512. which I'm aware, 3DGM is distributed by the same people distributing
  1513. ACL.  Several demos are available online.  Commercial. 
  1514.  
  1515. [feel free to send in more]
  1516.  
  1517.  *6* Text
  1518.  6.1) Q: How do I get TextEdit to display more than 32k of text?
  1519.  A: You don't.  Truly, it's not worth it.  There's a call-for-call
  1520. TextEdit replacement called TE32k which does > 32k text, and
  1521. is available from any recent Info-Mac mirror.  It doesn't do
  1522. styled text, though.
  1523.  
  1524. 6.2) Q: How do I get TextEdit to display more than 32k of __styled__
  1525. text *and* embedded objects in the text (such as pictures)?
  1526.  WASTE (http://cirrus.sprl.umich.edu/waste), now at release 1.1,
  1527. is a vast improvement over TextEdit.  It does >32k styled text,
  1528. retains compatibility with the TextEdit style scrap (which is
  1529. used to store styled text in files such as SimpleText's, as well
  1530. as in the clipboard), embedded objects within the text, such
  1531. as pictures, intelligent cut-and- paste, built-in Drag Manager
  1532. support, built-in Undo support, includes source code and is freeware.
  1533.  Really worth the download
  1534.  (ftp://ghost.dsi.unimi.it/pub2/papers/piovanel/).
  1535.  
  1536.  
  1537. "But," you nervously stutter, "WASTE is in Pascal!  What now?"
  1538.  
  1539. Dan Crevier is maintaining a  C port of WASTE
  1540.  (ftp://rhino.harvard.edu/pub/dan/).
  1541.  
  1542. 6.3) Q: I'm too backwards to use WASTE 1.1.  How do I include
  1543. pictures in text using TextEdit?
  1544.  
  1545. A: There's no really easy way (such as a TEAddPict() call), and
  1546. it will be a nasty kludge if you do get it working, but if you
  1547. can live with that, here's how to do it.  I do recommend that
  1548. you take a look at Q 6.2, above.
  1549.  Write an algorithm to get the position of a special marker character
  1550. [Teach/SimpleText uses option-space] or text attribute that the
  1551. user will insert wherever he wants a picture.  Pass this position
  1552. to a function similar to the one below.
  1553.  
  1554.  /*
  1555.     TEDrawPicture
  1556.     Draw a picture within TextEdit's text.
  1557.     
  1558.     input:
  1559.         pos - the position of the special character in the text
  1560. where the 
  1561.               user wants a picture.
  1562.         r   - size of picture
  1563.     
  1564.     output:
  1565.         r   - frame in which picture was drawn */
  1566.  
  1567. void TEDrawPicture(short pos,PicHandle pic,Rect &r,TEHandle theTE)
  1568.  {
  1569.     Point   bottomLeft;  //I think TT/ST uses topleft
  1570.     
  1571.     bottomLeft = TEGetPoint(pos, theTE);
  1572.     
  1573.     r.right = bottomLeft.h + (r.right - r.left);
  1574.     r.top = bottomLeft.v - (r.bottom - r.top);
  1575.     r.left = bottomLeft.h;
  1576.     r.bottom = bottomLeft.v;
  1577.     
  1578.     DrawPicture(pic, &r);
  1579.  } 
  1580.  
  1581. I'll leave selection and clipboard as an exercise for the reader.
  1582.  
  1583. Thereotically, it should be possible to kludge up TextEdit to
  1584. the point where it would treat pictures as if they were actually
  1585. letters (rather big letters, but letters just the same).  That's
  1586. what the width and word break hooks are for, after all.  However,
  1587. this would be a lot of Work, and I've never seen it done.  One
  1588. is lead to believe that it's less work to create an improved
  1589. version of TextEdit from the ground up with picture support.
  1590.  WASTE 1.1, in fact, does this rather nicely.
  1591.  
  1592. 6.4) Q: I have all this money, and I want to get rid of it. How
  1593. do I edit more than 32k of styled text now?
  1594.  
  1595. A: There are at least three solutions.
  1596.  
  1597. 1) The Galaxy application framework (mailto:galaxy@visix.com)
  1598. comes with a styled text editting engine which does more than
  1599. 32k of text.  It also happens to support cross-platform application
  1600. development.  Pricing starts at $10000.
  1601.  
  1602. 2) DataPak is selling a cross-platform library called "PAIGE".
  1603.  It is written to be customizable to any extent, and you can
  1604. do _anything_ in it (want quicktime movies that play and flow
  1605. with the text while editting? Three pages of code; you can adapt
  1606. their picture sample code.) Available for Mac, Windows & Never
  1607. Trusted and Power Mac.  Pricing at $5000 ($25000 for source code)
  1608. - it might be cheaper if you talk to them.  Customer support
  1609. is reputed to be "lousy".
  1610.  
  1611. 3) Or you could use WASTE 1.1 with it's embedded objects implementation
  1612. (want quicktime movies that play and flow with the text while
  1613. editing? One page of code, if that much.)
  1614.  
  1615. 6.5) Q: How do I convert from a string to a floating point type?
  1616.  
  1617. A: Once you've got an Str255, you want to call the routine StringToExtended
  1618. to change the number into type extended80, which is the 80-bit
  1619. floating point type.  The nice thing about StringToExtended is
  1620. that it even works in funky foreign language scripts like Chinese.
  1621.  To use the routine, you must pass it not only the Str255 that
  1622. you want converted, but also the results of the StringToFormatRec
  1623. routine and the GetIntlResourceTable routine.  The documentation
  1624. is generally difficult, so I'll describe the parameters and give
  1625. you a code example below.  Here's what you pass to StringToExtended:
  1626.  
  1627. - source: Obviously the string representation of the number.
  1628.  
  1629. - myFormatRec: This is simply the format that you expect the number
  1630. to be.  For example, if you wanted a positive integer with up
  1631. to 3 decimal places, you would want the format to be "###". 
  1632. (The "#" symbol means a non-zero filled digit, whereas a "0"
  1633. would mean zero filled.) If you wanted an floating point exponential
  1634. notation with up to 2 digit integer portion, exactly 2 digit
  1635. decimal portion, and exactly 1 digit after the "E", your format
  1636. would be "##.00E+0".  (Actually, in Canada, you folks might use
  1637. a "," instead of a "." for the decimal point; if you do, then
  1638. you would put the locally correct symbol in there.) In a format
  1639. string, you can put the format for a positive value, a negative
  1640. value, and 0 seperated by semicolons (e.g.  "##.00E+0;-##.00E+0;0.00E+0").
  1641.  
  1642. But myFormatRec is not the format string itself, but is an internal
  1643. format that you get from calling StringToFormatRec.  This is
  1644. so you can store the format returned to you by StringToFormatRec
  1645. and use it on different international systems.  There is a nice
  1646. editor for ResEdit for 'FMAT' resources that lets you type the
  1647. format string and will call StringToFormatRec for you and create
  1648. an 'FMAT' resource out of the result.  Then you can load the
  1649. 'FMAT' at run time and pass it to myFormatRec.
  1650.  
  1651. - partsTable: The number parts table from the 'itl4' resource.
  1652.  If you are using System 7 or later, you call GetIntlResourceTable,
  1653. asking it for the number parts table.  You don't need to worry
  1654. about HLock'ing itlHandle because StringToExtended doesn't move
  1655. memory; just don't do anything between your call to GetIntlResourceTable
  1656. and the StringToFormatRec routine.  If you are using System 6,
  1657. you need to perform the GetIntlResourceTable by hand.  It's a
  1658. few lines of code; left as an exercise to the reader.
  1659.  
  1660. - x: The extended number to put the thing into.
  1661.  
  1662. So, let's say you expect the user to enter a string containing
  1663. up to 5 digits in the integer with a thousand marker between
  1664. the 3rd and fourth digit, exactly two digits after the decimal,
  1665. put it in parenthesis if it's negative, and have it just be "0.00"
  1666. if it's 0.  (I will use "." for the decimal and "," for the thousand
  1667. marker.  Here's the C code (passing in the source string):
  1668.  
  1669.  Handle itlHandle;               /* The 'itl4' resource handle
  1670. */
  1671.  long offset, length;            /* Offset-length of parts table
  1672. */
  1673.  NumFormatStringRec myFormatRec; /* Canonical format record */
  1674.  extended80 x;                   /* The number to put it into
  1675. */
  1676.  
  1677.  GetIntlResourceTable (smCurrentScript, smNumberPartsTable,
  1678.                       &itlHandle, &offset, &length);
  1679.  StringToFormatRec ("/p##,###.00;(##,###.00);0.00",
  1680.                    (NumberParts *)(*itlHandle + offset),
  1681.                    &myFormatRec);
  1682.  StringToExtended (source, &myFormatRec,
  1683.                   (NumberParts *)(*itlHandle + offset),
  1684.                   &x);
  1685.  
  1686. If you saved a format record in a resource using the 'FMAT' editor
  1687. (which is really the preferred way to do it), you would change
  1688. the code to look like this:
  1689.  
  1690.  
  1691.  Handle itlHandle;                 /* The 'itl4' resource handle
  1692. */
  1693.  long offset, length;              /* Offset-length of parts
  1694. table */
  1695.  NumFormatStringRec **myFormatRec; /* Canonical format resource
  1696. */
  1697.  extended80 x;                     /* The number to put it into
  1698. */
  1699.  
  1700.  myFormatRec = (NumFormatStringRec **)GetResource('FMAT', MY_FMAT);
  1701.  GetIntlResourceTable (smCurrentScript, smNumberPartsTable,
  1702.                       &itlHandle, &offset, &length);
  1703.  StringToExtended (source, *myFormatRec,
  1704.                   (NumberParts *)(*itlHandle + offset),
  1705.                   &x); 
  1706.  
  1707. The StringToExtended routines will return a result that will
  1708. tell you if there are any parsing errors.  Error checking is
  1709. also left as an exercise to the reader.
  1710.  
  1711. Of course, the reverse of the process (using ExtendedToString)
  1712. works very much the same way, passing the same sorts of parameters.
  1713.  
  1714. *7* Communications and Networking
  1715.  
  1716. 7.1) Q: How do I get at the serial ports?
  1717.  
  1718. A: You call OpenDriver for the names "/p.AOut" and "/p.AIn" to
  1719. get at the modem port, and "/p.BOut" and "/p.BIn" for the printer
  1720. port.  The function RAMSDOpen was designed for the original Mac
  1721. with 128 kB of memory and 64 kB of ROM, and has been extinct
  1722. for several years.
  1723.  
  1724. However, many users use their serial ports for MIDI, LocalTalk,
  1725. graphic tablets, or what have you and have installed an additional
  1726. serial port card to get more ports.  What you SHOULD do as a
  1727. good application is to use the Comm Toolbox Resource Manager
  1728. to search for serial resources; this requires that the Comms
  1729. Toolbox is present (true on earlier System 6 with an INIT, on
  1730. later System 6 and System 7 always, as well as on A/UX) and that
  1731. you have initialized the comms resource manager.  The exact code
  1732. follows (adapted from Inside Mac Comms Toolbox):
  1733.  
  1734.  
  1735.  #include "CommResources.h"
  1736.  OSErr
  1737.  FindPorts ( Handle * portOutNames, Handle * portInNames, Handle
  1738. * names,
  1739.              Handle * iconHandles )
  1740.  {
  1741.  
  1742.     OSErr ret = noErr ;
  1743.     short old = 0 ;
  1744.     CRMRec theCRMRec , * found ;
  1745.     CRMSerialRecord * serial ;
  1746.  
  1747.     * portOutNames = NewHandle ( 0L ) ;
  1748.     * portInNames = NewHandle ( 0L ) ;
  1749.     * names = NewHandle ( 0L ) ;
  1750.     * iconHandles = NewHandle ( 0L ) ;
  1751.     while ( ! ret ) {
  1752.         theCRMRec . crmDeviceType = crmSerialDevice ;
  1753.         theCRMRec . crmDeviceID = old ;
  1754.         found = ( CRMRec * ) CRMSearch ( ( QElementPtr ) & theCRMRec
  1755. ) ;
  1756.         if ( found ) {
  1757.             serial = ( CRMSerialRecord * ) found -> crmAttributes
  1758. ;
  1759.             old = found -> crmDeviceID ;
  1760.             PtrAndHand ( & serial -> outputDriverName , * portOutNames
  1761. ,
  1762.                 sizeof ( serial -> outputDriverName ) ) ;
  1763.             PtrAndHand ( & serial -> inputDriverName , * portInNames
  1764. ,
  1765.                 sizeof ( serial -> inputDriverName ) ) ;
  1766.             PtrAndHand ( & serial -> name , * names , 
  1767.                 sizeof ( serial -> name ) ) ;
  1768.             PtrAndHand ( & serial -> deviceIcon , * iconHandles
  1769. ,
  1770.                 sizeof ( serial -> deviceIcon ) ) ;
  1771.         } else {
  1772.             break ;
  1773.         }
  1774.     }
  1775.     return err ;
  1776.  } 
  1777.  
  1778. This will create four handles with the driver names, device names
  1779. and driver icon handles for all of the available serial devices.
  1780.  Then let the user choose with a pop-up menu or scrolling list,
  1781. and save the choice in your settings file.
  1782.  
  1783. You can use OpenDriver, SetReset, SetHShake, SetSetBuf, SerGetBuf
  1784. and the other Serial Manager functions on these drivers.  To
  1785. write to the serial port, use FSWrite for synchronous writes
  1786. that wait until all is written, or PBWrite asynchronously for
  1787. queuing up data that is supposed to go out but you don't want
  1788. to wait for it.  At least once each time through your event loop,
  1789. you should call SerGetBuf on the in driver reference number you
  1790. got from OpenDriver, and call FSRead for that many bytes - neither
  1791. more nor less.
  1792.  
  1793. If you are REALLY interested in doing the right thing, you will
  1794. use the Communications Toolbox Connection Manager instead; this
  1795. will give you access to modems, direct lines, and networks of
  1796. various kinds using the same API! Great for stuff like BBSes
  1797. that may be on a network as well etc.  The Comms Toolbox also
  1798. provides modularized terminal emulation and file transfer tools,
  1799. although the Apple-suplied VT102 tool is pretty lame, as is the
  1800. VT102 mode of the VT320 tool. OTOH, the Comm Toolbox is being
  1801. abandoned by Apple, to be replaced by Open Transport.  (see below)
  1802.  
  1803. 7.2) Q: Where is a Berkley sockets library for the Mac?
  1804.  
  1805. A: There are some problems with that.  MacTCP, the Mac Toolbox
  1806. implementation of TCP/IP, doesn't have an API that looks at all
  1807. like Berkley sockets.  For instance, there is ONE paramater-block
  1808. call to do a combined listen()/accept()/bind() - sort of.  I
  1809. have heard that there may be a socket library available by ftp
  1810. from MIT but haven't seen it myself.
  1811.  
  1812. There is also a pretty good C++ TCP implementation called GUSI
  1813. which is easily handled, and it also is callable from C using
  1814. the Berkley socket API.  Apart from TCP, it also handles "standard"
  1815. Mac network protocols such as ADSP.  The big disadvantage is
  1816. that it is currently only implemented for MPW.  The ftp site
  1817. is nic.switch.ch, software/mac/src/mpw_c.
  1818.  
  1819. Don't forget to check out Apple's Open Transport architecture.
  1820.  Preliminary docs are available for ftp at seeding.apple.com.
  1821.  Open Transport will eventually replace MacTCP.
  1822.  
  1823. Novell and Wollogong offer commercial socket-like libraries.
  1824.  
  1825. 7.3) Q: Where do I find MacTCP?
  1826.  
  1827. A: You can buy the MacTCP developers kit from APDA.  It is also
  1828. available on E T O, and if you want saner headers than those,
  1829. try ftp to seeding.apple.com.  MacTCP is included with System
  1830. 7.5 and above.
  1831.  
  1832. 7.4) Q: I'm trying to write to the serial port.  It works fine
  1833. on the following Machines, Quadra700, IIFX, Powerbook 170, Quadra
  1834. 840av, but freezes on the Duo 230 and 280c.
  1835.  
  1836. A: You need to call SerHShake.  Otherwise you get screwed on
  1837. some machines without a hardware handshaking cable because the
  1838. port default to hardware handshaking.
  1839.  
  1840. *8* IAC
  1841.  
  1842. 8.1) Q: What are AppleEvents?
  1843.  
  1844. A: AppleEvents are a level-5 network protocol.  If you are not
  1845. familiar with the ISO network stack, this means it's a way of
  1846. structuring sessions between network entities (programs) that
  1847. is not dependent on the underlying protocol (such as PPC or TCP/IP)
  1848. Despite being a network protocol, they can be very useful on
  1849. Macs that are not on a network.  In short, they provide applications
  1850. with a comprehensive way to send arbitrary structured data to
  1851. other applications (or themselves) which receive the events through
  1852. their main event loop.
  1853.  
  1854. The AppleEvent Object Model is a way of looking at applications
  1855. and the data they contain, and also a level-6 network protocol.
  1856.  You _can_ send AppleEvent Object Model data through AppleEvents
  1857. (and the standard AppleEvents defined in the AppleEvent Registry
  1858. use it) but you don't have to - unless you want to talk with
  1859. other applications, of course, then the AEOM is a lingua franca.
  1860.  
  1861. 8.2) Q: What are the four required AppleEvents?
  1862.  
  1863. A: There are four events your application really must implement
  1864. if you want to sell it: the kCoreEventClass class, kAEOpenApplication,
  1865. kAEQuitApplication, kAEOpenDocuments and kAEPrintDocuments events
  1866. IDs.  When you support these events (or any AppleEvents) you
  1867. will not get startup info through GetAppParams() anymore, unless
  1868. you run under System 6 of course.  The kAEOpenApplication event
  1869. will be sent to you when the user double-clicks your app and
  1870. it's not started yet.  When receiving it, you can put up a new
  1871. untitled window.
  1872.  
  1873. kAEOpenDocuments is sent when the user double-clicks your apps
  1874. documents.  Note that if the first AppleEvent you receive is
  1875. a kAEOpenDocuments event, the user started your app by double-clicking
  1876. its documents.
  1877.  
  1878. kAEPrintDocuments is sent when the user selects your documents
  1879. and chooses "Print" in the Finder menu.  If this is the first
  1880. AppleEvent you receive, you should print the documents and then
  1881. quit the application again; if you received a kAEOpenApplication
  1882. or kAEOpenDocuments event before this, you should just print
  1883. the documents and close them when you're done.
  1884.  
  1885. kAEQuitApplication is sent to you when the user chooses "Shutdown"
  1886. or "Restart" from the Apple Menu.  You should ask the user whether
  1887. he wants to save any unsaved changed documents, and then quit
  1888. unless the user presses Cancel.
  1889.  
  1890. Interestingly enough, you can use these four AppleEvents to send
  1891. even to non-AE-aware applications, and the system will translate
  1892. these events into fake menu selections for you.
  1893.  
  1894. A good way of shutting down the Finder is to send it a Quit AppleEvent.
  1895.  You should send a Quit AppleEvent to File Sharing Extension
  1896. before you shut down the Finder, though; the FSE is found by
  1897. looking for a process with the creator 'hhgg'.
  1898.  
  1899. 8.3) Q: Are there any limits or tradeoffs with AppleEvents?
  1900.  
  1901. A: As always, more power means more responsibility. 
  1902.  
  1903. AppleEvents sent to applications on other Macs require authentification
  1904. the first time they are sent.  If the remote Mac allows Guests
  1905. to link to programs, the INIT AutoGuest 2.0 might help (or the
  1906. code solution that comes with it and you can build into your
  1907. application)
  1908.  
  1909. In the first version of the AppleEvent manager, there was a total
  1910. 64K limit on the size of data and overhead.  This limit has been
  1911. lifted with the version of the AppleEvent manager that comes
  1912. with AppleScript.
  1913.  
  1914. AppleEvents require a lot of memory copying and handle resizing
  1915. in their construction; this means that large AppleEvents may
  1916. be slow in construction, especially when compared to a pure PPC
  1917. Toolbox or ADSP/ASDSP link.  The way around this is to use Jens
  1918. Alfke's AEGizmos, available on the Developer CD, to create AppleEvents.
  1919.  AEGizmos are being integrated into System Software, so You Will
  1920. be doing the right thing.
  1921.  
  1922. You should use your own application signature as event class
  1923. for AppleEvents you make up, in order not to collide with anybody
  1924. else.  Other than that, you are free to make your own events
  1925. for your own needs, though supporting the required events and
  1926. at least a subset of the Core event suite will buy you a lot
  1927. of functinality from within AppleScript.  Especially important
  1928. are the Get Current Selection and Set Current Selection events
  1929. (which are really Get/Set Data on the contents of the current
  1930. selection of the application)
  1931.  
  1932. The signature for your application SHOULD be registered with DTS
  1933.  (mailto:devsupport@applelink.apple.com) to avoid conflicts;
  1934. this is done through e-mail and the form you use is located on
  1935. the developer CDs and found on ftp.apple.com.
  1936.  
  1937. 8.4) Q: How do AppleEvents interface with the Open Scripting
  1938. Architecture (AppleScript)?
  1939.  
  1940. A: AppleEvents are the meat and potatoes of OSA.  If you support
  1941. the AppleEvent Object Model from within your application, users
  1942. can control you through an OSA-derived language, such as AppleScript.
  1943.  
  1944. The first thing you should do is get ahold of Inside Mac: Interapplication
  1945. Communication, and a copy of the AppleEvents Registry.  The former
  1946. tells you all you ever need to know about AppleEvents, while
  1947. the latter is paramount for implementing the right standard events.
  1948.  If everybody use the standard events, dynamic data interchange
  1949. between any applications will become sweet reality!
  1950.  
  1951. Then there is the 'aete' resource which lets you put names on
  1952. the events you support, so that users can "Open Terminology"
  1953. on your application from within the Apple Script Editor and use
  1954. the proper AppleScript commands in their scripts.  The format
  1955. of an aete resource is defined in Inside Macintosh: Interapplication
  1956. Communication.
  1957.  
  1958. 8.5) Q: Can I compile and run scripts from within my application?
  1959.  
  1960. A: Yes, this is very simple.  There are toolbox calls for reading
  1961. scripts, compiling scripts, and executing scripts.  (OSACompile,
  1962. OSAExecute) These are all documented in Inside Mac: Interapplication
  1963. Communication.
  1964.  
  1965. 8.6) Q: Is this a good way of getting a macro language almost
  1966. for free?
  1967.  
  1968. A: "Good" is an understatement.  Just let users write scripts,
  1969. load them into menu items and go.  Total systems integration
  1970. in under a week, including adding support for the AEOM to your
  1971. application.
  1972.  
  1973. There is source code for an application called "MenuScripter"
  1974. on the developer CD which shows you how to do an application
  1975. with all of the menus being AppleScript scripts.
  1976.  
  1977. 8.7) Q: Why do I get error -903 (noPortErr) when I try to send
  1978. an Apple Event?
  1979.  
  1980. A: Make sure the isHighLevelEventAware flag in your application's
  1981. SIZE resource is set.  The AE Manager won't allow you to send
  1982. events if you're not able to receive them.
  1983.  
  1984. 8.8) Q: Didn't I hear that ApplEvents are slow?
  1985.  
  1986. A: Yes and no.  Yes, they are slower than necessary in current
  1987. systems.  No, they don't inherently have to be slow, and this
  1988. performance is being improved in Copland.  But you can realize
  1989. some Coplandish improvements right now by taking advantage of
  1990. Jens Alfke's AEGizmos library, which is being rolled into Copland
  1991. as one of the major speed improvements.  CodeWarrior users have
  1992. this library in a folder in the PowerPlant folder.
  1993.  
  1994.  *9* Standalone Code & Trap Patching
  1995.  
  1996. 9.1) Q: How do I do code resources/extensions/external functions,
  1997. much like HyperCard XCMDs only for my app/extension?
  1998.  
  1999. A:  The complete design process:
  2000.  
  2001. Define a storage location for the plug-ins.  For an application
  2002. called Foo, use a folder called "Foo PlugIns / Modules / Tools
  2003. / Etc", which your application checks for the existence of at
  2004. startup, creating anew if necessary.  The name of this plug-in
  2005. folder should be in a 'STR#' resource for easy localization.
  2006.  HyperCard actually forced you to embed XCMDs and XFCNs inside
  2007. user documents, but this led to duplicate XCMDs everywhere.
  2008.  
  2009. Decide whether or not you're going to require the Code Fragment
  2010. Manager.  If you do, you sacrifice backward compatibility with
  2011. most 68k Macs, but you will gain numerous programming advantages:
  2012.  
  2013.  You can call any exported function in a code fragment directly. You
  2014. can take advantage of File Mapping on PowerMacs to reduce memory
  2015. footprints. (Under System 7.x, this requires that the fragment
  2016. be located in the data fork.) You can use SOM to implement C++-based
  2017. interfaces.  
  2018.  
  2019. If you decide to support 68k Macs, define a resource type to
  2020. hold your 68k plug-in exectuable code.  To avoid runtime resource
  2021. loading issues, you should avoid using 'CODE'.  This still applies
  2022. under the 68k Code Fragment Manager, although you can store the
  2023. code in the data fork under that architecture.
  2024.  
  2025. If you decide to support PowerPC code in seperate resources,
  2026. repeat the above step.
  2027.  
  2028. If you decide to use fat resources, ie have resources with both
  2029. 68k and PPC code, all of the below discussion on 68k resources
  2030. applies.  If you want your code resource under PowerPC CFM to
  2031. have a single entry point, most of the 68k discussion still applies.
  2032.  If you want to take full advantage of the CFM, you don't need
  2033. to bother with selectors, dispatching, and the rest.  See Inside
  2034. Mac: PowerPC System Software.
  2035.  
  2036. Decide whether you will allow multiple code resources per file.
  2037.  For example, Photoshop lets you bundle an import resource, an
  2038. export resource, and a filter into the same file, each is its
  2039. own resource type.  It uses the resource name to tell the user,
  2040. so each has its own name.  Be aware that you can have multiple
  2041. CodeFragments in a single data fork, but MPW is required at present.
  2042.  
  2043. Decide on the user interface to plug-ins.  Typically, this is
  2044. answered best by asking "What will these plug-ins be used for?"
  2045. Commonly, at program start-up, you scan the PlugIns folder and
  2046. collect all the files of the correct types.  Photoshop inserts
  2047. the names of certain types of plug-ins into appropriate menus.
  2048.  Other types of Photoshop plug-ins do work "behind the scenes."
  2049.  
  2050. Under Copland, you will be able to register notification requests
  2051. which enable the file system to send messages to your application
  2052. when a user moves files from/to specific folders, thus allowing
  2053. the implementation of dynamic module addition/deletion.  You
  2054. should take this into account now in order that you need not
  2055. worry about it when it happens.
  2056.  
  2057. Use a Pascal-based calling convention to ensure maximum compatibility
  2058. with all Mac compilers, something like:
  2059.  
  2060. pascal OSErr MyCodeModule(ParamsBlock *inParams, Boolean doSomething);
  2061.  
  2062. ParamsBlock is typically something like:
  2063.  
  2064.  
  2065.  typedef struct
  2066.  {
  2067.     long        outVersion; // * version of interface used by
  2068. plug-in
  2069.     long        inVersion;  // * version of interface used by
  2070. program
  2071.     long        inSelector; // * what to do with the data
  2072.     Handle      inData;     // * here's the data, do what you
  2073. will with it
  2074.     long        refCon;     // * program ignores this; for internal
  2075. plug-in use
  2076.  }ParamsBlock, *ParamsBlockPtr; 
  2077.  
  2078. outVersion is filled in by the plug-in on the init selector with
  2079. the minimum version of the program that the plug-in can be used
  2080. with.  inVersion is the current version of the program, inSelector
  2081. is a value which is used to differentiate operations.  An "init"
  2082. selector is a good idea, as is a Dispose selector, and have Init
  2083. return an error or a refcon, which will be passed back to the
  2084. plug-in on each call, so the plug-in can have some persistent
  2085. storage.  You should definately set the CurResFile to the plug-in's
  2086. file while it is running, so it can easily get at any resources
  2087. it needs.
  2088.  
  2089. The actual call to the plug-in under 68k looks like:
  2090.  
  2091.  
  2092.     h = GetResource('PLUG', 1);
  2093.     HLock(h);
  2094.     xh = StripAddress(h);
  2095.     ((PlugInFunc) *xh)(kInit, callbacks, kInterfaceVer1, kProgVer1,
  2096. 0, 0);
  2097.     HUnlock(h); 
  2098.  
  2099. The StripAddress is important if you want to work on Macs running
  2100. under the 24-bit ROMs; if your app is running in 24bit mode,
  2101. the resource handle may contain tag bits and you don't want strange
  2102. things to happen if the code resource switches into 32bit mode
  2103. (which QuickDraw may do, incidentally).  Note that most post-1993
  2104. Macs always run in 32-bit mode, so this is becoming less of a
  2105. problem.
  2106.  
  2107. This won't work properly under PowerPC unless the code resource
  2108. is really just raw PowerPC machine code, with no surrounding
  2109. code fragment stuff.  See Inside Mac:PowerPC System Software
  2110. for information on the proper use of Code Fragments.
  2111.  
  2112. 9.2) Q: How do I fat-patch a trap (that is, how do I patch a
  2113. trap with both 68k and PPC code)?
  2114.  
  2115. A: Create a normal fat routine descriptor and pass it to SetToolTrapAddress()
  2116. or SetOSTrapAddress in place of the normal procedure pointer.
  2117.  
  2118.  *10* Compatibility
  2119.  
  2120. 10.1) Q: I see all these people call Gestalt without first checking
  2121. whether it's implemented.  Isn't that bad?
  2122.  
  2123. A: No; Gestalt and a few other traps (the HXxx file manager traps,
  2124. and FindFolder) are implemented using glue so they do the right
  2125. thing even if the trap is not implemented.
  2126.  
  2127. If you want to get rid of the glue, you can #define SystemSevenOrLater
  2128. (and remember to recompile precompiled headers!) However, then
  2129. you will be responsible for checking for these features before
  2130. you use them.
  2131.  
  2132. 10.2) Q: What more functions are implemented in glue?
  2133.  
  2134. A: Wake Up and Smell the Glue!
  2135.  
  2136. How often have you wished you could use that cool new ToolBox
  2137. call, but didn't want to make your application System 7 dependent?
  2138. Well, it might be that you *could* in fact have used the call.
  2139. Several traps are implemented in glue, that is, much of their
  2140. functionality is linked into your application and thus available
  2141. even if you are running under an old System.
  2142.  
  2143.  FSOpen: Tries first OpenDF, then Open. 
  2144.  
  2145. HOpenResFile: Full functionality emulated if trap not available
  2146.  
  2147.  
  2148. HCreateResFile: Full functionality emulated if trap not available
  2149.  
  2150.  
  2151. FindFolder: Under System 6, understands the following values
  2152. for folderType and returns the System Folder for all of them:
  2153.  
  2154.  
  2155. kAppleMenuFolderType 
  2156.  
  2157. kControlPanelFolderType 
  2158.  
  2159. kExtensionFolderType 
  2160.  
  2161. kPreferencesFolderType 
  2162.  
  2163. kPrintMonitorDocsFolderType 
  2164.  
  2165. kStartupFolderType 
  2166.  
  2167. kSystemFolderType 
  2168.  
  2169. kTemporaryFolderType 
  2170.  
  2171. SysEnvirons: Full functionality emulated if trap not available
  2172.  
  2173.  
  2174. NewGestalt: Returns an error if not implemented 
  2175.  
  2176. ReplaceGestalt: Returns an error if not implemented 
  2177.  
  2178. Gestalt: The following selectors are always implemented: 
  2179.  
  2180. vers    mach    sysv    proc    fpu     
  2181.  
  2182. qd      kbd     atlk    ram     lram    
  2183.  
  2184. 10.3) Q: I have to support System 6, don't I?
  2185.  
  2186. A: It would be foolish to lock yourself out of the many benefits
  2187. the System 7 API provides for software that you start to write
  2188. now.  Some of the System 6 and older things (likely SFGetFile
  2189. and wdRefNums among others) will be phased out of the interfaces
  2190. and lose support; especially on future platforms.  Note: the
  2191. major System Software release after Copland (System 8) is the
  2192. one where this stuff is very likely to break.  This gives you
  2193. until ca. 1997 to remove old stuff, but you'll want to do it
  2194. sooner to realize full performance advantages under Copland.
  2195.  
  2196. The installed base of System 7 is larger than that of System
  2197. 6; this is not surprising because Apple has been shipping System
  2198. 7 for several years with all new machines, including everything
  2199. from the Classic II on up.  Another argument is that newer computer
  2200. owners (having System 7) are much more likely to buy new software
  2201. than old computer owners who have systems that already do what
  2202. they want them to.
  2203.  
  2204. The added work to support both System 6 and System 7 is significant;
  2205. if you have the time and money you may want to do it, but only
  2206. supporting System 6 and not System 7 is doomed to fail in the
  2207. market of today.
  2208.  
  2209. Some may call this position subjective; I call it business sense
  2210. based on market demographics.  A rule of thumb may be that if
  2211. you target color machines only, you can just as well demand System
  2212. 7 as well.
  2213.  
  2214. Another thing to be aware of is that Copland will introduce new,
  2215. more robust APIs for almost everything, including the Window
  2216. Manager, Menu Manager, Resource Manager, and File Manager.  At
  2217. some point, if you still want to support System 6, you'll find
  2218. yourself support three different Systems, with all the application
  2219. bloat that one might expect.
  2220.  
  2221. Note also that Apple no longer sells System 6.0.8, the very last
  2222. version of System 6.
  2223.  
  2224. 10.4) Q: Why does my application work on an SE with accellerator
  2225. (or a Mac II or Quadra), but not on one without?
  2226.  
  2227. A: Assuming you're not calling Color QuickDraw (which is not
  2228. available on accellerated SEs), you most probably have an odd-aligned
  2229. word access somewhere.
  2230.  
  2231. The 68000 does not allow words or longwords to be read from odd
  2232. addresses, while the 68020 and up relaxes this restriction (it
  2233. still is slower than aligned-word access though)
  2234.  
  2235. This may or may not crash depending on your compiler:
  2236.  
  2237.  
  2238.  struct foo {
  2239.     char c1 ;
  2240.     char c2 ;
  2241.     char c3 ;
  2242.     char c4 ;
  2243.     char c5 ;
  2244.  } bar ;
  2245.  
  2246.     long * x = ( long * ) & bar . c2 ;
  2247.     * x = 0x12345678 ; /* X is odd if compiler doesn't pad */ 
  2248.  
  2249. This WILL crash on an SE/Plus/Classic/PB100:
  2250.  
  2251.  
  2252.  char foo [ 10 ] ;
  2253.  
  2254.     long * x = ( long * ) & foo [ 1 ] ;
  2255.     * x = 0x12345678 ; 
  2256.  
  2257. 10.5) Q: Why does my application work on a IIci and on early
  2258. PowerMacs but not on a Quadra?
  2259.  
  2260. A: Two reasons:
  2261.  
  2262. 1) The Quadras 900 and 950 have special processors that handle
  2263. the serial ports; if you write directly to the serial chips,
  2264. you will crash (this goes for the IIfx as well)
  2265.  
  2266. 2) The Quadras have 68040 processors, as have the Centrises.
  2267.  These processors have separate instruction and data caches (like
  2268. the 68030) but they are larger (4K each) and unlike the 68030
  2269. which is write-through data cached, the 68040 is copy-back data
  2270. cached.  This means that changes you make to "your code" aren't
  2271. really changed all the time, since the changes may still be in
  2272. the data cache and not written to memory when the CPU reads that
  2273. part of memory into its I-cache.  Even worse; that part might
  2274. already have been read into the I-cache before you change it
  2275. in the D-cache, meaning that writing out the D-cache will still
  2276. not be enough.  You need to flush both the caches when writing
  2277. self-modifying code.
  2278.  
  2279. Self-modifying code includes code that builds its own jump tables
  2280. and code that decrypts itself and code that "stubs" MDEFs or
  2281. WDEFs to jump back into the application code.
  2282.  
  2283. You flush the cache using FlushDataCache() which is implemented
  2284. if Gestalt says you have a 68020 or better processor (or if the
  2285. _HwDispatch trap is implemented)
  2286.  
  2287. The PowerMac 68k emulator used in all PowerMacs prior to the
  2288. 9500 doesn't have the self-modifying cache problem (thereby being
  2289. more compatible with old software than a Quadra!), but the dynamic
  2290. recompiling emulator in the 9500 and beyond have the same restrictions
  2291. as the 040's.
  2292.  
  2293. 10.6) Q: Why does my application work on my Quadra but not on
  2294. my accellerated SE?
  2295.  
  2296. A: You're probably calling Color QuickDraw without first checking
  2297. if it's available.  The following machines do not have color
  2298. QuickDraw in ROM nor RAM:
  2299.  
  2300. Mac Plus, Mac SE, Mac Classic, Mac Luggable, PowerBook 100, Outbound
  2301.  
  2302. 10.7) Q: I do check for color quickdraw, but crash nevertheless.
  2303.  
  2304. A: _Gestalt lies under some versions of System 7; it says that
  2305. non-color machines HAVE color QuickDraw when you test using the
  2306. gestaltQuickdrawFeatures selector.
  2307.  
  2308. Instead, check the gestaltQuickdrawVersion selector, if it returns
  2309. >= gestalt8BitQuickdraw then you can safely use gestaltQuickdrawFeatures,
  2310. else you only have b/w QuickDraw.
  2311.  
  2312. 10.8) Q: What can I do now to prepare my code for Copland (System
  2313. 8.0) (and beyond)?
  2314.  
  2315. A: Just the stuff Apple's been telling us for years: Support
  2316. OpenTransport.  Thread your applications using the Thread Manager.
  2317.  Be fully 32-bit clean (of course).  Don't patch traps.  If you
  2318. do patch traps, be aware that you will need to rewrite that code.
  2319.  Don’t use the Window Manager low-mem globals.  Don't manipulate
  2320. the GrayRgn.  Use Sound Manager 3.  Don't manipulate hardware
  2321. directly.  Rewrite extensions and control panels so that the
  2322. code that actually provides the functionality is seperated from
  2323. the code that installs or activates it.  Rewrite DAs as applications.
  2324.  Almost everything in Copland is new or rewritten.  Learn about
  2325. the Collection Manager, first introduced with QuickDraw GX and
  2326. documented in the QDGX Inside Mac books.  The Collection Manager
  2327. is used throughout the Copland Toolbox to provide robust, flexible,
  2328. and standard dynamic array services, and seems to be the one
  2329. API untouched by change in Copland.
  2330.  
  2331. While you _might_ be able to get away with using MacTCP, Comm
  2332. Toolbox, trap patching, low-mem global manipulation, and other
  2333. nasty stuff in Copland, the performance of your app will be lacking,
  2334. and it *will break* on system versions beyond  Copland
  2335.  (http://www.info.apple.com/dev/geeks.html).
  2336.  
  2337. You will not be able to get away with 32-bit dirtyness in Copland,
  2338. and at least some of the hardware will be protected.  Desk Accessories,
  2339. Control Panels, and Extensions as we know them won't run under
  2340. Copland.
  2341.  
  2342.  *11* Optional System Software
  2343.  
  2344. *11.1* QuickTime
  2345.  11.1.1) Q: I want to write a Amiga QuickTime player and need
  2346. the PREC format details.
  2347.  
  2348. A: Although the structure of QuickTime movies is well documented
  2349. in Inside Mac: QuickTime, the inner workings of the Apple compression
  2350. modules is a trade secret that Apple will only license to you
  2351. at great cost.  Perhaps it's time for a freeware, cross-platform
  2352. QuickTime codec?
  2353.  
  2354. *11.2* QuickDraw 3D
  2355.  
  2356. 11.2.1) Q: Where do I start with QuickDraw 3D?
  2357.  
  2358. A: Apple (http://www.info.apple.com/) maintains a web server
  2359. devoted to QuickDraw 3D (http://qd3d.apple.com).
  2360.  
  2361. *11.2* OpenDoc
  2362.  
  2363. 11.2.1) Q: Tell me about OpenDoc, please?
  2364.  
  2365. A: OpenDoc can be found at CILabs and  Apple
  2366.  (http://www.info.apple.com/dev/du/intro_to_opendoc/iod0_index.html),
  2367. and an OpenDoc-interest mailing list is maintained at CILabs
  2368. for those who are interested enough.
  2369.  
  2370.  *12* Third-Party Solutions
  2371.  
  2372. *12.1* Databases
  2373.  
  2374. 12.1.1) Q: What are some royalty-free databases available for
  2375. the Macintosh?
  2376.  
  2377. A: These are commercial with no run-time licenses:
  2378.  
  2379.  
  2380.  Prograph CPX (mailto:sales@prograph.com) comes with a database
  2381. that can do indexes and tables.
  2382.  CXBase Pro (mailto:tse.int@applelink.apple.com) is an engine
  2383. that comes with source, does tables and indexes in one compound
  2384. file.
  2385.  dtF (mailto:DTF.AMERICA@applelink.apple.com) is a relational
  2386. database library.  
  2387.  
  2388. NeoAccess is an object-oriented database, where you can store
  2389. objects and retrieve by field value; it handles inheritance as
  2390. well.  Comes as a demo on the CodeWarrior CD with an unlockable
  2391. archive of the real thing.
  2392.  
  2393. 12.1.2) Q: I need a robust Client/Server database library.
  2394.  
  2395. A: Get the Macintosh Client/Server Database Development Summary
  2396.  (mailto:maccsdb@external.umass.edu), by Liam Breck.  It covers
  2397. software applicable to Macintosh (and cross-platform) client/server
  2398. database development in three categories:
  2399.  
  2400.  
  2401.  Client application development tools
  2402.  Data access layers
  2403.  Database servers 
  2404.  
  2405. The eight page (20 Kbytes ASCII text) document includes explanations
  2406. of the three categories and describes over 30 products.  Its
  2407. sources are vendors' product literature, industry periodicals,
  2408. and discussions with users and vendors' tech support staff. 
  2409. It is purely informational and contains no propaganda, as the
  2410. author is a neutral party.
  2411.  
  2412. *12.2* Circumvention of Toolbox Limitations
  2413.  
  2414. 12.2.1) Q: Help!  The List Manager is driving me right up the
  2415. wall!  I want to throw it out and start over.  What'r my options?
  2416.  
  2417. A: The only commercially available non-framework List Manager
  2418. replacement of which I'm aware is StoneTable
  2419.  (http://www.teleport.com/~stack), a commerical replacement library
  2420. for the List Manager which provides many extensions  including
  2421. variable size columns/rows, column/row titles, different style/font/size/color
  2422. per cell, sorting, edit in cell, and much more.
  2423.  
  2424. TCL, PowerPlant, and MacApp (see section 1) all have their own
  2425. integrated list management solutions.
  2426.  
  2427.  *13* Dessert
  2428.  
  2429. 13.1) Q: Dessert?
  2430.  
  2431. A: Honey Hill Farms Cookie Jar Frozen Yoghurt or Haagen-Dazs
  2432. Raspberry & Cream Ice Cream.
  2433.  
  2434. Hokey-Pokey icecream with chocolate sauce and (for those who
  2435. like their brain food firmer) Almond and Double Chocolate CookieTime
  2436. cookies!?
  2437.  
  2438. President's Choice Decadent chocolate chip cookies straight out
  2439. of the refrigerator with large quantities of milk.
  2440.  
  2441. *14* Other Answers
  2442.  
  2443. No FAQ is an island.  The answer sheets/pages listed here cover
  2444. in-depth topics only lightly touched upon in these electrons.
  2445.  Feel free to send in more!
  2446.  
  2447. Language FAQs  C++
  2448.  (http://www.cis.ohio-state.edu/hypertext/faq/bngusenet/comp/lang/c++/top.html)  C
  2449.  (http://www.cis.ohio-state.edu/hypertext/faq/bngusenet/comp/lang/c/top.html)
  2450.  
  2451. Graphics Programming FAQs  comp.graphics.algorithms
  2452.  (http://www.cis.ohio-state.edu/hypertext/faq/usenet/graphics/algorithms-faq/faq.html)
  2453. - good graphics programming pointers.  Not very complete at this
  2454. writing.
  2455.  
  2456. Free Development Tools (http://www.europa.com/~sf/fdsm.html) Free/Shareware
  2457. Development Tools FAQ, maintained by Brian Connors.
  2458.  
  2459. The Literature of Mac Programming
  2460.  (http://www.pitt.edu:81/~nick/MacDev/Literature.html) A part
  2461. of Nick DeMello's  Mac Programming pages
  2462.  (http://www.pitt.edu:81/~nick/MacDev).
  2463.  
  2464.  Usenet Mac Game Programming book
  2465.  (http://www.best.com/~mxmora/c.s.m.g.p.b.0.html) Matt X. Mora
  2466. is coordinating a virtual comp.sys.mac.programmer Game Programming
  2467. book.
  2468.  
  2469. Land O' Mac Geeks (http://dts.apple.com/geeks.html) DTS Mac programming
  2470. page.
  2471.  
  2472.  Portable Parallel C++
  2473.  (http://www.extreme.indiana.edu/sage/pcxx_ug/pcxx_ug.html) PowerMacintosh
  2474. programming at an affordable price.  Who needs Java?
  2475.  
  2476. *15* Contributors
  2477.  
  2478. The public domain comp.sys.mac.programmer FAQ sheet was started
  2479. by, and largely reflects the wisdom of, Jon Watte
  2480.  (mailto:h+@austin.metrowerks.com).  Chris Thomas (mailto:ckt@best.com)
  2481. succeeded him as content editor/caretaker in 1994, and usurped
  2482. distribution in 1995.
  2483.  
  2484. The following is a list of people who've contributed to the FAQ
  2485. directly.  If I've forgotten someone or you want a name corrected, please
  2486. let me know (mailto:ckt@best.com).
  2487.  
  2488.  
  2489.  Brian Bechtel (mailto:blob@apple.com)
  2490.  Denis Birnie
  2491.  C. Ben Boyle (mailto:boyle@spacsun.rice.edu)
  2492.  Liam Breck
  2493.  Scott Bronson (mailto:urge@mcl.mcl.ucsb.edu)
  2494.  Jim Chan (mailto:jchan@bio-rad.com)
  2495.  Brian Connors (mailto:connorbd@cleo.bc.edu)
  2496.  Tim Converse (mailto:converse@cs.uchicago.edu) 
  2497.  Chris (mailto:dagnon@cs.wisc.edu)
  2498.  Bob Hablutzel
  2499.  Julian Harris
  2500.  Bruce Hoult (mailto:Bruce@hoult.actrix.gen.nz) 
  2501.  Peter Jensen (mailto:pjensen@netcom.com) 
  2502.  Steve Jasik (mailto:macnosy@jasik.com) 
  2503.  Jonathan Kimmitt (mailto:jrrk@camcon.co.uk) 
  2504.  Scott Kleper (mailto:sjked@rit.edu)
  2505.  Jim Lloyd (mailto:jim@melongem.com)
  2506.  Matthias Neeracher (mailto:neeri@iis.ee.ethz.ch) 
  2507.  David P. Oster (mailto:oster@netcom.com) 
  2508.  Louis M. Pecora
  2509.  Marco Piovanelli (mailto:piovanel@dsi.unimi.it)
  2510.  Ingemar Ragnemalm (mailto:ingemar@lysator.liu.se)
  2511.  Pete Resnick (mailto:resnick@uiuc.edu)
  2512.  Phil Shapiro (mailto:phils@bedford.symantec.com)
  2513.  eric slosser (mailto:slosser@apple.com)
  2514.  M Sooriarachchi
  2515.  Bill (mailto:stack@teleport.com)
  2516.  Chris Thomas (mailto:ckt@best.com)
  2517.  Mark Valence (mailto:kurash@dartmouth.edu)
  2518.  Doug W. (mailto:dougw@as.arizona.edu)
  2519.  Jon Watte (mailto:h+@austin.metrowerks.com)
  2520.  Rick Zaccone (mailto:zaccone@bucknell.edu) 
  2521.  
  2522.  This FAQ is public domain.   
  2523.  
  2524.