Errata – Macintosh Programming Secrets (1992)

Preamble

Mistakes in Macintosh Programming Secrets (1992) by Scott Knaster.

See also

Links

  • No link to PDF version

Notes

Errata

  • Page 39
    • The pixel order in a Figure 2-3, byte #65 and then the next line byte #64
  • Page 88
    • = (WindowPtr)
  • Page 99
    • longmenuResult just hanging loose before the {
  •  Page 92 vs page 117
    • FrontWindow() or theWindow?
  • Page (Chapter 3)
    • NIL, TRUE and FALSE should be nil, true and false or need to be declared
  • Chapter 3
    • No mention of CloseAnyWindow in the text of the book’s chapter 3 (nor in the routine summary at the end of the chapter), although it is in the listing
  • Chapter 3
    • No mention of IsDialogWindow in the text of the book’s chapter 3 (nor in the routine summary at the end of the chapter), although it is in the listing
  • Chapter 3
    • No header files #include lines are given
  • Pages 74 and 112
    • Order of the #includes is wrong
    • #include standardStuff.h should be the last include and requires a lot of headers preceding it (at least Types.h, and maybe Traps.h), see below
  • Page 93
  • Function called HandleMultiFinder, but page 118, in listing 3-2, it is HandleOSEvent
  • Page 112
    • exists should be exits
  • Page 127/128
    • No mention of declaring sleepyTime, which is a long, so long sleepyTime; is needed in MainEventLoop()
  • Page 128 – 4th paragraph
    • “We finish up this stuff…” – The the lines for, or calling, HandleEvent, and /or MainEventLoopTasks are not shown… see Page128 guess work below
  • Page 128
    • if (gInModelState && (theWindow != FrontWindow()) && (part != menuBar)) { has too many )
      • It should be if (gInModelState && (theWindow != FrontWindow() && (part != menuBar)) {
  • Page 128
    • AdjustMenus() code changes not shown (it even says “we won’t even bother showing them”! The changes to standardstuff.c are not even shown in the listing at the end of the chapter. Given the unreliability of the code in the text of the previous chapter, this doesn’t inspire much confidence..!
  • Page 130
    • Mentions global and then the enter, escape definitions, but totally skips over the routine declarations
  • Page 130
    • Resource #defines should begin with r and not k?
  • Page 155 (Summary)
    • Movable Modeless dialog should be movable modal dialog – get it right, FFS!
  • Page 164
    • Indentation is bad (missing 4 spaces) starting at first return TRUE; to return FALSE;
  • Page 165
    • Space in variable name
      • SetIText(iHandle, the String);
  • Page 177
    • Ox should be 0x(16 occurrences)
  • Page 195 – top line
    •  fourth parameter not the third
  • Page 195 – last line
    • Divided by, not times: “number of pixels times eight” should be “number of pixels divided by eight”. Subsequent calculation and result is correct, though
  • Page 224
    • Why is the chapter 5 listing confusingly also called neat stuff.c the same as the listing in chapter 4?
  • Page 229
    • our big union on visRgns should be of not on
  • Page 232
    • off Worlder – space in name
    • 0x08000 – weird x
  • Page 239
    • HandleOSEvent previously in Chapter 3, page 93 (and ch4?) was HandleMultiFinder, but page 118, in listing 3-2, it is HandleOSEvent
  • page 239
    • HandleUpdate is in NeatStuff.c, but Ch3 page 95, it is in StandardStuff.c. Where is it in Ch4?
      • However, upon re-reading, HandleUpdate is still in StandardStuff.c but now calls DoUpdateWindow which is in (the new Ch6 version of) NeatStuff.c. Is that all that HandleUpdate does now? Who the fuck knows, without any listing being given?
  • Page249
    • For symmetry p249, DoCloseWindow() should simply call a new function CloseBufferedWindow(), which contains the lines currently in DoCloseWindow()
  • Page 279
    • NeatStuff.h and .c again (see also note about page 224) !!! Does this guy use the same filename for every file that he produces, including love letters??! Should be “Neat Stuff Ch6.h” and “Neat Stuff Ch6.c”
  • Page 293
    • Listing of MouseTracker.h starts one third down the page, but is listed as still being part of Neat Stuff.c
  • Pages 252 and 254/255
    • DoUpdateWindow() and RefreshWindow() (respectively) – maybe not errata but confusingly written.
      • DoUpdate Window calculates rectToCopy and calls RefreshWindow, passing rectToCopy
      • RefreshWindow renames the parameter rectToCopy to theRect and then also declares a local variable also called rectToCopy. Then uses SectRect to calculate the new rectToCopy.
      • Why mess with the names like that? Keep the passed parameter with the same name, for the love of God, man!!!!
  • Page 255
    • However, the book text on page 255 states “putting the intersection rectangle into the variable theRect”, it should be “putting the intersection rectangle into the local variable rectToCopy”
    • SectRect places the intersection into the third parameter not the first!!!
  • Page 302
    • How is DoZoomWindowO() actually added to HandleMouseDown(), in StandardStuff.c? Not specified.
  • Page 343
    • void TweakLowerGuys((WindPtr theWindow); is declared in the header file StandardStuff.h but not defined in StandardStuff.c
  • page 343 vs 355 and 357
    •  FinishUpProc theEnder vs FinishUpProc enderWiggin
  • page 351
    • Missing indentation on line maxWindowsInDiagonal = kWindowsPerDiagonal;
  • Page 357
    • Messed up indentation after first if after do makes it look like there is a missing closing brace. However, the closing brace of the do is at the end of the function on the follwing page, along with the while.
  • Page 358
    • Again, the same messed up indentation gives the two adjacent closing braces in the same tab. This is actually resolved, once the indentation is fixed.

#include lines required for Chapter 3 – Standard_stuff.c

To compile Standard_stuff.c

#include "Traps.h"
#include "types.h"
#include "Events.h"
//#include "Traps.h"
//#include <Memory.h>/* for THz heap zone ptr */
#include <OSUtils.h> /* for GetTrapAddress() */
#include "Windows.h"
#include "Menus.h"
#include "Values.h"
#include "AppleEvents.h"
//#include "MacTypes.h"

To build Standard_stuff.c

/* Headers required for building */
#include "TextEdit.h"
#include "Dialogs.h"
#include "DiskInit.h"
//#include "Disks.h"
#include "Files.h"
#include "Fonts.h"
#include "Desk.h"
//#include "Windows.h"
//#include "StandardFile.h"
//#include "OSEvents.h"
//#include "OSUtils.h"
//#include "Packages.h"
//#include "Processes.h"
//#include "QuickDraw.h"
#include "ToolUtils.h"

/* This needs to be at the end */
#include "Standard_stuff.h"

Page128 guess work

MainEventLoop from Chapter 3 is this (note gotEvent=Wait... and HandleEvent()

  cursorRgn = nil;
  while (!gQuit) {
    gotEvent = WaitNextEvent(everyEvent, &event, MAXLONG, cursorRgn);
    if (gotEvent){
      HandleEvent(&event);
    }

Page 127 adds

  while (!gQuit) {
    sleepyTime = (gPeriodicTask ?1: MAXLONG);
    gotEvent = WaitNextEvent(everyEvent, &event, sleepyTime, cursorRgn);
    passToDialog = TRUE;
    if ((FrontWindow() == NIL ) || (event.what ==diskEvt) || ((event.what == keyDown) && ((event.modifiers & cmdKey) != 0)))
      passToDialog = FALSE;

    if (passToDialog) {
      if (IsDialogEvent(&event)){
        itemWasHit = DialogSelect(&event, &theDialog, &itemHit);
        if (itemHit) {
          DoDialogHit(theDialog, itemHit);
        }
        gotEvent = FALSE;
      }
  }    

The book on page 128 says (but doesn’t show the actual code):

We finish off by handing the event off to our HandleEvent routine if the modeless dialog doesn’t want it, and then calling DoMainEventLoop

Which suggests that the code should now be

  while (!gQuit) {
    sleepyTime = (gPeriodicTask ?1: MAXLONG);
    gotEvent = WaitNextEvent(everyEvent, &event, sleepyTime, cursorRgn);
    passToDialog = TRUE;
    if ((FrontWindow() == NIL ) || (event.what ==diskEvt) || ((event.what == keyDown) && ((event.modifiers & cmdKey) != 0)))
      passToDialog = FALSE;

    if (passToDialog) {
      if (IsDialogEvent(&event)){
        itemWasHit = DialogSelect(&event, &theDialog, &itemHit);
        if (itemHit) {
          DoDialogHit(theDialog, itemHit);
        }
        gotEvent = FALSE;
      }
    if (gotEvent){
      HandleEvent(&event);
    }
    DoMainLoopTasks();
  }

It has to be said that the new code has made rather a mess of the previously tidy and elegant code.

Chapter 4 – AdjustMenus()

Again, on page 128 there is a description of the changes necessary to AdjustMenus() but no code. However, the first part could be as simple as

  /* BEGIN: Chapter 4 changes START */
  if (IsDialogWindow(window)) { // or (more specifically)...
  if (FrontWindow(window) == gMovableModalDialog) {
    DisableMenu(mFile);
    DisableMenu(mEdit);
    // all other menus too...
    DisableMenu(mDialog);
    return;
  }
  /* END: Chapter 4 changes END */

However, the last line on page 128 says:

We also had to add code to enable the menus when the modal dialog isn’t up

Presumably, as there is only one modal dialog, they mean

when the movable modal dialog isn’t up

Logically the code above will do this anyway (as any front window that isn’t movable modeless, will continue in the routine and not return.

Unless we want only one exit point from the routine, in which case use the following code:

  /* BEGIN: Chapter 4 changes START */
  if (IsDialogWindow(window)) { // or (more specifically)...
  if (FrontWindow(window) == gMovableModalDialog) {
    DisableMenu(mFile);
    DisableMenu(mEdit);
    // all other menus too...
    DisableMenu(mDialog);
  } else {
  /* END: Chapter 4 changes END */

  // rest of code (indented for else)

  /* BEGIN: Chapter 4 changes START */
  }  // end of else
  /* END: Chapter 4 changes END */

So, the only extra code is a load of spaces/tabs for indentation and a closing brace `}`.

Upon further thought, maybe you need to check that the movable modal exists using

gMovableModalDialog != NIL

???

Also, upon even further reflection, couldn’t you just reuse the if used (and given in the book on page 128) for HandleMouseDown?

if (gInModelState && (theWindow != FrontWindow())

I wonder whether the listing of the updated Standard_stuff.c wasn’t provided:

  • by accident, or
  • intentionally, to force the reader to think.

Chapter 6 guess work for StandardStuff.c

See pages 238-240

  • MainEventLoop
  • HandleActivate
  • HandleUpdate
  • HandleMouseDown
  • AdjustMenus
  • HandleMenuCommand

Chapter 7 guess work for StandardStuff.c

Guessing HandleMouseDown().

Page 302 says add DoZoomWIndow() but where? The relevant case of HandleMouseDown looks like this

    case inZoomIn:
    case inZoomOut:
      if (TrackBox(theWindow, event->where, part)){
        SetPort(theWindow);
        EraseRect(&theWindow->portRect);
        /*ZoomWindow(theWindow, part, TRUE);*/
        ZoomWindow(theWindow, part, true);
        InvalRect(&theWindow->portRect);
      }
      break;

Within the if or does it replace the if, or does it replace the contents of the if. Or just replace the line

 

        /*ZoomWindow(theWindow, part, TRUE);*/
        ZoomWindow(theWindow, part, true);

This is the end, my friend.

Leave a comment