System 7 app boilerplate
Needs refinement/completion.
Written in C, can be compiled with MPW. Requires Color QuickDraw.
#include <Types.h>
#include <Memory.h>
#include <Quickdraw.h>
#include <Fonts.h>
#include <Events.h>
#include <Menus.h>
#include <Windows.h>
#include <TextEdit.h>
#include <Dialogs.h>
#include <Sound.h>
#include <ToolUtils.h>
#include <Processes.h>
void main(void);
// utility functions
Boolean IsColorQuickDrawAvailable(void);
Boolean IsSystem7Available(void);
Boolean TrapAvailable(short trap);
TrapType GetTrapType(short trap);
short GetNumToolboxTraps(void);
void PrintDebug(Str255 s);
// lifecycle
void Initialize(void);
void EventLoop(void);
void CleanUp(void);
// event handlers
void HandleActivate(WindowPtr window, Boolean isActive);
void HandleIdle(EventRecord *event);
void HandleEvent(EventRecord *event);
void HandleMenuCommand(EventRecord *event);
void HandleUpdate();
void HandleMouseDown(EventRecord *event);
Boolean HandleCloseWindow(WindowPtr window);
// globals
QDGlobals qd;
RgnHandle global_cursorRegion;
WindowPtr global_window;
Rect global_rect;
Rect global_dragRect;
Boolean global_isQuitting;
void main(void) {
Initialize();
EventLoop();
CleanUp();
ExitToShell();
}
void Initialize(void) {
global_isQuitting = false;
if (!IsColorQuickDrawAvailable()) {
SysBeep(50);
global_isQuitting = true;
} else {
InitGraf(&qd.thePort);
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(nil);
InitCursor();
SetRect(&global_rect, 100, 100, 640, 480);
SetRect(&global_dragRect, 0, 0, 32767, 32767); // is there a proper way to handle this?
// opens a color window
global_window = NewCWindow(nil, &global_rect, "\pHello World", true, noGrowDocProc, (WindowPtr) -1, true, 0);
SetPort(global_window);
// SetUpMenus();
}
}
void CleanUp(void) {
if (!!global_window) {
DisposeWindow(global_window);
}
}
void EventLoop(void) {
Boolean haveEvent;
EventRecord event;
while(!global_isQuitting) {
// global_isQuitting = Button();
// this should handle yielding to the os and other processes for multitasking...
// but it doesnt seem to be working properly? (apps underneath do not redraw/update)
haveEvent = WaitNextEvent(everyEvent, &event, 100, global_cursorRegion);
if (haveEvent) {
HandleEvent(&event);
} else {
HandleIdle(&event);
}
}
}
void HandleEvent(EventRecord *event) {
switch(event->what) {
case updateEvt:
if ((WindowPtr) event->message == global_window) {
HandleUpdate();
}
break;
case mouseDown:
HandleMouseDown(event);
break;
case activateEvt:
//HandleActivate((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
break;
}
}
void HandleIdle(EventRecord *event) {
// TODO
}
void HandleUpdate(void) {
BeginUpdate(global_window);
// Updating/drawing goes here
EndUpdate(global_window);
}
void HandleMouseDown(EventRecord *event) {
WindowPtr clickWnd;
int clickLoc = FindWindow(event->where, &clickWnd);
// TODO: check if all of these are actually necessary in System 7+
switch(clickLoc) {
case inSysWindow:
SystemClick(event, clickWnd);
break;
case inContent:
if (clickWnd != FrontWindow()) {
SelectWindow(clickWnd);
}
break;
case inGoAway:
// handles clicking close window
if (TrackGoAway(clickWnd, event->where)) {
global_isQuitting = true;
}
break;
case inDrag:
// allows dragging the window within the given drag rect
DragWindow(clickWnd, event->where, &global_dragRect);
break;
}
}
// dunno really what to do with this yet
void HandleActivate(WindowPtr window, Boolean isActive) {
if (isActive) {
} else {
}
}
Boolean IsColorQuickDrawAvailable(void) {
SysEnvRec sysenv;
OSErr error = SysEnvirons(1, &sysenv);
return !error && sysenv.hasColorQD;
}