home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
develop, the CD; issue 1
/
Apple_Develop_1989.bin
/
Compatibility
/
Sample.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-10-16
|
31KB
|
888 lines
/*------------------------------------------------------------------------------
#
# Apple Macintosh Developer Technical Support
#
# MultiFinder-Aware Simple Sample Application
#
# Sample
#
# Sample.c - C Source
#
# Copyright © 1989 Apple Computer, Inc.
# All rights reserved.
#
# Versions:
# 1.00 08/88
# 1.01 11/88
# 1.02 04/89
#
# Components:
# Sample.p April 1, 1989
# Sample.c April 1, 1989
# Sample.a April 1, 1989
# Sample.inc1.a April 1, 1989
# SampleMisc.a April 1, 1989
# Sample.r April 1, 1989
# Sample.h April 1, 1989
# PSample.make April 1, 1989
# CSample.make April 1, 1989
# ASample.make April 1, 1989
#
# Sample is an example application that demonstrates how to
# initialize the commonly used toolbox managers, operate
# successfully under MultiFinder, handle desk accessories,
# and create, grow, and zoom windows.
#
# It does not by any means demonstrate all the techniques
# you need for a large application. In particular, Sample
# does not cover exception handling, multiple windows/documents,
# sophisticated memory management, printing, or undo. All of
# these are vital parts of a normal full-sized application.
#
# This application is an example of the form of a Macintosh
# application; it is NOT a template. It is NOT intended to be
# used as a foundation for the next world-class, best-selling,
# 600K application. A stick figure drawing of the human body may
# be a good example of the form for a painting, but that does not
# mean it should be used as the basis for the next Mona Lisa.
#
# We recommend that you review this program or TESample before
# beginning a new application.
#
------------------------------------------------------------------------------*/
/* Segmentation strategy:
This program consists of three segments. Main contains most of the code,
including the MPW libraries, and the main program. Initialize contains
code that is only used once, during startup, and can be unloaded after the
program starts. %A5Init is automatically created by the Linker to initialize
globals for the MPW libraries and is unloaded right away. */
/* SetPort strategy:
Toolbox routines do not change the current port. In spite of this, in this
program we use a strategy of calling SetPort whenever we want to draw or
make calls which depend on the current port. This makes us less vulnerable
to bugs in other software which might alter the current port (such as the
bug (feature?) in many desk accessories which change the port on OpenDeskAcc).
Hopefully, this also makes the routines from this program more self-contained,
since they don't depend on the current port setting. */
#include <Values.h>
#include <Types.h>
#include <Resources.h>
#include <QuickDraw.h>
#include <Fonts.h>
#include <Events.h>
#include <Windows.h>
#include <Menus.h>
#include <TextEdit.h>
#include <Dialogs.h>
#include <Desk.h>
#include <ToolUtils.h>
#include <Memory.h>
#include <SegLoad.h>
#include <Files.h>
#include <OSUtils.h>
#include <OSEvents.h>
#include <DiskInit.h>
#include <Packages.h>
#include <Traps.h>
#include <Sample.h> /* bring in all the #defines for Sample */
/* The "g" prefix is used to emphasize that a variable is global. */
/* GMac is used to hold the result of a SysEnvirons call. This makes
it convenient for any routine to check the environment. */
SysEnvRec gMac; /* set up by Initialize */
/* GHasWaitNextEvent is set at startup, and tells whether the WaitNextEvent
trap is available. If it is false, we know that we must call GetNextEvent. */
Boolean gHasWaitNextEvent; /* set up by Initialize */
/* GInBackground is maintained by our osEvent handling routines. Any part of
the program can check it to find out if it is currently in the background. */
Boolean gInBackground; /* maintained by Initialize and DoEvent */
/* The following globals are the state of the window. If we supported more than
one window, they would be attatched to each document, rather than globals. */
/* GStopped tells whether the stop light is currently on stop or go. */
Boolean gStopped; /* maintained by Initialize and SetLight */
/* GStopRect and gGoRect are the rectangles of the two stop lights in the window. */
Rect gStopRect; /* set up by Initialize */
Rect gGoRect; /* set up by Initialize */
/* Here are declarations for all of the C routines. In MPW 3.0 we can use
actual prototypes for parameter type checking. */
void EventLoop( void );
void DoEvent( EventRecord *event );
void AdjustCursor( Point mouse, RgnHandle region );
void GetGlobalMouse( Point *mouse );
void DoUpdate( WindowPtr window );
void DoActivate( WindowPtr window, Boolean becomingActive );
void DoContentClick( WindowPtr window );
void DrawWindow( WindowPtr window );
void AdjustMenus( void );
void DoMenuCommand( long menuResult );
void SetLight( WindowPtr window, Boolean newStopped );
Boolean DoCloseWindow( WindowPtr window );
void Terminate( void );
void Initialize(WindowPtr *win);
Boolean GoGetRect( short rectID, Rect *theRect );
void ForceEnvirons( void );
Boolean IsAppWindow( WindowPtr window );
Boolean IsDAWindow( WindowPtr window );
Boolean TrapAvailable( short tNumber, TrapType tType );
void AlertUser( void );
/* Define HiWrd and LoWrd macros for efficiency. */
#define HiWrd(aLong) (((aLong) >> 16) & 0xFFFF)
#define LoWrd(aLong) ((aLong) & 0xFFFF)
/* Define TopLeft and BotRight macros for convenience. Notice the implicit
dependency on the ordering of fields within a Rect */
#define TopLeft(aRect) (* (Point *) &(aRect).top)
#define BotRight(aRect) (* (Point *) &(aRect).bottom)
extern void _DataInit();
/* This routine is part of the MPW runtime library. This external
reference to it is done so that we can unload its segment, %A5Init. */
#pragma segment Main
main()
{
WindowPtr window;
UnloadSeg((Ptr) _DataInit); /* note that _DataInit must not be in Main! */
/* 1.01 - call to ForceEnvirons removed */
/* If you have stack requirements that differ from the default,
then you could use SetApplLimit to increase StackSpace at
this point, before calling MaxApplZone. */
MaxApplZone(); /* expand the heap so code segments load at the top */
Initialize(&window); /* initialize the program */
UnloadSeg((Ptr) Initialize); /* note that Initialize must not be in Main! */
InstallCVBL(); /* demo our VBL task */
if (window)
ShowWindow (window); /* show traffic light window */
EventLoop(); /* call the main event loop */
}
/* Get events forever, and handle them by calling DoEvent.
Get the events by calling WaitNextEvent, if it's available, otherwise
by calling GetNextEvent. Also call AdjustCursor each time through the loop. */
#pragma segment Main
void EventLoop()
{
RgnHandle cursorRgn;
Boolean gotEvent;
EventRecord event;
Point mouse;
cursorRgn = NewRgn(); /* we'll pass WNE an empty region the 1st time thru */
do {
/* use WNE if it is available */
if ( gHasWaitNextEvent ) {
GetGlobalMouse(&mouse);
AdjustCursor(mouse, cursorRgn);
gotEvent = WaitNextEvent(everyEvent, &event, MAXLONG, cursorRgn);
}
else {
SystemTask();
gotEvent = GetNextEvent(everyEvent, &event);
}
if ( gotEvent ) {
/* make sure we have the right cursor before handling the event */
AdjustCursor(event.where, cursorRgn);
DoEvent(&event);
}
/* If you are using modeless dialogs that have editText items,
you will want to call IsDialogEvent to give the caret a chance
to blink, even if WNE/GNE returned FALSE. However, check FrontWindow
for a non-NIL value before calling IsDialogEvent. */
} while ( true ); /* loop forever; we quit via ExitToShell */
} /*EventLoop*/
/* Do the right thing for an event. Determine what kind of event it is, and call
the appropriate routines. */
#pragma segment Main
void DoEvent(event)
EventRecord *event;
{
short part, err;
WindowPtr window;
Boolean hit;
char key;
Point aPoint;
switch ( event->what ) {
case mouseDown:
part = FindWindow(event->where, &window);
switch ( part ) {
case inMenuBar: /* process a mouse menu command (if any) */
AdjustMenu