Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
main.c
/*------------------------------------------------------------------------------ |
# |
# Apple Developer Technical Support |
# |
# AppleEvents & Edition Manager Sample Application |
# |
# AEObject-Edition Sample |
# |
# main.c - C Source |
# |
# Copyright © 1990-1992 Apple Computer, Inc. |
# All rights reserved. |
# |
# Versions: |
# 1.0.1 2/92 C.K. Haun <TR> |
# 1.0 11/91 C.K. Haun <TR> |
# based on the EditionSample |
# Components: |
# main.c |
# Menu.c |
# Files.c |
# Publish.c |
# Subscribe.c |
# TextSections.c |
# Windows.c |
# AppleEventCore.c |
# AEObject-Edition Sample.make |
# BuildHeaders.c |
# AEUtilities.c |
# AEObjects.c |
# Utilities.c |
# Initialize.c |
# globals.c |
# Print.c |
# prototypes.h |
# SampConstants.h |
# Structs.h |
# Macros.h |
# Sampdefines.h |
# |
# |
# This sample demonstrates the Apple Event Object model and |
# the Edition Manager. |
# It is an expanded version of the the earlier EditionSample, |
# most of the changes (besides bug fixes) have been made in the |
# files AppleEventCore.c,AEUtilities.c and AEObjects.c. |
# I decided to add the Object Model demonstration to the Edition Sample |
# to use the objects (windows, shapes) that already existed |
# instead of developing a new sample. |
# I beleive that the fuctional areas are discreet enough that |
# you can find what you are looking for without too much difficulty, |
# the file names really do reflect the major contents of a |
# specific source file. |
# |
# This sample contains most of the Edition Manager calls that |
# you'll need in your application. It also contains one method |
# for keeping track of the edition data for all your documents. |
# It does NOT by any means demonstrate all the techniques |
# you need for a large application, nor the best data handling |
# methods for all cases. |
# |
# This sample also implements some Apple Event Object model objects, |
# specifically cWindow, cText,cWord,cGraphicLine,cRectangle and cOval. |
# |
# Use this sample as a starting point, and adapt its' routines to |
# meet the specific needs of your project. |
# This sample will grow as more edition types are implemented, |
# periodically check AppleLink for a later, expanded sample. |
# 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. |
# This sample's focus is the Edition Manager and AppleEvents, NOT |
# drawing or text editing, so those areas are implemented in |
# a very minimal fashion. This is done to prevent obscuring the |
# goal of this sample. If you are interested in those (or other) |
# areas, please look for a sample that focuses on them. |
# |
# |
------------------------------------------------------------------------------*/ |
#define __SAMPMAIN__ |
#pragma segment Main |
#include "Sampdefines.h" |
#include <SegLoad.h> |
extern void _DataInit(); |
main() |
{ |
WindowPtr twindow; |
Boolean x; |
Boolean menuAction; |
windowCHandle tempWCH; |
PScrapStuff theScrap; |
short myScrapCount = -999; /* intialize to a silly value */ |
UnloadSeg((Ptr)_DataInit); /* throw the bums out */ |
StartStuff(); /* initialize managers and normal startup actions */ |
UnloadSeg((Ptr)StartStuff); |
theScrap = InfoScrap(); |
FlushEvents(everyEvent, 0); |
mousergn = NewRgn(); |
gStop = false; |
while (!gStop){ |
x = WaitNextEvent(everyEvent, &gERecord, gMySleep,mousergn); |
theScrap = InfoScrap(); |
if (theScrap->scrapCount != myScrapCount) { |
myScrapCount = theScrap->scrapCount; |
UpdateScrap(true); |
} |
if (FrontWindow() != nil) { |
/* if there is a text box, idle the cursor */ |
TEHandle tempTE; |
windowCHandle tempWCH = (windowCHandle)GetWRefCon(FrontWindow()); |
tempTE = (*tempWCH)->boxHandle; |
if (tempTE != nil) |
TEIdle(tempTE); |
} |
switch (gERecord.what) {short fHit; |
case nullEvent: |
/* marching ants as necessary */ |
DoAnts(nil); |
break; |
case updateEvt: |
DrawIt((WindowPtr)gERecord.message); /* draw whatever window needs an update */ |
break; |
case mouseDown: |
/* first see where the hit was */ |
fHit = FindWindow(gERecord.where, &twindow); |
switch (fHit) {Rect limitRect; |
long back; |
Str255 tempString; |
case inDesk: /* if they hit in desk, then the process manager */ |
break; /* will switch us out, we don't need to do anything */ |
case inMenuBar: |
/* If they clicked in the menu bar, we need to set up the Undo */ |
/* text string for the current window, and the toggle of */ |
/* Publisher or Subscriber options before we drop the */ |
/* menu down. */ |
/* Also change the Save string depending on the save state */ |
/* Pull our aux data structure out of the current window */ |
if (FrontWindow()) { |
tempWCH = (windowCHandle)GetWRefCon(FrontWindow()); |
HLock((Handle)tempWCH); /* lock it */ |
AdjustMenus(tempWCH,FrontWindow()); /* in menu.c */ |
HUnlock((Handle)tempWCH); |
} else { |
AdjustMenus(nil,nil); |
} |
/* Now we drop the menu down, and pass the results */ |
/* to our menu handler (in Menu.c) */ |
menuAction = DoSelected(MenuSelect(gERecord.where)); |
break; |
case inSysWindow: |
/* pass to the system */ |
SystemClick(&gERecord, twindow); |
break; |
case inContent: |
/* Our major workarea. Depending on other factors, a */ |
/* user could be drawing, moving a subscriber, selecting */ |
/* a publisher or subscriber, selecting an area, or nothing. */ |
/* First, if they did not click in the front window, we need */ |
/* to bring the window they did click in to the front, and */ |
/* pull the information we need (cursor mode, undo action, etc. ) */ |
/* out of the aux record and update things */ |
if (twindow != FrontWindow()) { |
ChangePlane(twindow); |
} else { |
if (FrontWindow()) { /* don't do this unless we have a window open, silly */ |
windowCHandle clicker; |
clicker = (windowCHandle)GetWRefCon(twindow); |
/* jump to the content function stored for this window */ |
HLock((Handle)clicker); /* lock it down so things don't get stupid */ |
(ProcPtr)((*clicker)->clickMe)(twindow); |
HUnlock((Handle)clicker); /* all done */ |
} |
} |
break; |
case inDrag: |
DragWindow(twindow, gERecord.where, &qd.screenBits.bounds); |
break; |
case inGrow: |
SetPort(twindow); |
limitRect = qd.screenBits.bounds; |
limitRect.top = kMinHeight; |
GetWTitle(twindow, tempString); |
/* I'm not letting the user shrink the window so */ |
/* small that the title is truncated */ |
limitRect.left = StringWidth(tempString) + 120; |
back = GrowWindow(twindow,gERecord.where, &limitRect); |
if (back) {windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow); |
Rect sizeRect = ((WindowPtr)twindow)->portRect; |
sizeRect.top = sizeRect.bottom - 16; |
sizeRect.left = sizeRect.right - 16; |
EraseRect(&sizeRect); |
InvalRect(&sizeRect); |
SizeWindow(twindow, back & 0xffff, back >> 16, true); |
(ProcPtr)((*tempWCH)->sizeMe)(twindow); |
} |
InvalRect(&twindow->portRect); |
break; |
case inGoAway: |
/* Track a click in the go away box. If the user stays in it, */ |
/* call the close proc for this window */ |
if (TrackGoAway(twindow, gERecord.where)) |
(ProcPtr)((*(windowCHandle)((WindowPeek)twindow)->refCon)->closeMe)(twindow); |
break; |
case inZoomIn: |
case inZoomOut: |
if (TrackBox(twindow, gERecord.where, fHit)) {windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow); |
SetPort(twindow); |
ZoomWindow(twindow, fHit, true); |
InvalRect(&twindow->portRect); |
(ProcPtr)((*tempWCH)->sizeMe)(twindow); |
} |
break; |
} |
case mouseUp: |
/* don't care */ |
break; |
/* same action for key or auto key */ |
case keyDown: |
case autoKey: |
/* Do menu commands. */ |
/* Also check the window record for a TextEdit field, if there */ |
/* is one pass the key to it */ |
if (gERecord.modifiers & cmdKey) { |
if (FrontWindow()) { |
tempWCH = (windowCHandle)GetWRefCon(FrontWindow()); |
HLock((Handle)tempWCH); /* lock it */ |
AdjustMenus(tempWCH,FrontWindow()); /* in menu.c */ |
HUnlock((Handle)tempWCH); |
} else { |
AdjustMenus(nil,nil); |
} |
menuAction = DoSelected(MenuKey(gERecord.message & charCodeMask)); |
} else { |
WindowPtr tempWP = FrontWindow(); |
tempWCH = (windowCHandle)GetWRefCon(tempWP); |
if (((WindowPeek)tempWP)->windowKind == kDocumentWindow && ((*tempWCH)->boxHandle != nil)) { |
Boolean wasPC = false; |
tempWCH = (windowCHandle)GetWRefCon(tempWP); |
if ((*tempWCH)->textSections != nil) { |
/* this text box has sections, and the sections may need to be */ |
/* adjusted by this keystroke. First, see if it's a pure cursor move, */ |
if (wasPC= PureCursor(gERecord.message & charCodeMask)) |
wasPC = SkipOverSubscriber(tempWCH, gERecord.message & charCodeMask); |
else |
CheckTextSections(tempWCH, kKeyStroke); |
} |
if (!wasPC) { |
/* ExcludeSubscriber shortens the current selection if it impact on any */ |
/* subscribers */ |
ExcludeSubscriber(tempWCH); |
TEKey(gERecord.message & charCodeMask, (*tempWCH)->boxHandle); |
KillSelection(tempWCH); |
} |
} |
if(((WindowPeek)tempWP)->windowKind == kAEStatusWindow)AESKey(gERecord.message & charCodeMask,tempWCH); |
} |
break; |
case keyUp: |
/* don't care */ |
break; |
case diskEvt: |
/* I don't do anything special for disk events, this just passes them */ |
/* to a function that checks for an error on the mount */ |
DoDiskEvents(gERecord.message); |
break; |
case activateEvt: |
/* Draws on a window activate. Other activate/deactivate stuff is */ |
/* handled in either the ChangePlane function (for normal shuffling ) */ |
/* or in the suspend/resume handler for layer swaps */ |
if (gERecord.modifiers & activeFlag){ |
ChangePlane((WindowPtr)gERecord.message); |
DrawIt((WindowPtr)gERecord.message); |
} else { |
windowCHandle tempWCH = (windowCHandle)GetWRefCon((WindowPtr)gERecord.message); |
if ((*tempWCH)->boxHandle != nil) |
TEDeactivate((*tempWCH)->boxHandle); |
} |
break; |
case networkEvt: |
/* don't care */ |
break; |
case driverEvt: |
/* don't care */ |
break; |
case app4Evt: |
switch ((gERecord.message >> 24) & 0x0FF) { /* high byte of message */ |
case suspendResumeMessage: /* suspend/resume is also an activate/deactivate */ |
gInBackground = (gERecord.message & kResumeMask) == 0; |
if (gInBackground) { |
SpitClip(); /* export the clipboard please */ |
/* If the clipboard is showing, hide it, since a clipboard */ |
/* is not valid when you are in another layer */ |
if(((WindowPeek)FindClipWindow())->visible == true)CloseClip(FindClipWindow()); |
/* deactivate the current TextEdit record as necessary */ |
if (FrontWindow() != nil) { |
windowCHandle tempWCH = (windowCHandle)GetWRefCon(FrontWindow()); |
if ((*tempWCH)->boxHandle != nil) |
TEDeactivate((*tempWCH)->boxHandle); |
/* set sleep value very high, since I'm doing no nul processing */ |
gMySleep = -1; |
} |
if (gShowSub || gShowPub) { |
/* I forget what this is here for. Oh well */ |
} |
} else { |
gMySleep = 5; /* wake up more */ |
if (FrontWindow() != nil) { |
windowCHandle tempWCH = (windowCHandle)GetWRefCon(FrontWindow()); |
if ((*tempWCH)->boxHandle != nil) |
TEActivate((*tempWCH)->boxHandle); |
} |
} |
break; |
case mouseMovedMessage: |
AdjustCursor(gERecord.where, mousergn); |
break; |
} |
break; |
/* This dispatches high level events (AppleEvents, for example) */ |
/* to our dispatch routine. This is NEW in the event loop for */ |
/* System 7 */ |
case kHighLevelEvent: |
DoHighLevel(gERecord); |
break; |
default: |
break; |
} |
} |
/* save current prferences on exit */ |
SavePrefs(); |
} |
/* DrawIt calls the drawing routine for the window that requires a refresh, |
* either for a update or activate |
*/ |
void DrawIt(WindowPtr theWindow) |
{ |
WindowPtr tempwind; |
windowCHandle tempWCH; |
GetPort(&tempwind); /* save the current port */ |
BeginUpdate(theWindow); /* tell window manager to do it's thing */ |
SetPort(theWindow); |
EraseRgn(theWindow->visRgn); /* erase whatever needs updating, remember that |
BeginUpdate copies the update region into the visRgn */ |
/* pull our control structure out of the refCon */ |
tempWCH = (windowCHandle)GetWRefCon(theWindow); |
HLock((Handle)tempWCH); /* lock it down so things don't get stupid */ |
/* jump to the drawing function stored for this window */ |
(ProcPtr)((*tempWCH)->drawMe)(tempWCH, theWindow); |
HUnlock((Handle)tempWCH); /* all done */ |
EndUpdate(theWindow); /* all done */ |
SetPort(tempwind); /* reset the port to the entry port */ |
} |
/* DrawIt */ |
void DeBorderSelection(void) |
{ |
if (gShowPub) { |
gShowPub = false; |
gShowingSecHandle = nil; |
InsetRect(&gShowPubRect, kNegFour, kNegFour); |
InvalRect(&gShowPubRect); |
InsetRect(&gShowPubRect, kFour, kFour); |
} else { |
if (gShowSub) { |
gShowSub = false; |
gShowingSecHandle = nil; |
InsetRect(&gShowSubRect, kNegFour, kNegFour); |
InvalRect(&gShowSubRect); |
InsetRect(&gShowSubRect, kFour, kFour); |
} |
} |
} |
/* Just in case I need a nothing proc, here's one. In Main so I'm not dragging in other segments */ |
void NilProc(void) |
{ |
} |
#undef __SAMPMAIN__ |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14