• Updated 2023-07-12: Hello, Guest! Welcome back, and be sure to check out this follow-up post about our outage a week or so ago.

Problem with example in Macintosh Programming Primer

PB170

Well-known member
I really don't mind the absence of syntax highlighting too much, to be honest.  It is nice, but not obligatory.  But honestly I'm still perfectly happy writing code in BBEdit Lite.

I suppose in my head I'm kind of comparing it with the THINK Pascal that I used to use, which had things like actual integration between the debugger and editor (though it also did really, really odd things with syntax hilighting).  That said, I think that version of TP was a few years later than THINK C 5.0, so I may just be being unfair.
Interesting! I wasn't aware of that. I feel I have to check it out, just to compare it and see what it looks like.

According to freepascal.org the last version of Think Pascal is about as old as Think C 5: "THINK Pascal was a Pascal language compiler for 68K-based Mac computers. […] The last official update was released in 1992. THINK Pascal was discontinued in 1997."

Also, Wikipedia seem to confirm your experience: "The Lightspeed and Think C integrated development environment (IDE) influenced other such environments, though considered not as advanced as that belonging to Think Pascal, its sister language product."

 

Crutch

Well-known member
Yeah THINK Pascal with its excellent editor/debugger integration is at least as old as THINK C and really goes back to Macintosh Pascal, which THINK built for Apple.  They just never made THINK C quite as pretty.

I always thought THINK C was very happily usable, though.

Crazy weekend so wouldn’t be able to code this up formally but FWIW here’s how I would do this:

  • Build the pop-up menu on the fly with NewMenu():


    minutesMenu = NewMenu(kMinutesMenuID, ...);

[*]Add items to it with AppendMenu(), like


  • const short kMinuteIncrement = 5;
  • short i;
  • Str255 string;
  • for (i = 0; i < 60; i += kMinuteIncrement)
  • {


    NumToString(i, string);
  • AppendMenu(minutesMenu, string);

[*]}



[*]Then when the user hits OK, use GetCtlValue() to get the index of the selected item ID in the pop up menu, and multiply it by kMinuteIncrement:


  • val = GetCtlValue( (ControlHandle) itemHandle );
  • reminder->minute = (val - 1) * kMinuteIncrement;






 

PB170

Well-known member
Thank you, that's very, very helpful! I'll go through and digest it all tomorrow. What better way to learn than to correct and improve the learning material! :)  

 
Last edited by a moderator:

cheesestraws

Well-known member
Crazy weekend so wouldn’t be able to code this up formally but FWIW here’s how I would do this:
Seconded. This was pretty much what I was thinking, too.

Yeah THINK Pascal with its excellent editor/debugger integration is at least as old as THINK C and really goes back to Macintosh Pascal, which THINK built for Apple.
I still feel like it took a *long* time for the rest of the world to catch up to THINK Pascal's debugger.  But this may be simply an artefact of old fondness.

 

PB170

Well-known member
Crazy weekend so wouldn’t be able to code this up formally but FWIW here’s how I would do this:

  • Build the pop-up menu on the fly with NewMenu():


    minutesMenu = NewMenu(kMinutesMenuID, ...);

[*]Add items to it with AppendMenu(), like


  • const short kMinuteIncrement = 5;
  • short i;
  • Str255 string;
  • for (i = 0; i < 60; i += kMinuteIncrement)
  • {


    NumToString(i, string);
  • AppendMenu(minutesMenu, string);

[*]}



[*]Then when the user hits OK, use GetCtlValue() to get the index of the selected item ID in the pop up menu, and multiply it by kMinuteIncrement:


  • val = GetCtlValue( (ControlHandle) itemHandle );
  • reminder->minute = (val - 1) * kMinuteIncrement;
Hello again,

Regarding your first point; will building the menu on the fly replace both the DITL item and the MENU resource, or just the MENU resource? Would you mind showing how this is done in a bit more detail?

Also, if I were to just correct the code in the example from the book so that it works properly with a minimum of changes, what would be the right way to get the text string of the current menu setting?

 

Crutch

Well-known member
Building on the fly would just replace the MENU resource.  I am having a crazy week but happy to cobble together an example of how do to this .... it might be a little while though.

Re your second question, this code snippet (from the book) is the right way to to do it .... but you need to make sure that mMinutes is a menu ID not a ‘MENU’ resource ID.  I don’t recall how a menu ID is assigned for a pop up menu offhand though ... the Menu Manager chapter of Inside Macintosh Volume V should help!  I can give a better answer when I have time to research slightly and refresh my memory!

Code:
[COLOR=#000000]    GetDItem( dialog, iMinutesPopup, &itemType, &itemHandle, &itemRect );
    val = GetCtlValue( (ControlHandle)itemHandle );
    menu = GetMHandle( mMinutes );
    GetItem[/COLOR]( menu, val, string );
 
Last edited by a moderator:

PB170

Well-known member
Building on the fly would just replace the MENU resource.  I am having a crazy week but happy to cobble together an example of how do to this .... it might be a little while though.

Re your second question, this code snippet (from the book) is the right way to to do it .... but you need to make sure that mMinutes is a menu ID not a ‘MENU’ resource ID.  I don’t recall how a menu ID is assigned for a pop up menu offhand though ... the Menu Manager chapter of Inside Macintosh Volume V should help!  I can give a better answer when I have time to research slightly and refresh my memory!

GetDItem( dialog, iMinutesPopup, &itemType, &itemHandle, &itemRect );
val = GetCtlValue( (ControlHandle)itemHandle );
menu = GetMHandle( mMinutes );
GetItem
( menu, val, string );

Thank you! There's no rush, so take your time.

 

PB170

Well-known member
In the meantime, does anyone here have any ideas about why the texts don't fit in the popups like they do in the book?

Book:

Book.png

My version:

ResEdit.png

System 7.png

OS 9:

Mac OS 9.png

 

PB170

Well-known member
By the way, I haven't come across this syntax before:

   pascal OSErr SetDialogDefaultItem(DialogPtr theDialog, short newItem)
       = { 0x303C, 0x0304, 0xAA68 };


Is this standard C syntax or something specific for the Mac or Think C?

I assume the values inside the curly braces are specifying the specific memory locations where the beginning of the function and its parameters are stored.

 

Crutch

Well-known member
That’s THINK C’s way of defining a function implementation with inline machine code in hex.  I’m pretty sure 0xAA68 is the trap number for _DialogDispatch, which was added in System 7 (see Inside Macintosh Volume VI, probably).  SetDialogDefaultItem() and many other new Dialog Manager routines added in System 7 is actually implemented by calling _DialogDispatch with a particular routine selector.  “0x303C 0x0304” are probably 68k opcodes to push the appropriate routine selector onto the stack.

So in short, that function definition is telling THINK C that SetDialogDefaultItem() is syntactic sugar for pushing a particular routine selector onto the stack then dropping into _DialogDispatch.

 
Last edited by a moderator:

PB170

Well-known member
Thanks! That's interesting. Makes sense.

Do other compilers have similar ways of doing this, and is this way of doing it present also in modern systems? Just curios :)

Do you think you will find a moment to explain how to build the popup menu directly and how to fix the code in the example? I'm thankful for any input.

 
Last edited by a moderator:
Top