Posted 2025-04-20 | Back to blog index
This weekend I made a lot of progress on my Classic Mac OS app template in C!
I have ideas for tools I want to make (mainly for GlobalTalk), but need a foundation to build on. AIRConfig was built on of some very basic sample code included with MPW and really not suitable for extending even as far as I went with AIRConfig
There are also full-blown frameworks like MacApp and PowerPlant, but they seem like quite a lot of complexity to learn just for small tools
So I've moved from MPW to CodeWarrior, and with heavy (HEAVY) inspiration from Easy App (from the Programming Starter Kit book) been putting together a basic framework.
The main goal is striking the right balance between complexity and simplicity - which is hard to explain for a Classic MacOS Toolbox app since it's so different from how modern apps are written. A Mac OS app does nothing automatically - you need to build the whole event loop manually, with a big switch for event type.
There is a very specific sweet spot in abstraction I'm looking for.
I don't want to go full GUI builder/Object Oriented abstracted framework/document management like PowerPlant appears to do.
But I still want a basic OO style where the framework deals with all the basic window management but I can add new window definitions where I just add implementations for event handler/drawing/onClose/etc.
Easy App is partially there, but has way too many hooks for things I'll never want to customize, meaning each new window is a thousand lines of boilerplate. And there is a bunch of stuff like abstracting window content drawing to also support printing that makes things more complicated than I will ever need.
So I'm reducing that down to something manageable to make hacking together classic mac tools fun.
One thing I have in mind is keeping it simple enough to make a series of videos for next MARCHintosh using it to introduce the very basics of Classic Mac OS Toolbox C programming - walking through what the framework does, and then showing some examples of adding buttons to windows that play sounds or show dialogs, and then opening up a Projector (version control system) database (repository) on GlobalTalk for anyone else to add stuff in a collaborative project.
For reference, here is the sample code that AIRConfig was based on. Note how emphatic the paragraph at the end is about how "it is NOT a template"!!
Made huuuge amounts of progress today
- Windows with programmatically created controls
- Windows with controls loaded from a DITL resource
- Modal dialogs
- Error alerts (just give it a string)
- Appearance Manager support for the above
- TextEdit control with working appearance manager theming (with focus outline) and working edit menu items
Left on TODO:
- List Manager
- Code cleanup
- Nicer sample app
Then I can get started on the apps I actually want to write!
Dealing with the Appearance Manager and wrangling it into drawing the outline for the TextEdit control was definitely the most difficult part today. And I'm still not quite sure if I'm doing it right, probably not.
E.g. there's no theme color for the background of the text field, so I'm using kThemeDocumentWindowBackgroundBrush. Also there's none for the text!
List Manager lists are working! With focus/tabbing and type-to-search support as well (all of which you have to do manually, of course). Of course with Appearance Manager support as well as fallback drawing for System 7.
Next step is making sure everything works on older OSes - I've only been testing on my G4 in MacOS 9.2.2 so far.
Infinite Mac is great for this!
- System 7: crashes
- MacOS 8.1: crashes
- MacOS 8.5: works
Looks like I have my work cut out for me
Installed QEMU for easier debugging with MacsBug.
Here's the stack trace, and a screenshot of the code.
It's crashing in FrameRect - trying to draw a rectangle. Really weird! Right before that it's drawing text, so the grafport is set correctly. We're in the event loop so it's not due to interrupts. I tried making a static rect instead of pulling it from the TextEdit handle, so it's not a bad pointer or corrupted coordinates.
After banging my head against it for an hour or teo, I started looking at some other QuickDraw sample code to see if there was anything missing.
The sample code was setting the pen pattern to black. I mean, I'm sure it defaults to that so there's no point in setting it but...
Damn. That fixed it!! What the heck! Well, works perfectly in System 7 now!
Out of time for today, but I did a bit of testing in MacOS 8.1 in Infinite Mac (installing MacOS 8 w MacsBug into QEMU will have to be another day) to narrow down the crashes:
- The window with the TextEdit crashes, but that crash goes away when I disable the Appearance Manager drawing code
- The window with the List Manager lists crashes even without Appearance Manager
The appearance manager crash could be due to differences in AM 1.0 in MacOS 8 and AM 1.1 in MacOS 8.5. Dunno about the lists…