home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1996-04-25 | 126.4 KB | 4,139 lines | [ TEXT/CWIE]
{****************************************************************************} { TCL.p} {} { Interface for the Core TCL classes} {} { Copyright © 1989-1991 Symantec Corporation. All rights reserved.} {} {****************************************************************************} {TCL VERSION 1.1.2.3 - APRIL 25 1996} {CAN BE COMPILED USING METROWERKS PASCAL COMPILERS} unit TCL; { Core TCL classes } interface uses AppleEvents, Balloons, Exceptions, Windows, StandardFile, types, TextUtils, ToolUtils; {**************************************************} { Globals} {} { Commonly used constants, type definitions, and variables. } {} {**************************************************} const MININT = (-maxint) - 1; { Mininum int value } MINLONG = (-maxlongint) - 1; { Minimum longint value } NOTHING = 0; { Useful flag } xInts = (maxint div sizeof(integer)) - 1; { Used in array type } xLongs = (maxint div sizeof(longint)) - 1; { definitions below } type BytePtr = ^Byte; IntPtr = ^integer; LongPtr = ^longint; PointPtr = ^Point; RectPtr = ^Rect; RectHandle = ^RectPtr; IntArrayP = ^IntArray; IntArrayH = ^IntArrayP; IntArray = array[0..xInts] of integer; LongArrayP = ^LongArray; LongArrayH = ^LongArrayP; LongArray = array[0..xLongs] of longint; DimOption = (dimNONE, dimSOME, dimALL); { Used by Bartender } CharPtr = ^char; tSystem = packed record hasWNE: BOOLEAN; hasColorQD: BOOLEAN; hasGestalt: BOOLEAN; hasAppleEvents: BOOLEAN; hasAliasMgr: BOOLEAN; hasEditionMgr: BOOLEAN; hasHelpMgr: BOOLEAN; hasScriptMgr: BOOLEAN; hasFPU: BOOLEAN; scriptsInstalled: Integer; systemVersion: Integer; end; var nullStr: Str255; (* MenuDisable: LongPtr; { Low-memory global }*) gSystem: tSystem; {**************************************************} { Constants} {} { Constants used in the THINK Class Library} {} {**************************************************} const STRcommon = 128; { STR# resource ID for commonly } { used strings } strQUITTING = 1; strCLOSING = 2; strUNDO = 3; strREDO = 4; strUNTITLED = 5; strSHOWCLIP = 6; strHIDECLIP = 7; STRmemWarn = 129; { Strings for low memory warnings } iMEM_LOW = 1; MBARapp = 1; { Menu Bar Resource ID } MINIMUM_BALANCE = 2048; { Minimum memory reserve } CMD_DELIMITER = '#'; { Separates menu item name from cmd no. } DEFAULT_DIM = dimALL; { Default DimOption for menus } WIND_CLIPBOARD = 200; { Clipboard window resource ID } { Button Numbers in Alerts } answerYES = 1; answerNO = 2; answerCANCEL = 3; DRAG_MARGIN = 4; { Margin around desktop when } { dragging a window } REASONABLY_CLOSE = 5; { How close two points must be to } { be part of a multi-click on } { the Desktop } { CDecorator Parameters } MAX_WOFFSETS = 5; { Max depth of offsetting windows } LEFT_SMARGIN = 4; { Margin at left of screen } TOP_SMARGIN = 22; { Margin at top of screen } RIGHT_SMARGIN = 4; { Margin at right of screen } BOTTOM_SMARGIN = 4; { Margin at bottom of screen } HORIZ_WOFFSET = 8; { Horizontal window offset } VERT_WOFFSET = 16; { Vertical window offset } STRprompt = 150; { STR resource ID of prompt string } { when doing a SaveAs } ALRTrevert = 150; { Alert to confirm revert to saved } ALRTsaveChanges = 151; { Save changes before close/quit } STRtaskNames = 130; { STR# resource ID for task names } ALRTgeneral = 128; { Generic Alert box } ALRTsevereErr = 200; { Alert box for a Severe Error } ALRTosError = 300; { Alert box for a Mac OS Error } ALRT_NOPRINTER = 250; { Alert when there is no printer } STRosError = 300; { Generic Mac OS error message } ErrMsg_Res = 'Estr'; { Resource type for list of error } { message string corresponding } { to Mac OS Errors/result codes } STR_TCLfailMsgs = 131; { STR# resource ID for failure } { messages for TCL } kUserFailMsgBase = 1024; { programmer defined failure msgs } { are specified from a base value } { of 1024 } STRdlgValidation = 133; { STR# resource ID for dialog } { validation errors } ALRTvalidation = 129; { Alert box for dialog validation } ALRT_Exception = 251; { Alert used by exception handler } ALRT_ExceptionAbort = 252; { Exception alert used when aborting app } STRosError2 = 301; { ErrorAlert's Mac OS error message} CNTL_SBAR = 300; { CNTL Resource ID of a scroll bar } PAGE_DELAY = 10; { Ticks to delay during continuous } { page scrolling } SIZEBOX_LENGTH = 16; { Length of a size box in pixels } SICN_SIZEBOX = 200; { SICN Resource ID for size box } MIN_WSIZE = 100; { Minimum size of a window } SBARSIZE = 16; { Size of a scroll bar in pixels } SBARSIZE1 = 15; { SBARSIZE - 1 } OBJ_WINDOW_KIND = 1001; { windowKind for a Mac window } { associated with a CWindow object } pascalKind = 32700; { THINK Pascal's windows have a } { windowKind >= 32700 } kDefaultHelpResID = 128; { default ID for 'hrct' help balloon resource } TCL_SICN = 200; { resource ID for SICN used by TCL } POPUP_SICN = 2; { index into SICN 200 for popup arrow } STD_PAGE_WIDTH = 576; { Default pixel width of a page } STD_PAGE_HEIGHT = 720; { Default pixel height of a page } SYS_FONT_SIZE = 12; { Size of System font } CARRIAGE_RETURN = chr(13); { Character code } KeyHome = $73; { Key code for Home key } KeyEnd = $77; { Key code for End key } KeyPageUp = $74; { Key code for Page Up key } KeyPageDown = $79; { Key code for Page Down key } kEnterKey = chr(3); { ASCII code for Enter key } kBackspaceKey = chr(8); kTabKey = chr(9); kReturnKey = chr(13); kEscapeOrClear = chr($1B); { ASCII code for both Escape and Clear keys } kLeftCursor = chr(28); kRightCursor = chr(29); kUpCursor = chr(30); kDownCursor = chr(31); KeyEscape = $35; { Key code for Escape key } KeyClear = $47; { Key code for Clear key } KeyHelp = $72; { Key code for Help key } KeyFwdDelete = $75; { Key code for Forward Delete } KeyLeftCursor = $7B; { Key code for cursor left } KeyRightCursor = $7C; { Key code for cursor right } KeyUpCursor = $7E; { Key code for cursor up } KeyDownCursor = $7D; { Key code for cursor down } KeyF1 = $7A; { Key code for F1 } KeyF2 = $78; { Key code for F2 } KeyF3 = $63; { Key code for F3 } KeyF4 = $76; { Key code for F4 } KeyF5 = $60; { Key code for F5 } KeyF6 = $61; { Key code for F6 } KeyF7 = $62; { Key code for F7 } KeyF8 = $64; { Key code for F8 } KeyF9 = $65; { Key code for F9 } KeyF10 = $6D; { Key code for F10 } KeyF11 = $67; { Key code for F11 } KeyF12 = $6F; { Key code for F12 } KeyF13 = $69; { Key code for F13 } KeyF14 = $6B; { Key code for F14 } KeyF15 = $71; { Key code for F15 } {*** M E N U S ***} MENUapple = 1; { Apple menu with DAs, etc. } MENUfile = 2; { File menu with New, Open, etc. } MENUedit = 3; { Edit menu with Cut, Copy, etc. } MENUfont = 10; { Menu of installed fonts } MENUsize = 11; { Menu of font sizes } MENUstyle = 12; { Menu of font styles } {**************************************************} { Commands} {} { Commands recognized by the THINK Class Library } {} { Command numbers 0 through 1023 are reserved for use by the TCL. } {} {**************************************************} const cmdNull = 0; { Command which does nothing } cmdOK = 100; { OK button in dialog box } cmdCancel = 101; { Cancel button in dialog box } cmdAbout = 256; { About Application request } { Standard File Menu commands } cmdQuit = 1; cmdNew = 2; cmdOpen = 3; cmdClose = 4; cmdSave = 5; cmdSaveAs = 6; cmdRevert = 7; cmdPageSetup = 8; cmdPrint = 9; { Standard Edit Menu commands } cmdUndo = 16; cmdCut = 18; cmdCopy = 19; cmdPaste = 20; cmdClear = 21; cmdToggleClip = 22; { Show or Hide the Clipboard window } cmdSelectAll = 23; { Text Styles } cmdPlain = 30; cmdBold = 31; cmdItalic = 32; cmdUnderline = 33; cmdOutline = 34; cmdShadow = 35; cmdCondense = 36; cmdExtend = 37; { Text Alignment } cmdAlignRight = 40; cmdAlignLeft = 41; cmdAlignCenter = 42; cmdJustify = 43; { Line Spacing } cmdSingleSpace = 50; cmd1HalfSpace = 51; cmdDoubleSpace = 52; {****************************************************************************} { Exceptions } {****************************************************************************} {****************************************************************************} { LongCoordinates} {****************************************************************************} type LongPt = record case INTEGER of 1: ( v: Longint; h: Longint ); 2: ( vh: array[VHSelect] of Longint ); end; LongPtPtr = ^LongPt; LongRect = record case INTEGER of 1: ( top: Longint; left: Longint; bottom: Longint; right: Longint ); 2: ( topLeft: LongPt; botRight: LongPt ); end; LongRectPtr = ^LongRect; procedure QDToLongPt (srcPt: Point; var destPt: LongPt); procedure LongToQDPt (srcPt: LongPt; var destPt: Point); procedure SetLongPt (var pt: LongPt; h: Longint; v: Longint); procedure AddLongPt (srcPt: LongPt; var destPt: LongPt); procedure SubLongPt (srcPt: LongPt; var destPt: LongPt); function EqualLongPt (pt1: LongPt; pt2: LongPt): Boolean; function PtInQDSpace (pt: LongPt): Boolean; procedure QDToLongRect (srcRect: Rect; var destRect: LongRect); procedure LongToQDRect (srcRect: LongRect; var destRect: Rect); procedure SetLongRect (var r: LongRect; left: Longint; top: Longint; right: Longint; bottom: Longint); procedure OffsetLongRect (var r: LongRect; dh: Longint; dv: Longint); procedure InsetLongRect (var r: LongRect; dh: Longint; dv: Longint); function SectLongRect (src1: LongRect; src2: LongRect; var destRect: LongRect): Boolean; procedure UnionLongRect (src1: LongRect; src2: LongRect; var destRect: LongRect); function PtInLongRect (pt: LongPt; r: LongRect): Boolean; procedure Pt2LongRect (pt1: LongPt; pt2: LongPt; var r: LongRect); function EqualLongRect (r1: LongRect; r2: LongRect): Boolean; function EmptyLongRect (r: LongRect): Boolean; function RectInQDSpace (r: LongRect): Boolean; {****************************************************************************} { CObject} {} {} { TCL 1.1 CHANGES} { [} { - Declare Lock method} { ]} {****************************************************************************} type CObject = object procedure Free; function Clone: CObject; { TCL 1.1.1 DLP 9/25/91 } function Lock (fLock: Boolean): Boolean; procedure SubclassResponsibility; procedure GetClassName (var className: Str255); end; {****************************************************************************} { TCLUtilities } {****************************************************************************} function AbortInQueue: Boolean; function IsCancelEvent (VAR theEvent: EventRecord): Boolean; procedure ErrorAlert (error: Integer; message: Longint); function NewHandleCanFail (size: Longint): Handle; procedure ResizeHandleCanFail (theHandle: univ Handle; newSize: Longint); function SetAllocation (canFail: Boolean): Boolean; procedure SetCriticalOperation (aCriticalOp: Boolean); procedure ForgetHandle (var h: univ Handle); procedure ForgetObject (var obj: univ CObject); procedure ForgetPtr (var p: univ Ptr); procedure ForgetResource (var res: univ Handle); procedure SetMinimumStack (minSize: Longint); function EqualMem (p1, p2: univ Ptr; len: Longint): Boolean; const { mnemonic constants for SetAllocation flag } kAllocCantFail = FALSE; kAllocCanFail = TRUE; {****************************************************************************} { CBartender} {} {} { TCL 1.1 CHANGES} { [} { - added EnableMenuBar and DisableMenuBar methods} { - added UpdateMenuBar method} { - added inMenuBar flag to MenuEntry, to indicate whether the} { menu is currently installed in the menu bar.} { - added lastEnable flag to MenuEntry, to indicate the last} { seen enable state for a menu.} { - added forceMBarUpdate instance variable.} { - merged CBartender with CBarOwner. CBartender gained a choreAssigned} { instance variable.} { ]} {} {****************************************************************************} type MenuEntry = record MENUid: Integer; macMenu: MenuHandle; dimming: DimOption; numCmds: Integer; unchecking: Boolean; hasHMenus: Boolean; inMenuBar: Boolean; lastEnable: Boolean; theCommands: LongArrayH; end; const xMenuEntries = (maxint div sizeof(MenuEntry)) - 1; { Used in definition of } { MenuArray type (below) } type MenuArrayP = ^MenuArray; MenuArrayH = ^MenuArrayP; MenuArray = array[0..xMenuEntries] of MenuEntry; type CBartender = object(CObject) numMenus: Integer; theMenus: MenuArrayH; choreAssigned: Boolean; forceMBarUpdate: Boolean; procedure IBartender (MBARid: Integer); procedure AddMenu (MENUid: Integer; install: Boolean; beforeID: Integer); procedure RemoveMenu (MENUid: Integer); procedure InsertInBar (MENUid: Integer; beforeID: Integer); procedure DeleteFromBar (MENUid: Integer); procedure InsertHierMenu (hMENUid: Integer; cmdNo: Longint; inMENUid: Integer; afterItem: Integer); procedure EnableCmd (cmdNo: Longint); procedure DisableCmd (cmdNo: Longint); procedure EnableMenu (MENUid: Integer); procedure DisableMenu (MENUid: Integer); procedure EnableMenuBar; procedure DisableMenuBar; procedure SetCmdText (cmdNo: Longint; theText: Str255); procedure GetCmdText (cmdNo: Longint; var theText: Str255); procedure CheckMarkCmd (cmdNo: Longint; checked: Boolean); procedure InsertMenuCmd (cmdNo: Longint; theText: Str255; MENUid: Integer; afterItem: Integer); procedure RemoveMenuCmd (cmdNo: Longint); function FindMenuIndex (MENUid: Integer): Integer; function FindMacMenu (MENUid: Integer): MenuHandle; function FindCmdNumber (MENUid: Integer; itemNo: Integer): Longint; procedure FindMenuItem (cmdNo: Longint; var MENUid: Integer; var macMenu: MenuHandle; var itemNo: Integer); function FindItemText (MENUid: Integer; itemStr: Str255): Integer; procedure ExtractCommands (var theEntry: MenuEntry); procedure ParseItemString (var itemStr: Str255; var cmdNo: Longint); procedure ExtractHierMenus (macMenu: MenuHandle; index: Integer); procedure SetDimOption (MENUid: Integer; aDimming: DimOption); procedure SetUnchecking (MENUid: Integer; anUnchecking: Boolean); procedure UpdateAllMenus; procedure UpdateMenuBar; end; {****************************************************************************} { CAppleEvent} {****************************************************************************} type CAppleEvent = object(CObject) theEvent: AppleEvent; theReply: AppleEvent; theRefCon: Longint; eventClass: DescType; eventID: DescType; canInteract: Boolean; errCode: Integer; notificationRec: NMRecPtr; idleProc: Ptr; procedure IAppleEvent (VAR aeEvent: AppleEvent; VAR aeReply: AppleEvent; aeRefCon: Longint; aeEventClass: DescType; aeEventID: DescType); function GetEventClass: DescType; function GetEventID: DescType; function GetAEEvent: AppleEvent; function GetAEReply: AppleEvent; function GetAERefCon: Longint; procedure GetDescList (whichParam: AEKeyword; var descList: AEDescList); function ExtractFromDescList (whichParam: AEKeyword; itemType: DescType; itemSize: Size): CArray; function GotRequiredParams: Boolean; function RequestInteraction (timeOutTicks: Longint): Integer; procedure SetErrorResult (anErrorCode: Integer); function GetErrorResult: Integer; end; {****************************************************************************} { CCollaborator} {****************************************************************************} type CCollaborator = object(CObject) itsProviders: CList; itsDependents: CList; procedure ICollaborator; procedure DependUpon (aProvider: CCollaborator); procedure CancelDependency (aProvider: CCollaborator); procedure Free; OVERRIDE; procedure BroadcastChange (reason: Longint; info: univ Ptr); procedure ProviderChanged (aProvider: CCollaborator; reason: Longint; info: univ Ptr); procedure AddDependent (aDependent: CCollaborator); procedure RemoveDependent (aDependent: CCollaborator); procedure AddProvider (aProvider: CCollaborator); procedure RemoveProvider (aProvider: CCollaborator); end; {****************************************************************************} { CCollection} {} { TCL 1.1 CHANGES} { [} { - CCollection is now a subclass of CCollaborator} { ]} {} {****************************************************************************} type CCollection = object(CCollaborator) numItems: Longint; procedure ICollection; function GetNumItems: Longint; function IsEmpty: Boolean; end; {****************************************************************************} { CArray} {****************************************************************************} type CArray = object(CCollection) blockSize: Integer; { Number of slots to allocate when } { more space is needed } slots: Longint; { Total number of slots allocated } hItems: Handle; { Items in the array } elementSize: Longint; { size of each element in bytes } lockChanges: Boolean; { can't insert or delete if locked } usingTemporary: Boolean; { TRUE if temporary element storage} { buffer is in use } procedure IArray (anElementSize: Longint); procedure Free; OVERRIDE; procedure SetBlockSize (aBlockSize: Integer); procedure InsertAtIndex (itemPtr: univ Ptr; index: Longint); procedure DeleteItem (index: Longint); procedure MoveItemToIndex (currentIndex: Longint; newIndex: Longint); procedure SetItem (itemPtr: univ Ptr; index: Longint); procedure GetItem (itemPtr: univ Ptr; index: Longint); procedure Swap (index1: Longint; index2: Longint); function Search (itemPtr: univ Ptr; function compare (item1, item2: univ Ptr): Boolean): Longint; function SetLockChanges (fLockChanges: Boolean): Boolean; procedure Resize (numSlots: Longint); procedure MoreSlots; procedure CopyToTemporary (index: Longint); procedure CopyFromTemporary (index: Longint); function ItemOffset (itemIndex: Longint): Longint; { PRIVATE } procedure AssertIndex (index: Longint); function GetItemPtr (index: Longint): Ptr; procedure Store (itemPtr: univ Ptr; index: Longint); procedure Retrieve (itemPtr: univ Ptr; index: Longint); function Clone: CObject; { TCL 1.1.1 DLP 9/25/91 } OVERRIDE; end; { A pointer to a tMovedElementInfo structure is passed as the info } { parameter to BroadCastChange when MoveItemToIndex has completed } type tMovedElementInfo = record originalIndex: Longint; { item's original index } newIndex: Longint; { item's new index } end; tMovedElementInfoPtr = ^tMovedElementInfo; { Change protocol for Array class } const { index of new element } arrayInsertElement = 1; { index of new element } arrayDeleteElement = 2; { index of deleted element } arrayMoveElement = 3; { pointer to tMovedElementInfo, see above } arrayElementChanged = 4; { index of changed element } arrayLastChange = arrayElementChanged; BAD_INDEX = -1; { Flag indicating a failed search } {****************************************************************************} { CRunArray} {} {****************************************************************************} { structure used to store run info } type tRun = record runLength: Longint; { number of consecutive entries with same value } value: Longint; { the value } end; const xRuns = (maxint div sizeof(tRun)) - 1; type tRunArray = array[0..xRuns] of tRun; tRunPtr = ^tRunArray; tRunHndl = ^tRunPtr; type CRunArray = object(CArray) itemCount: Longint; { number of values in array - numItems is number of runs } hRuns: tRunHndl; { handle to runs, same as CArray.hItems } procedure IRunArray; procedure InsertValue (item, value, count: Longint); procedure SetValue (index, value: Longint); function GetValue (index: Longint): Longint; procedure DeleteValue (index: Longint); procedure DeleteAll; function SumRange (startIndex, endIndex: Longint): Longint; function FindSum (aSum: Longint): Longint; function GetNumItems: Longint; OVERRIDE; procedure FindRun (itemIndex: Longint; var runIndex, firstInRun: Longint); procedure InsertRun (index, runLength, value: Longint); procedure DeleteRun (runIndex: Longint); function Clone: CObject; { TCL 1.1.1 DLP 9/25/91 } OVERRIDE; end; { change protocol } {) { * CRunArray will send its dependents the runArraySizeChanged} { * change message when InsertValue, DeleteValue, or DeleteAll} { * methods are called. Since it is a subclass of CArray, it } { * may also send CArray change messages, but those signal} { * changes in the runs, not in the elements themselves, and} { * will not usually be of interest to dependents.} { } const { info parameter is pointer to new size } runArraySizeChanged = arrayLastChange + 1; runArrayLastChange = runArraySizeChanged; {****************************************************************************} { CCluster} {} { TCL 1.1 CHANGES} { [} { - CCluster is now a subclass of CArray. CArray already has} { the instance variables blockSize and slots, so} { these are removed from CCluster's declaration. CArray also} { has an items handle, but it is declared as a handle instead} { of LongHandle. For backward compatibility, the items instance} { variable is maintained, but as an alias to CArray's handle.} { This also lets certain operations be implemented more efficiently.} { - The Free, MoreSlots, and SetBlockSize methods have been} { removed because they are now implemented by CArray.} { - moved BAD_INDEX constant to CArray} { - override of Clone} { ]} {} {****************************************************************************} const SLOT_SIZE = 4; { Size of an item in a cluster } type ObjArrayP = ^ObjArray; ObjArrayH = ^ObjArrayP; ObjArray = array[0..xLongs] of CObject; CCluster = object(CArray) items: ObjArrayH; procedure ICluster; procedure DisposeAll; procedure DisposeItems; procedure Add (theObject: CObject); procedure Remove (theObject: CObject); function Includes (theObject: CObject): Boolean; procedure DoForEach (procedure proc (theObject: CObject)); procedure DoForEach1 (procedure proc (theObject: CObject; theParam: univ Ptr); param: univ Ptr); function FindItem (function testFunc (theObject: CObject): Boolean): CObject; function FindItem1 (function testFunc (theObject: CObject; theParam: univ Ptr): Boolean; param: univ Ptr): CObject; function Offset (theObject: CObject): Longint; function Clone: CObject; { TCL 1.1.1 DLP 9/25/91 } OVERRIDE; end; {****************************************************************************} { CList} {} { TCL 1.1 CHANGES} { [} { - CList is now a subclass of CArray (via CCluster).} { - The Remove method was removed because it is already implemented} { in CCluster} { ]} {} {****************************************************************************} type CList = object(CCluster) { Instance Methods } procedure IList; procedure Append (theObject: CObject); procedure Prepend (theObject: CObject); procedure InsertAfter (theObject: CObject; afterObject: CObject); procedure InsertAt (theObject: CObject; index: longint); procedure BringFront (theObject: CObject); procedure SendBack (theObject: CObject); procedure MoveUp (theObject: CObject); procedure MoveDown (theObject: CObject); procedure MoveToIndex (theObject: CObject; index: longint); function FirstItem: CObject; function LastItem: CObject; function NthItem (n: longint): CObject; function FindIndex (theObject: CObject): longint; function FirstSuccess (function testFunc (theObject: CObject): boolean): CObject; function FirstSuccess1 (function testFunc (theObject: CObject; theParam: univ Ptr): boolean; param: univ Ptr): CObject; function LastSuccess (function testFunc (theObject: CObject): boolean): CObject; function LastSuccess1 (function testFunc (theObject: CObject; theParam: univ Ptr): boolean; param: univ Ptr): CObject; end; { Change protocol for List class } { This is just a redeclaration of the same protocol as CArray } { redefined as "list" constants because lists are used so frequently } { reason parameter } const { index of new element } listInsertElement = 1; { index of new element } listDeleteElement = 2; { index of deleted element } listMoveElement = 3; { pointer to tMovedElementInfo, see above } listElementChanged = 4; { index of changed element } listLastChange = listElementChanged; {****************************************************************************} { CChore} {} {****************************************************************************} type CChore = object(CObject) procedure Perform (var maxSleep: Longint); end; {****************************************************************************} { CMBarChore} {} {****************************************************************************} type CMBarChore = object(CChore) procedure Perform (var maxSleep: Longint); OVERRIDE; end; {****************************************************************************} { CEnvironment} {} {****************************************************************************} type CEnvironment = object(CObject) procedure Restore; end; {****************************************************************************} { CError} {} {****************************************************************************} type CError = object(CObject) procedure SevereMacError (macErr: Integer); function CheckOSError (macErr: Integer): Boolean; procedure PostAlert (STRid: Integer; index: Integer); procedure MissingResources; end; {****************************************************************************} { CDecorator} {} { TCL 1.1 CHANGES} { [} { - added StaggerWindow method} { ]} {} {****************************************************************************} type CDecorator = object(CObject) wCount: Integer; index: Integer; wWidth: Integer; wHeight: Integer; hLocation: Integer; vLocation: Integer; procedure IDecorator; procedure PlaceNewWindow (theWindow: CWindow); procedure StaggerWindow (theWindow: CWindow); procedure CenterWindow (theWindow: CWindow); function GetWCount: Integer; end; {****************************************************************************} { CPrinter} {} {} { TCL 1.1 CHANGES} { [} { - added printMgrOpen, printDocOpen, printPageOpen, savedResFile,} { printDirection instance variables} { - changed interface for OpenPrintMgr} { - added ClosePrintMgr, SetPrintDir, HavePagination, ResetPagination,} { SetStrips, SetHorizPageBreak, SetVertPageBreak, SetAllStripWidths,} { SetStripHeight, SetAllStripHeights, GetStripCount, PageNumToStrips,} { GetPageStart, GetPageArea methods} { ] } {} {****************************************************************************} const kUsePaperWidth = -1; kUsePaperHeight = -1; type tPrintDirection = ( printHoriz, { printing proceeds row by row } printVert { printing proceeds column by column } ); CPrinter = object(CObject) itsDocument: CDocument; macTPrint: Handle; macPrintPort: GrafPtr; printDirection: tPrintDirection; printMgrOpen: Boolean; printDocOpen: Boolean; printPageOpen: Boolean; savedResFile: Integer; itsStripWidths: CRunArray; itsStripHeights: CRunArray; function IPrinter (aDocument: CDocument; aMacTPrint: Handle): Boolean; procedure Free; OVERRIDE; function OpenPrintMgr (fCheckFailure: Boolean): Boolean; procedure ClosePrintMgr; function GetPrintRecord: Handle; procedure GetPageInfo (var paperRect: Rect; var pageRect: Rect; var hRes: Integer; var vRes: Integer); function DoPageSetup: Boolean; procedure SetPrintDir (aPrintDir: tPrintDirection); function HavePagination: Boolean; procedure ResetPagination; procedure SetStrips (numHStrips, numVStrips: Integer); procedure SetHorizPageBreak (vStripNum: Integer; hPos: Longint); procedure SetVertPageBreak (hStripNum: Integer; vPos: Longint); procedure SetAllStripWidths (aStripWidth: Integer); procedure SetStripWidth (pageNum: Integer; aStripWidth: Integer); procedure SetAllStripHeights (aStripHeight: Integer); procedure SetStripHeight (pageNum: Integer; aStripHeight: Integer); procedure GetStripCount (var hStrips: Integer; var vStrips: Integer); procedure PageNumToStrips (pageNum: Integer; var hStrip: Integer; var vStrip: Integer); procedure GetPageStart (pageNum: Integer; var startPos: LongPt); procedure GetPageArea (pageNum: Integer; var pageArea: LongRect); procedure DoPrint; procedure PrintPageRange (firstPage: Integer; lastPage: Integer); end; {****************************************************************************} { CPaneBorder} {} {****************************************************************************} const kBorderNone = $00; kBorderLeft = $01; kBorderTop = $02; kBorderRight = $04; kBorderBottom = $08; kBorderFrame = kBorderLeft + kBorderTop + kBorderRight + kBorderBottom; kBorderOval = $10; kBorderRoundRect = $20; kBorderRsrv1 = $40; kBorderRsrv2 = $80; kPaneBorderRes = 'PBrd'; { CPaneBorder resource type } type CPaneBorder = object(CObject) borderFlags: Longint; { describes the type of border } borderPen: Point; { pen size for border } shadowOffset: Point; { amount to offset for shadow } shadowPen: Point; { pen size for shadow } doShadow: Boolean; { TRUE if shadow is drawn } roundDiameter: Point; { oval width and height for rounded rectangle } penPattern: Pattern; { pattern for border } margin: Rect; { minimum whitespace desired } procedure IPaneBorder (aBorderFlags: Longint); procedure IResPaneBorder (resID: Integer); procedure SetPattern (aPattern: Pattern); procedure GetPattern (var aPattern: Pattern); procedure SetBorderFlags (aBorderFlags: Longint); function GetBorderFlags: Longint; procedure SetPenSize (penWidth: Integer; penHeight: Integer); procedure GetPenSize (var penWidth: Integer; var penHeight: Integer); procedure SetShadow (hOffset: Integer; vOffset: Integer; width: Integer; height: Integer); procedure GetShadow (var hOffset: Integer; var vOffset: Integer; var width: Integer; var height: Integer); procedure SetRounding (hDiameter: Integer; vDiameter: Integer); procedure GetRounding (var hDiameter: Integer; var vDiameter: Integer); procedure SetMargin (aMargin: Rect); procedure GetMargin (var aMargin: Rect); procedure CalcBorderRect (var paneFrame: Rect); procedure DrawBorder (paneFrame: Rect); end; { CPaneBorder resource template } PaneBorderTemp = record borderFlags: Longint; borderPen: Point; shadowOffset: Point; shadowPen: Point; roundDiameter: Point; patID: Integer; margin: Rect; end; PaneBorderTempPtr = ^PaneBorderTemp; PaneBorderTempHndl = ^PaneBorderTempPtr; {****************************************************************************} { CSwitchboard} { } { TCL 1.1 CHANGES} { [} { - added GetAnEvent, DispatchEvent, DoHighLevelEvent, DoAppleEvent methods} { ]} {} {****************************************************************************} type CSwitchboard = object(CObject) mouseRgn: RgnHandle; procedure ISwitchboard; procedure DoMouseDown (VAR macEvent: EventRecord); procedure DoMouseUp (VAR macEvent: EventRecord); procedure DoKeyEvent (VAR macEvent: EventRecord); procedure DoDiskEvent (VAR macEvent: EventRecord); procedure DoUpdate (VAR macEvent: EventRecord); procedure DoActivate (VAR macEvent: EventRecord); procedure DoDeactivate (VAR macEvent: EventRecord); procedure DoSuspend (VAR macEvent: EventRecord); procedure DoResume (VAR macEvent: EventRecord); procedure DoOtherEvent (VAR macEvent: EventRecord); procedure DoIdle (VAR macEvent: EventRecord); procedure ProcessEvent; function GetAnEvent (var macEvent: EventRecord): Boolean; procedure DispatchEvent (VAR macEvent: EventRecord); procedure DoHighLevelEvent (VAR macEvent: EventRecord); function DoAppleEvent (VAR theEvent: AppleEvent; VAR theReply: AppleEvent; refCon: Longint): Integer; function AppleEventIdle (VAR macEvent: EventRecord; sleepTime: Longint; mouseRgn: RgnHandle): Boolean; end; {****************************************************************************} { CTask} {} { TCL 1.1 CHANGES} { [} { - added undone instance variable and IsUndone method.} { ]} {} {****************************************************************************} type CTask = object(CObject) nameIndex: Integer; { Index for name in string list } undone: Boolean; procedure ITask (aNameIndex: Integer); function GetNameIndex: Integer; procedure DoTask; procedure Undo; procedure Redo; function IsUndone: Boolean; end; {****************************************************************************} { CMouseTask} {****************************************************************************} type CMouseTask = object(CTask) procedure IMouseTask (aNameIndex: Integer); procedure BeginTracking (var startPt: LongPt); procedure KeepTracking (var currPt, prevPt, startPt: LongPt); procedure EndTracking (var currPt, prevPt, startPt: LongPt); end; {****************************************************************************} { CBureaucrat} {} { TCL 1.1 CHANGES} { [} { - added BecomeGopher method} { - changed superclass to CCollaborator} { - added override of BroadcastChange, ProviderChanged} { - added DoAppleEvent method} { ]} {} {****************************************************************************} type CBureaucrat = object(CCollaborator) itsSupervisor: CBureaucrat; procedure IBureaucrat (aSupervisor: CBureaucrat); procedure Free; OVERRIDE; function GetSupervisor: CBureaucrat; procedure Notify (theTask: CTask); procedure DoKeyDown (theChar: Char; keyCode: Byte; VAR macEvent: EventRecord); procedure DoAutoKey (theChar: Char; keyCode: Byte; VAR macEvent: EventRecord); procedure DoKeyUp (theChar: Char; keyCode: Byte; VAR macEvent: EventRecord); procedure DoCommand (theCommand: Longint); procedure Dawdle (var maxSleep: Longint); procedure UpdateMenus; function BecomeGopher (fBecoming: Boolean): Boolean; procedure BroadcastChange (reason: Longint; info: univ Ptr); OVERRIDE; procedure ProviderChanged (aProvider: CCollaborator; reason: Longint; info: univ Ptr); OVERRIDE; procedure DoAppleEvent (anAppleEvent: CAppleEvent); end; { Change propagation constants for CBureacrat } const { bureaucrat has become the gopher, info parameter is zero } bureaucratIsGopher = 1; { bureaucrat is no longer the gopher, info parameter is zero } bureaucratIsNotGopher = 2; bureaucratLastChange = bureaucratIsNotGopher; {****************************************************************************} { CDirectorOwner} {} { Interface for CDirectorOwner class} {} { SUPERCLASS = CBureacrat} {} { Copyright © 1991 Symantec Corporation. All rights reserved.} {} {} {****************************************************************************} type CDirectorOwner = object(CBureaucrat) itsDirectors: CList; { list of its directors} active: Boolean; { TRUE if any director is active} procedure IDirectorOwner (aSupervisor: CDirectorOwner); procedure AddDirector (aDirector: CDirector); procedure RemoveDirector (aDirector: CDirector); procedure ActivateDirector (aDirector: CDirector); procedure DeactivateDirector (aDirector: CDirector); procedure Suspend; procedure Resume; function Quit: Boolean; function Close (quitting: Boolean): Boolean; procedure Free; OVERRIDE; end; {****************************************************************************} { CApplication} {} { TCL 1.1 CHANGES} { [} { - added MakeSwitchBoard, MakeBartender, and MakeError methods} { - removed eventLoopJump instance variable} { - added Process1Event, PackageAppleEvent, DoAppleEvent method} { - added phase instance variable, phase enumeration constants,} { and GetPhase methods. The application is always in one of three} { phases: initializing, running, or quitting.} { - added class variable cMaxSleepTime, which determines the default} { maximum sleep time passed to WaitNextEvent} { - changed interface for IApplication, InitMemory, and RequestMemory methods} { - added SetCriticalOperation method} { - removed instance variables loanApproved and creditLimit} { - added instance variables criticalBalance, toolboxBalance,} { and tempAllocation.} { - added methods InstallPatches, RemovePatches, ForceClassReferences} { ]} {} {****************************************************************************} const { phases of application execution, return by GetPhase() method } appInitializing = 1; appRunning = 2; appQuitting = 3; GROW_FAILURE = 0; GROW_SUCCESS = 1; type CApplication = object(CDirectorOwner) itsSwitchboard: CSwitchboard; { Retrieves and processes events } itsIdleChores: CList; { Chores to perform at idle time } itsUrgentChores: CCluster; { Chores to perform ASAP } urgentsToDo: Boolean; { Are any urgent chores pending? } running: Boolean; { Status flag } phase: Integer; { what phase is the application in? } rainyDayFund: Longint; { Bytes of memory to set aside } criticalBalance: Longint; { bytes to save for critical operations } toolboxBalance: Longint; { bytes to save for the toolbox } tempAllocation: Longint; { bytes of temporarily allocate mem } rainyDay: Handle; { Handle to the reserve memory } rainyDayUsed: Boolean; { Has rainy day fund been tapped? } memWarningIssued: Boolean; { Has user been alerted? } canFail: Boolean; { OK for memory request to fail? } inCriticalOperation: Boolean; { OK to use critical memory reserve? } sfNumTypes: Integer; { Number of file types recognized } sfFileTypes: SFTypeList; { File types which are recognized } sfFileFilter: FileFilterUPP; { Filter for files to display } sfGetDLOGHook: DlgHookUPP; { Hook for handling get dialog } sfGetDLOGid: Integer; { Dialog resource ID for get file } sfGetDLOGFilter: ModalFilterUPP; { Filter for get dialog events } unhandledTask: CTask; { Task that no document handled } procedure IApplication (extraMasters: Integer; aRainyDayFund: Longint; aCriticalBalance: Longint; aToolboxBalance: Longint); procedure InitToolbox; procedure InitMemory (extraMasters: Integer; aRainyDayFund: Longint; aCriticalBalance: Longint; aToolboxBalance: Longint); procedure InstallPatches; procedure RemovePatches; procedure InspectSystem; procedure MakeDesktop; procedure MakeClipboard; procedure MakeDecorator; procedure MakeSwitchboard; procedure MakeBartender; procedure MakeError; procedure SetUpFileParameters; procedure SetUpMenus; procedure ForceClassReferences; procedure Notify (theTask: CTask); OVERRIDE; procedure DoKeyDown (theChar: Char; keyCode: Byte; VAR macEvent: EventRecord); OVERRIDE; procedure DoAutoKey (theChar: Char; keyCode: Byte; VAR macEvent: EventRecord); OVERRIDE; procedure DoKeyUp (theChar: Char; keyCode: Byte; VAR macEvent: EventRecord); OVERRIDE; procedure DoCommand (theCommand: Longint); OVERRIDE; procedure UpdateMenus; OVERRIDE; function PackageAppleEvent (VAR theEvent: AppleEvent; VAR theReply: AppleEvent; theRefCon: Longint; eventClass: DescType; eventID: DescType): CAppleEvent; procedure DoAppleEvent (anAppleEvent: CAppleEvent); OVERRIDE; procedure RequestMemory (aCanFail: Boolean); procedure SetCriticalOperation (fInCriticalOperation: Boolean); function GrowMemory (bytesNeeded: Longint): Longint; procedure MemoryShortage (bytesNeeded: Longint); procedure MemoryReplenished; function OutOfMemory (bytesNeeded: Longint): Longint; procedure Run; procedure Process1Event; procedure Preload; procedure StartUpAction (numPreloads: Integer); procedure Suspend; OVERRIDE; procedure Resume; OVERRIDE; procedure SwitchToDA; procedure SwitchFromDA; procedure Idle (VAR macEvent: EventRecord); function Quit: Boolean; OVERRIDE; procedure ExitApp; procedure JumpToEventLoop; function GetPhase: Integer; procedure CreateDocument; procedure OpenDocument (macSFReply: SFReply); procedure DoOpenOrPrintDocEvent (theEvent: CAppleEvent); procedure ChooseFile (var macSFReply: SFReply); procedure AssignIdleChore (theChore: CChore); procedure CancelIdleChore (theChore: CChore); procedure AssignUrgentChore (theChore: CChore); end; { utility routines defined for the benefit of the Exceptions library } procedure ExitApplication; function ApplicationIsRunning: Boolean; var cMaxSleepTime: Longint; {****************************************************************************} { CDirector} {} { TCL 1.1 CHANGES} { [} { - added GetWindow, FindViewByID methods} { - added override of ProviderChanged} { - added activateWindOnResume instance variable} { ]} {} {****************************************************************************} type CDirector = object(CDirectorOwner) itsWindow: CWindow; itsGopher: CBureaucrat; activateWindOnResume: Boolean; { TCL 1.1.1 DLP 9/25/91 } alreadyClosing: Boolean; { TRUE while attempting to Close } { the director } procedure IDirector (aSupervisor: CDirectorOwner); procedure Free; OVERRIDE; procedure DoCommand (theCommand: Longint); OVERRIDE; procedure UpdateMenus; OVERRIDE; procedure Activate; procedure Deactivate; procedure Suspend; OVERRIDE; procedure Resume; OVERRIDE; function Close (quitting: Boolean): Boolean; OVERRIDE; procedure CloseWind (theWindow: CWindow); procedure ActivateWind (theWindow: CWindow); procedure DeactivateWind (theWindow: CWindow); function IsActive: Boolean; procedure ActivateDirector (aDirector: CDirector); OVERRIDE; procedure DeactivateDirector (aDirector: CDirector); OVERRIDE; function OwnsWindow (aWindow: CWindow): Boolean; function GetWindow: CWindow; function FindViewByID (aViewID: Longint): CView; procedure ProviderChanged (aProvider: CCollaborator; reason: Longint; info: univ Ptr); OVERRIDE; procedure RemoveDirector (aDirector: CDirector); OVERRIDE; end; { symbolic constants for Boolean parameters} const kNotQuitting = FALSE; kQuitting = TRUE; {****************************************************************************} { CDocument} {} { TCL 1.1 CHANGES} { [} { - added MakePrinter, DoAppleEvent method} { ]} {} {****************************************************************************} type CDocument = object(CDirector) itsMainPane: CPane; itsFile: CFile; lastTask: CTask; undone: Boolean; itsPrinter: CPrinter; dirty: Boolean; pageWidth: Integer; pageHeight: Integer; procedure IDocument (aSupervisor: CApplication; printable: Boolean); procedure Free; OVERRIDE; procedure Notify (theTask: CTask); OVERRIDE; procedure DoCommand (theCommand: Longint); OVERRIDE; procedure UpdateMenus; OVERRIDE; function Close (quitting: Boolean): Boolean; OVERRIDE; procedure CloseWind (theWindow: CWindow); OVERRIDE; function ConfirmClose (quitting: Boolean): Boolean; procedure NewFile; procedure OpenFile (macSFReply: SFReply); procedure MakePrinter; procedure Paginate; function PageCount: Integer; procedure AboutToPrint (var firstPage: Integer; var lastPage: Integer); procedure PrintPageOfDoc (pageNum: Integer); procedure DonePrinting; function DoSave: Boolean; function DoSaveAs (macSFReply: SFReply): Boolean; procedure DoRevert; function DoSaveFileAs: Boolean; procedure PickFileName (var macSFReply: SFReply); procedure GetName (var theName: Str255); procedure UpdateUndo; end; { symbolic constants for Boolean parameters} const kNotPrintable = FALSE; kPrintable = TRUE; {****************************************************************************} { CClipboard} { } { TCL 1.1 CHANGES} { [} { - added EmptyGlobalScrap, EmptyScrap methods. PutGlobalScrap} { no longer calls ZeroScrap, so you must call EmptyGlobalScrap} { or EmptyScrap before calling PutGlobalScrap or PutData.} { - added MakeClipView method} { ]} {} {****************************************************************************} type ScrapStatus = (GLOBAL_SCRAP_NEWER, PRIVATE_SCRAP_NEWER, SCRAPS_THE_SAME); CClipboard = object(CDirector) { Instance Variables } itsContents: CPanorama; { Pane for displaying contents } itsScrollPane: CScrollPane; { Contents can be scrolled } theLength: longint; { Length from last Get operation } theOffset: longint; { Offset from last Get operation } lastScrapCount: integer; { Count at the last conversion } { between global and private } privateNewer: Boolean; { Has private scrap changed since } { last conversion? } windowVisible: Boolean; { Is clipboard window visible? } { Instance Methods } procedure IClipboard (aSupervisor: CApplication; hasWindow: Boolean); procedure Suspend; OVERRIDE; procedure Resume; OVERRIDE; function Close (quitting: Boolean): Boolean; OVERRIDE; procedure CloseWind (theWindow: CWindow); OVERRIDE; procedure Toggle; procedure PutGlobalScrap (theType: ResType; theData: Handle); function GetGlobalScrap (theType: ResType; theData: Handle): Boolean; function Status: ScrapStatus; procedure ScrapConverted; procedure ConvertGlobal; procedure ConvertPrivate; procedure EmptyGlobalScrap; procedure EmptyScrap; procedure PutData (theType: ResType; theData: Handle); function GetData (theType: ResType; var theData: Handle): Boolean; function DataSize (theType: ResType): Longint; procedure PrivateChanged; procedure UpdateDisplay; function MakeClipView (dataType: ResType; dataHandle: Handle): CPanorama; end; {****************************************************************************} { CView} {} { TCL 1.1 CHANGES} { [} { - added GetWantsClicks method} { - added fCanBeGopher instance variable, and SetCanBeGopher and} { CanBeGopher methods for accessing} { - added ID instance variable, GetID, SetID,} { and FindByID methods} { - added MatchView method} { - added ForcePrepare method} { - for 32-bit view support, changed GetFrame, GetInterior, GetAperture,} { and FrameToGlobalR to use LongRects.} { - added usingLongCoord instance variable and UseLongCoordinates} { method.} { - added ForceNextPrepare static method} { - moved TrackMouse to CPane. It needs access to some coordinate} { transformations provided by CPane.} { - added helpResIndex instance variable, and GetBalloonInfo, ShowHelpBalloon, } { and GetHelpResID methods} { - added cPreparedView, cCurrHelpView, cLastHelpView,} { class variables} { ]} {****************************************************************************} type CView = object(CBureaucrat) macPort: GrafPtr; { Mac drawing port for the image } itsEnclosure: CView; { Enclosing view } itsSubviews: CList; { Views within this view } visible: Boolean; { Is the view visible? } active: Boolean; { Is the view active? } wantsClicks: Boolean; { Does view handle mouse clicks? } fCanBeGopher: Boolean; { Can this view become the gopher? } ID: Longint; { identifier for this view } usingLongCoord: Boolean; { TRUE if using 32-bit coordinates } helpResIndex: Integer; { ballon help info for the view } procedure IView (anEnclosure: CView; aSupervisor: CBureaucrat); procedure IViewRes (rType: ResType; resID: Integer; anEnclosure: CView; aSupervisor: CBureaucrat); procedure IViewTemp (anEnclosure: CView; aSupervisor: CBureaucrat; viewData: Ptr); procedure Free; OVERRIDE; function IsVisible: Boolean; function IsActive: Boolean; function ReallyVisible: Boolean; function GetMacPort: GrafPtr; procedure GetOrigin (var theHOrigin: Longint; var theVOrigin: Longint); procedure GetFrame (var theFrame: LongRect); procedure GetInterior (var theInterior: LongRect); procedure GetAperture (var theAperture: LongRect); function Contains (thePoint: Point): Boolean; procedure SetWantsClicks (aWantsClicks: Boolean); function GetWantsClicks: Boolean; procedure SetCanBeGopher (aCanBeGopher: Boolean); function CanBeGopher: Boolean; procedure SetID (anIdentifier: Longint); function GetID: Longint; procedure UseLongCoordinates (fUsing: Boolean); procedure Show; procedure Hide; procedure Activate; procedure Deactivate; procedure DispatchClick (var macEvent: EventRecord); procedure DoClick (hitPt: Point; modifierKeys: Integer; when: Longint); function HitSamePart (pointA: Point; pointB: Point): Boolean; procedure DoMouseUp (VAR macEvent: EventRecord); procedure DispatchCursor (where: Point; mouseRgn: RgnHandle); procedure AdjustCursor (where: Point; mouseRgn: RgnHandle); procedure GetBalloonInfo (var helpData: HMMessageRecord; var tip: Point; var alternateRect: Rect; var tipProc: Ptr; var theProc, variant, method: Integer); procedure ShowHelpBalloon (helpData: HMMessageRecord; tip: Point; alternateRect: Rect; tipProc: Ptr; theProc, variant, method: Integer); function GetHelpResID: Integer; procedure AddSubview (theSubview: CView); procedure RemoveSubview (theSubview: CView); function FindSubview (hitPt: Point): CView; procedure SubpaneLocation (hEncl: Longint; vEncl: Longint; var hLocation: Longint; var vLocation: Longint); function FindViewByID (anID: Longint): CView; function CView.MatchView (function matchProc (aView: CView): Boolean): CView; procedure Prepare; procedure FrameToGlobalR (frameRect: LongRect; var globalRect: Rect); end; { View template } type ViewTemp = record visible: Integer; active: Integer; wantsClicks: Integer; end; ViewTempP = ^ViewTemp; var { CLASS VARIABLES } cPreparedView: CView; { currently Prepared view } cCurrHelpView: CView; { used for Balloon help } cLastHelpView: CView; { also for Balloon help } procedure ForceNextPrepare; {****************************************************************************} { CWindow} {} { TCL 1.1 CHANGES} { [} { - added isModal instance variable and IsModal method.} { - added INewWindow method to support creation without WIND resource} { - added procID instance variable to remember the defproc ID used} { to create the window.} { - added isColor instance variable and IsColor method} { - added helpResID instance variable, SetHelpResID, GetHelpResID} { methods} { ]} {} {****************************************************************************} type WStateDataP = ^WStateData; WStateDataH = ^WStateDataP; CWindow = object(CView) procID: Integer; { defproc ID used to create the window } sizeRect: Rect; { Max and Min size for the window } floating: Boolean; { Is this a floating window? } fIsColor: Boolean; { Is this a color window? } fIsModal: Boolean; { Is it currently modal? } actClick: Boolean; { Does it process a mouse click } { which activates the window? } location: Point; { Location of window, used when } { "hiding" while suspended } helpResID: Integer;{ index of 'hrct' resource for } { help balloons } procedure IWindow (WINDid: Integer; aFloating: Boolean; anEnclosure: CDesktop; aSupervisor: CDirector); procedure INewWindow (bounds: Rect; fVisible: Boolean; aProcID: Integer; fFloating: Boolean; fHasGoAway: Boolean; anEnclosure: CDesktop; aSupervisor: CDirector); procedure IWindowX; procedure Free; OVERRIDE; procedure MakeMacWindow (WINDid: Integer); procedure MakeNewMacWindow (bounds: Rect; aProcID: Integer; fHasGoAway: Boolean); procedure Close; procedure GetFrame (var theFrame: LongRect); OVERRIDE; procedure GetInterior (var theInterior: LongRect); OVERRIDE; procedure GetAperture (var theAperture: LongRect); OVERRIDE; function IsFloating: Boolean; function IsModal: Boolean; function IsColor: Boolean; procedure SetModal (fModal: Boolean); procedure SetTitle (theTitle: Str255); procedure GetTitle (var theTitle: Str255); procedure SetActClick (anActClick: Boolean); function WantsActClick: Boolean; function Contains (thePoint: Point): Boolean; OVERRIDE; procedure SetSizeRect (aSizeRect: Rect); procedure SetStdState (aStdState: Rect); procedure SetHelpResID (aResID: Integer); function GetHelpResID: Integer; OVERRIDE; procedure Show; OVERRIDE; procedure Hide; OVERRIDE; procedure Activate; OVERRIDE; procedure Deactivate; OVERRIDE; procedure Select; procedure ShowResume; procedure HideSuspend; procedure ShowOrHide (showFlag: Boolean); procedure Drag (VAR macEvent: EventRecord); procedure Resize (VAR macEvent: EventRecord); procedure Zoom (direction: Integer); procedure Move (hGlobal: Integer; vGlobal: Integer); procedure ChangeSize (width: Integer; height: Integer); procedure MoveOffScreen; procedure Update; procedure Prepare; OVERRIDE; procedure DispatchClick (var macEvent: EventRecord); OVERRIDE; procedure DispatchCursor (where: Point; mouseRgn: RgnHandle); OVERRIDE; procedure FrameToGlobalR (frameRect: LongRect; var globalRect: Rect); OVERRIDE; end; { symbolic constants for Boolean parameters} const kModeless = FALSE; kModal = TRUE; kNotVisible = FALSE; kVisible = TRUE; kNoGoAway = FALSE; kHasGoAway = TRUE; kNotFloating = FALSE; kFloating = TRUE; {****************************************************************************} { CDesktop} {} {****************************************************************************} type CDesktop = object(CView) bounds: Rect; { Boundaries of the Desktop } itsWindows: CList; { Application windows } topWindow: CWindow; { Topmost visible window } procedure IDesktop (aSupervisor: CBureaucrat); procedure Free; OVERRIDE; procedure Show; OVERRIDE; procedure Hide; OVERRIDE; procedure Activate; OVERRIDE; procedure Deactivate; OVERRIDE; function ReallyVisible: Boolean; OVERRIDE; procedure DispatchClick (var macEvent: EventRecord); OVERRIDE; procedure DoMouseUp (VAR macEvent: EventRecord); OVERRIDE; procedure DispatchCursor (where: Point; mouseRgn: RgnHandle); OVERRIDE; procedure AdjustCursor (where: Point; mouseRgn: RgnHandle); OVERRIDE; function Contains (thePoint: Point): Boolean; OVERRIDE; function HitSamePart (pointA: Point; pointB: Point): Boolean; OVERRIDE; procedure AddWind (theWindow: CWindow); procedure RemoveWind (theWindow: CWindow); procedure SelectWind (theWindow: CWindow); procedure ShowWind (theWindow: CWindow); procedure HideWind (theWindow: CWindow); procedure DragWind (theWindow: CWindow; VAR macEvent: EventRecord); procedure UpdateWindows; function GetTopWindow: CWindow; function GetBottomWindow: CWindow; procedure GetBounds (var theBounds: Rect); procedure GetAperture (var theAperture: LongRect); OVERRIDE; procedure Prepare; OVERRIDE; procedure Cleanup; end; {****************************************************************************} { CPane} {} { TCL 1.1 CHANGES} { [} { - added GetWindow method} { - added instance variable itsBorder, and SetBorder, GetBorder,} { SetResBorder, and RefreshBorder methods} { - Moved TrackMouse from CView to CPane.} { - for 32-bit support, changed instance variables hEncl, vEncl, } { frame, and aperture to use long coordinates. Also changed } { interface for SetFrameOrigin, GetFrame, GetAperture, Place, } { Offset, EnclosureScrolled, WindToFrame, WindToFrameR, FrameToWind, } { FrameToWindR, EnclToFrame, EnclToFrameR, FrameToEncl, FrameToEnclR, } { and FrameToGlobalR methods to use long coordinates.} { - added new methods RefreshLongRect, QDToFrame, QDToFrameR, } { FrameToQD, FrameToQDR, and SectAperture, GetHelpResID} { ]} {} {****************************************************************************} type { How pane changes size when the size of its enclosure changes } SizingOption = (sizFIXEDLEFT, { Fixed length, anchored to left } sizFIXEDRIGHT, { Fixed length, anchored to right } sizFIXEDTOP, { Fixed length, anchored to top } sizFIXEDBOTTOM, { Fixed length, anchored to bottom } sizFIXEDSTICKY, { Fixed length, sticks to coords } { of its enclosure } sizELASTIC { Variable length, always a fixed } { amount smaller than enclosure } ); ClipOption = (clipAPERTURE, clipFRAME, clipPAGE); CPane = object(CView) width: Integer; { Horizontal size in pixels } height: Integer; { Vertical size in pixels } hEncl: Longint; { Horizontal location in enclosure } vEncl: Longint; { Vertical location in enclosure } hSizing: SizingOption; { Horizontal sizing option } vSizing: SizingOption; { Vertical sizing option } autoRefresh: Boolean; { Refresh all after a resize? } frame: LongRect; { Area for displaying the Pane } { which defines Frame coords } aperture: LongRect; { Active drawing area of the Pane } hOrigin: Longint; { Window left in Frame coords } vOrigin: Longint; { Window top in Frame coords } itsEnvironment: CEnvironment; { Drawing environment } printClip: ClipOption; { Clipping option when printing } printing: Boolean; { Is printing in progress? } itsBorder: CPaneBorder; { border of this pane } itsLastTask: CTask; { subclasses should always make } { sure that itsLastTask points to } { the last CTask subclass created } { by the pane. The Dispose } { method will make sure that the } { task is disposed when the pane } { is disposed. This is important } { because most tasks refer back to } { the originating pane and would } { be left with a dangling pointer. } procedure IPane (anEnclosure: CView; aSupervisor: CBureaucrat; aWidth: Integer; aHeight: Integer; aHEncl: Integer; aVEncl: Integer; aHSizing: SizingOption; aVSizing: SizingOption); procedure IViewTemp (anEnclosure: CView; aSupervisor: CBureaucrat; viewData: Ptr); OVERRIDE; procedure IPaneX; procedure Free; OVERRIDE; procedure SetFrameOrigin (fLeft: Longint; fTop: Longint); procedure GetFrame (var theFrame: LongRect); OVERRIDE; procedure GetLengths (var theWidth, theHeight: Integer); procedure GetOrigin (var theHOrigin, theVOrigin: Longint); OVERRIDE; procedure GetAperture (var theAperture: LongRect); OVERRIDE; function Contains (thePoint: Point): Boolean; OVERRIDE; function ReallyVisible: Boolean; OVERRIDE; procedure GetPixelExtent (var hExtent: Longint; var vExtent: Longint); procedure SetPrintClip (aPrintClip: ClipOption); function GetWindow: CWindow; procedure SetBorder (aBorder: CPaneBorder); procedure SetResBorder (resID: Integer); function GetBorder: CPaneBorder; function GetHelpResID: Integer; OVERRIDE; procedure Show; OVERRIDE; procedure Hide; OVERRIDE; procedure Place (aHEncl: Longint; aVEncl: Longint; redraw: Boolean); procedure Offset (hOffset: Longint; vOffset: Longint; redraw: Boolean); procedure ChangeSize (delta: Rect; redraw: Boolean); procedure AdjustToEnclosure (deltaEncl: Rect); procedure AdjustHoriz (deltaEncl: Rect; var delta: Rect; var theOffset: Integer; var moved: Boolean; var sized: Boolean); procedure AdjustVert (deltaEncl: Rect; var delta: Rect; var theOffset: Integer; var moved: Boolean; var sized: Boolean); procedure EnclosureScrolled (hOffset: Longint; vOffset: Longint); procedure FitToEnclosure (horizFit: Boolean; vertFit: Boolean); procedure FitToEnclFrame (horizFit: Boolean; vertFit: Boolean); procedure CenterWithinEnclosure (horizCenter: Boolean; vertCenter: Boolean); procedure Draw (var area: Rect); procedure DrawAll (var area: Rect); procedure Refresh; procedure RefreshRect (area: Rect); procedure RefreshLongRect (area: LongRect); procedure RefreshBorder; procedure Paginate (aPrinter: CPrinter; pageWidth: Integer; pageHeight: Integer); procedure AboutToPrint (var firstPage: Integer; var lastPage: Integer); procedure PrintPage (pageNum: Integer; pageWidth: Integer; pageHeight: Integer; aPrinter: CPrinter); procedure DonePrinting; procedure PrepareToPrint; procedure Prepare; OVERRIDE; procedure RestoreEnvironment; procedure CalcFrame; procedure ResizeFrame (delta: Rect); procedure CalcAperture; procedure TrackMouse (theTask: CMouseTask; startPt: LongPt; var pinRect: LongRect); procedure WindToFrame (qdPt: Point; var framePt: LongPt); procedure WindToFrameR (qdRect: Rect; var frameRect: LongRect); procedure FrameToWind (framePt: LongPt; var qdPt: Point); procedure FrameToWindR (frameRect: LongRect; var qdRect: Rect); procedure EnclToFrame (var thePoint: LongPt); procedure EnclToFrameR (var theRect: LongRect); procedure FrameToEncl (var thePoint: LongPt); procedure FrameToEnclR (var theRect: LongRect); procedure FrameToGlobalR (frameRect: LongRect; var globalRect: Rect); OVERRIDE; procedure QDToFrame (qdPt: Point; var framePt: LongPt); procedure QDToFrameR (qdRect: Rect; var frameRect: LongRect); procedure FrameToQD (framePt: LongPt; var qdPt: Point); procedure FrameToQDR (frameRect: LongRect; var qdRect: Rect); function SectAperture (srcRect: LongRect; var destRect: Rect): Boolean; end; { Pane template } PaneTemp = record sViewTemp: ViewTemp; width: Integer; height: Integer; hEncl: Integer; vEncl: Integer; hSizing: Integer; vSizing: Integer; autoRefresh: Integer; printClip: Integer; end; PaneTempP = ^PaneTemp; { TRUE/FALSE synonyms for some common Boolean parameters } const kNoRedraw = FALSE; kRedraw = TRUE; kNotHorizontal = FALSE; kDoHorizontal = TRUE; kNotVertical = FALSE; kDoVertical = TRUE; var cPageArea: Rect; { area of page being printed } {****************************************************************************} { CControl} { } { TCL 1.1 CHANGES} { [} { - added constants for CControl change protocol.} { ]} {} {****************************************************************************} type CControl = object(CPane) macControl: ControlHandle; { Toolbox control record } { Destruction } procedure Free; override; { Accessing } procedure SetValue (aValue: integer); function GetValue: integer; procedure SetMaxValue (aMaxValue: integer); function GetMaxValue: integer; procedure SetMinValue (aMinValue: integer); function GetMinValue: integer; procedure SetTitle (aTitle: Str255); procedure GetTitle (var aTitle: Str255); procedure SetActionProc (anActionProc: ControlActionUPP); { Manipulating } procedure Show; override; procedure Hide; override; procedure Activate; override; procedure Deactivate; override; procedure Offset (hOffset: Longint; vOffset: Longint; redraw: Boolean); override; procedure ChangeSize (delta: Rect; redraw: Boolean); override; { Drawing } procedure Draw (var area: Rect); override; procedure DrawAll (var area: Rect); override; procedure Prepare; override; procedure PrepareToPrint; { TCL 1.1.1 DLP 9/25/91 } override; { Click Response } procedure DoClick (hitPt: Point; modifierKeys: integer; when: longint); override; procedure DoThumbDragged (delta: integer); procedure DoGoodClick (whichPart: integer); procedure RefreshLongRect (area: LongRect); OVERRIDE; end; CNTLtemplate = record boundsRect: Rect; value: Integer; visible: Integer; max: Integer; min: Integer; procID: Integer; refcon: Longint; title: Str255; end; CNTLtemplatePtr = ^CNTLtemplate; CNTLtemplateHndl = ^CNTLtemplatePtr; { Change protocol for CControl } const { The value of the control has changed. The info parameter is } { a pointer (IntegerPtr) to the new value } controlValueChanged = bureaucratLastChange + 1; controlLastChange = controlValueChanged; {****************************************************************************} { CPanorama} {} { TCL 1.1 CHANGES} { [} { - To accomodate 32 bit coordinates, changed instance variables} { bounds, position, and savePosition.} { - Changed interface for SetBounds, GetBounds, SetPosition, GetPosition,} { GetHomePosition, ScrollTo, SetBounds, and GetBounds } { to accomodate 32 bit coordinates. } { - added ClipToAperture method } { ]} {} {****************************************************************************} type CPanorama = object(CPane) bounds: LongRect; hScale: Integer; vScale: Integer; position: LongPt; savePosition: LongPt; itsScrollPane: CScrollPane; procedure IPanorama (anEnclosure: CView; aSupervisor: CBureaucrat; aWidth: Integer; aHeight: Integer; aHEncl: Integer; aVEncl: Integer; aHSizing: SizingOption; aVSizing: SizingOption); procedure IViewTemp (anEnclosure: CView; aSupervisor: CBureaucrat; viewData: Ptr); OVERRIDE; procedure GetExtent (var theHExtent: Longint; var theVExtent: Longint); procedure GetFramePosition (var theHPos: Longint; var theVPos: Longint); procedure GetFrameSpan (var theHSpan, theVSpan: Integer); procedure SetBounds (aBounds: LongRect); procedure GetBounds (var theBounds: LongRect); procedure SetPosition (aPosition: LongPt); procedure GetPosition (var thePos: LongPt); procedure SetScales (aHScale: Integer; aVScale: Integer); procedure GetScales (var theHScale, theVScale: Integer); procedure SetScrollPane (aScrollPane: CScrollPane); procedure GetHomePosition (var theHomePos: LongPt); procedure GetPixelExtent (var hExtent: Longint; var vExtent: Longint); OVERRIDE; procedure ResizeFrame (delta: Rect); OVERRIDE; procedure Scroll (hDelta: Longint; vDelta: Longint; redraw: Boolean); procedure ScrollTo (aPosition: LongPt; redraw: Boolean); procedure ScrollToSelection; function AutoScroll (mouseLoc: LongPt): Boolean; procedure DoKeyDown (theChar: Char; keyCode: Byte; VAR macEvent: EventRecord); OVERRIDE; procedure Paginate (aPrinter: CPrinter; pageWidth: Integer; pageHeight: Integer); OVERRIDE; procedure AboutToPrint (var firstPage: Integer; var lastPage: Integer); OVERRIDE; procedure PrintPage (pageNum: Integer; pageWidth: Integer; pageHeight: Integer; aPrinter: CPrinter); OVERRIDE; procedure DonePrinting; OVERRIDE; end; { Panorama template } type PanoramaTemp = record sPaneTemp: PaneTemp; bounds: Rect; hScale: Integer; vScale: Integer; position: Point; end; PanoramaTempP = ^PanoramaTemp; {****************************************************************************} { CPicture} {} {****************************************************************************} type CPicture = object(CPanorama) macPicture: PicHandle; scaled: Boolean; isResPicture: Boolean; ownsPicture: Boolean; procedure IPicture (anEnclosure: CView; aSupervisor: CBureaucrat; aWidth: Integer; aHeight: Integer; aHEncl: Integer; aVEncl: Integer; aHSizing: SizingOption; aVSizing: SizingOption); procedure IViewTemp (anEnclosure: CView; aSupervisor: CBureaucrat; viewData: Ptr); OVERRIDE; procedure Free; OVERRIDE; procedure Draw (var area: Rect); OVERRIDE; procedure SetMacPicture (aMacPicture: PicHandle); procedure UsePICT (PICTid: Integer); function GetMacPicture: PicHandle; procedure SetScaled (aScaled: Boolean); function GetScaled: Boolean; procedure ResizeFrame (delta: Rect); OVERRIDE; procedure FrameToBounds; end; { Picture Pane template } type PictureTemp = record sPanoramaTemp: PanoramaTemp; PICTid: Integer; scaled: Integer; end; PictureTempP = ^PictureTemp; {****************************************************************************} { CScrollBar} {} {****************************************************************************} type Orientation = (HORIZONTAL, VERTICAL); CScrollBar = object(CControl) theOrientation: Orientation; theThumbFunc: ControlActionUPP; procedure IScrollBar (anEnclosure: CView; aSupervisor: CBureaucrat; anOrientation: Orientation; aLength: Integer; aHEncl: Integer; aVEncl: Integer); procedure SetThumbFunc (aThumbFunc: ControlActionUPP); procedure Draw (var area: Rect); OVERRIDE; procedure Activate; OVERRIDE; procedure Deactivate; OVERRIDE; procedure DoClick (hitPt: Point; modifierKeys: Integer; when: Longint); OVERRIDE; procedure DoThumbDragged (delta: Integer); OVERRIDE; end; procedure CallTheThumbFunc (theScrollBar: CScrollBar; delta: integer; thumbFunc: ControlActionUPP); {$IFC MAC68K} inline $205F, { MOVEA.L (A7)+, A0 } $4E90; { JSR (A0) } {$ENDC} {****************************************************************************} { CScrollPane} {} { TCL 1.1 CHANGES} { [} { - added DoScroll method} { ]} {} {****************************************************************************} type CScrollPane = object(CPane) itsPanorama: CPanorama; { View which scrolls } itsHorizSBar: CScrollBar; { Horizontal scroll bar } itsVertSBar: CScrollBar; { Vertical scroll bar } itsSizeBox: CSizeBox; { Grow box } hExtent: Longint; vExtent: Longint; hUnit: Integer; vUnit: Integer; hSpan: Integer; vSpan: Integer; hStep: Integer; vStep: Integer; hOverlap: Integer; vOverlap: Integer; procedure IScrollPane (anEnclosure: CView; aSupervisor: CBureaucrat; aWidth: Integer; aHeight: Integer; aHEncl: Integer; aVEncl: Integer; aHSizing: SizingOption; aVSizing: SizingOption; hasHoriz: Boolean; hasVert: Boolean; hasSizeBox: Boolean); procedure IViewTemp (anEnclosure: CView; aSupervisor: CBureaucrat; viewData: Ptr); OVERRIDE; procedure IScrollPaneX (hasHoriz: Boolean; hasVert: Boolean; hasSizeBox: Boolean); procedure InstallPanorama (aPanorama: CPanorama); procedure SetSteps (aHStep: Integer; aVStep: Integer); procedure GetSteps (var theHStep: Integer; var theVStep: Integer); procedure SetOverlaps (aHOverlap: Integer; aVOverlap: Integer); procedure GetInterior (var theInterior: LongRect); OVERRIDE; procedure AdjustScrollMax; procedure Calibrate; procedure ChangeSize (delta: Rect; redraw: Boolean); OVERRIDE; procedure DoHorizScroll (whichPart: Integer); procedure DoVertScroll (whichPart: Integer); procedure DoThumbDrag (hDelta: Integer; vDelta: Integer); procedure DoScroll (hDelta: Longint; vDelta: Longint); end; { ScrollPane template } type ScrollPaneTemp = record sPaneTemp: PaneTemp; hStep: Integer; vStep: Integer; hOverlap: Integer; vOverlap: Integer; hasHoriz: Integer; hasVert: Integer; hasSizeBox: Integer; end; ScrollPaneTempP = ^ScrollPaneTemp; { synonyms for some Boolean parameters} const kNoHScroll = FALSE; kHasHScroll = TRUE; kNoVScroll = FALSE; kHasVScroll = TRUE; kNoSizebox = FALSE; kHasSizebox = TRUE; {****************************************************************************} { CSizeBox} {} { TCL 1.1 CHANGES} { [} { - added useSICN instance variable. Determines whether a SICN resource} { or the DrawGrowIcon trap is used to draw the size box.} { ]} {} {****************************************************************************} type CSizeBox = object(CPane) useSICN: Boolean; procedure ISizeBox (anEnclosure: CView; aSupervisor: CBureaucrat); procedure Draw (var area: Rect); OVERRIDE; procedure Activate; OVERRIDE; procedure Deactivate; OVERRIDE; end; {****************************************************************************} { CAbstractText} {****************************************************************************} type { buffer for a single character, allowing for multi-byte scripts } { first byte is length-byte, as in a Pascal string } tCharBuf = string[5]; CAbstractText = object(CPanorama) itsTypingTask: CTextEditTask; fixedLineHeights: Boolean; wholeLines: Boolean; editable: Boolean; stylable: Boolean; lineWidth: Integer; lastFontNum: Integer; lastFontCmd: Longint; lastTextSize: Integer; lastSizeCmd: Longint; procedure IAbstractText (anEnclosure: CView; aSupervisor: CBureaucrat; aWidth: Integer; aHeight: Integer; aHEncl: Integer; aVEncl: Integer; aHSizing: SizingOption; aVSizing: SizingOption; aLineWidth: Integer); procedure IViewTemp (anEnclosure: CView; aSupervisor: CBureaucrat; viewData: Ptr); OVERRIDE; procedure SetTextString (textStr: Str255); procedure SetTextHandle (textHand: Handle); procedure SetTextPtr (textPtr: Ptr; numChars: Longint); function GetTextHandle: Handle; function CopyTextRange (startPos: Longint; endPos: Longint): Handle; procedure InsertTextPtr (text: Ptr; length: Longint; fRedraw: Boolean); procedure InsertTextHandle (text: Handle; fRedraw: Boolean); procedure Specify (fEditable, fSelectable, fStylable: Boolean); procedure GetSpecification (var fEditable, fSelectable, fStylable: Boolean); procedure SetFontNumber (aFontNumber: Integer); procedure SetFontName (aFontName: Str255); procedure SetFontStyle (aStyle: Style); procedure SetFontSize (aSize: Integer); procedure SetTextMode (aMode: Integer); procedure SetAlignCmd (anAlignCmd: Longint); function GetAlignCmd: Longint; procedure SetSpacingCmd (aSpacingCmd: Longint); function GetSpacingCmd: Longint; function GetHeight (startLine: Longint; endLine: Longint): Longint; function Get1Height (aLineNum: Longint): Integer; function GetCharOffset (aPt: LongPt): Longint; procedure GetCharPoint (theOffset: Longint; var aPt: LongPt); procedure GetCharStyle (charOffset: Longint; var theStyle: TextStyle); procedure GetTextStyle (var whichAttributes: Integer; var aStyle: TextStyle); procedure GetCharBefore (var aPosition: Longint; var charBuf: tCharBuf); procedure GetCharAfter (var aPosition: Longint; var charBuf: tCharBuf); procedure ResizeFrame (delta: Rect); OVERRIDE; procedure SetWholeLines (aWholeLines: Boolean); function GetWholeLines: Boolean; function FindLine (charPos: Longint): Longint; function GetLength: Longint; function GetNumLines: Longint; procedure DoCommand (theCommand: Longint); OVERRIDE; procedure PerformEditCommand (theCommand: Longint); procedure UpdateMenus; OVERRIDE; procedure DoKeyDown (theChar: Char; keyCode: Byte; VAR macEvent: EventRecord); OVERRIDE; procedure DoAutoKey (theChar: Char; keyCode: Byte; VAR macEvent: EventRecord); OVERRIDE; procedure TypeChar (theChar: Char; theModifiers: Integer); procedure SelectionChanged; procedure ScrollToSelection; OVERRIDE; function BecomeGopher (fBecoming: Boolean): Boolean; OVERRIDE; procedure SetSelection (selStart: Longint; selEnd: Longint; fRedraw: Boolean); procedure GetSelection (var selStart, selEnd: Longint); procedure SelectAll (fRedraw: Boolean); procedure Paginate (aPrinter: CPrinter; pageWidth, pageHeight: Integer); OVERRIDE; procedure AdjustCursor (where: Point; mouseRgn: RgnHandle); OVERRIDE; function MakeEditTask (editCmd: Longint): CTextEditTask; function MakeStyleTask (styleCmd: Longint): CTextStyleTask; end; tAbstractTextTemp = record sPanoramaTemp: PanoramaTemp; lineWidth: Integer; wholeLines: Integer; editable: Integer; styleable: Integer; end; tAbstractTextTempP = ^tAbstractTextTemp; var cFirstTaskIndex: Integer; { Usage of cFirstTaskIndex:} {} { CDocument updates the Undo menu item by sending a GetNameIndex message to the} { most recent task. The integer the task returns is used as an index into the} { STR# 130 resource, and the resulting string is used in the menu item text.} { } { CAbstractText, along with CTextEditTask and CStyleTask can perform a number of} { undoable operations, so more than one string is needed. The tasks assumes} { all the strings are located together in the STR# 130 resource, starting} { at the index given by the class variable cFirstTaskIndex. By default this} { index is 1, meaning these strings are the first in the STR# resource. } { It also expects them to be in the following order:} { Typing, Cut, Copy, Paste, Clear, Formatting} { } { If you have these strings at a different position in the resource, be sure} { to set cFirstTaskIndex at some point in your application resource. If you} { don't supply the strings at all, set cFirstTaskIndex to 0.} {} {) { Usage of cFirstTaskIndex:} {} { CDocument updates the Undo menu item by sending a GetNameIndex message to the} { most recent task. The integer the task returns is used as an index into the} { STR# 130 resource, and the resulting string is used in the menu item text.} { } { CAbstractText, along with CTextEditTask and CStyleTask can perform a number of} { undoable operations, so more than one string is needed. The tasks assumes} { all the strings are located together in the STR# 130 resource, starting} { at the index given by the class variable cFirstTaskIndex. By default this} { index is 1, meaning these strings are the first in the STR# resource. } { It also expects them to be in the following order:} { Typing, Cut, Copy, Paste, Clear, Formatting} { } { If you have these strings at a different position in the resource, be sure} { to set cFirstTaskIndex at some point in your application resource. If you} { don't supply the strings at all, set cFirstTaskIndex to 0.} {} {} const kAlignNotContinuous = MININT; { alignment not continuous over selection } kAlignJustify = 5; { full justification } { mnemonic constants for the Specify method } kNotEditable = FALSE; kEditable = TRUE; kNotSelectable = FALSE; kSelectable = TRUE; kNotStylable = FALSE; kStylable = TRUE; { constants specifying the expected order of undo task names } undoTyping = 0; undoCut = 1; undoCopy = 2; undoPaste = 3; undoClear = 4; undoFormatting = 5; { Change protocol for CAbstractText: info parameter not used } textSelectionChanged = bureaucratLastChange + 1; textLastChange = textSelectionChanged; {****************************************************************************} { CEditText} {} { TCL 1.1 CHANGES} { [} { - BIG CHANGE: EditText is now a subclass of CAbstractText, and} { CStaticText is a subclass of CEditText. Many, many things} { changed because of this. See comments in CEditText.p} { ]} {} {****************************************************************************} type CEditText = object(CAbstractText) macTE: TEHandle; spacingCmd: Longint; alignCmd: Longint; procedure IEditText (anEnclosure: CView; aSupervisor: CBureaucrat; aWidth: Integer; aHeight: Integer; aHEncl: Integer; aVEncl: Integer; aHSizing: SizingOption; aVSizing: SizingOption; aLineWidth: Integer); procedure IViewTemp (anEnclosure: CView; aSupervisor: CBureaucrat; viewData: Ptr); OVERRIDE; procedure IEditTextX; procedure MakeMacTE; procedure Free; OVERRIDE; procedure DoClick (hitPt: Point; modifierKeys: Integer; when: Longint); OVERRIDE; procedure PerformEditCommand (theCommand: Longint); OVERRIDE; procedure Draw (var area: Rect); OVERRIDE; procedure Scroll (hDelta, vDelta: Longint; redraw: Boolean); OVERRIDE; procedure Activate; OVERRIDE; procedure Deactivate; OVERRIDE; procedure SetSelection (selStart, selEnd: Longint; fRedraw: Boolean); OVERRIDE; procedure SetTextPtr (textPtr: Ptr; numChars: Longint); OVERRIDE; function GetTextHandle: Handle; OVERRIDE; function CopyTextRange (startPos, endPos: Longint): Handle; OVERRIDE; procedure InsertTextPtr (text: Ptr; length: Longint; fRedraw: Boolean); OVERRIDE; procedure TypeChar (theChar: Char; theModifiers: Integer); OVERRIDE; procedure CheckInsertion (insertLen: Longint; useSelection: Boolean); procedure CalcTERects; procedure ResizeFrame (delta: Rect); OVERRIDE; procedure AdjustBounds; function FindLine (charPos: Longint): Longint; OVERRIDE; function GetLength: Longint; OVERRIDE; procedure SetFontNumber (aFontNumber: Integer); OVERRIDE; procedure SetFontStyle (aStyle: Style); OVERRIDE; procedure SetFontSize (aSize: Integer); OVERRIDE; procedure SetTextMode (aMode: Integer); OVERRIDE; procedure SetAlignment (anAlignment: Integer); procedure SetAlignCmd (anAlignCmd: Longint); OVERRIDE; procedure SetSpacingCmd (aSpacingCmd: Longint); OVERRIDE; procedure GetTEFontInfo (var macFontInfo: FontInfo); function GetHeight (startLine, endLine: Longint): Longint; OVERRIDE; function GetCharOffset (aPt: LongPt): Longint; OVERRIDE; procedure GetCharPoint (theOffset: Longint; var aPt: LongPt); OVERRIDE; procedure GetTextStyle (var whichAttributes: Integer; var aStyle: TextStyle); OVERRIDE; procedure GetCharStyle (charOffset: Longint; var theStyle: TextStyle); OVERRIDE; function GetSpacingCmd: Longint; OVERRIDE; function GetAlignCmd: Longint; OVERRIDE; function GetNumLines: Longint; OVERRIDE; procedure GetSelection (var selStart, selEnd: Longint); OVERRIDE; procedure AboutToPrint (var firstPage, lastPage: Integer); OVERRIDE; procedure PrintPage (pageNum: Integer; pageWidth, pageHeight: Integer; aPrinter: CPrinter); OVERRIDE; procedure DonePrinting; OVERRIDE; procedure Dawdle (var maxSleep: Longint); OVERRIDE; end; const kMaxTELength = 32000; { maximum text we allow in TE record } {****************************************************************************} { CTextEditTask} { } {****************************************************************************} { saves information about a range of text} type tTextRange = record text: Handle; startPos: Longint; endPos: Longint; selStart: Longint; selEnd: Longint; end; { specify either insert or deleted range of text} tRangeSelector = (kInsertedRange, kDeletedRange); { specify either the old or new clipboard} tClipSelector = (kOldClip, kNewClip); CTextEditTask = object(CTask) itsTextPane: CAbstractText; { Target text pane for this task} editCmd: Longint; { initiating command, cmdNull for typing} inserted: tTextRange; { info about the inserted text} deleted: tTextRange; { info about the deleted text} originalScrap: Handle; { contents of text scrap, before the task} stillTyping: Boolean; { true if typing is active} doText: Boolean; { TRUE if text should be undone} doClip: Boolean; { TRUE if clipboard should be undone} typingEvent: EventRecord; { event record for last keystroke} procedure ITextEditTask (aTextPane: CAbstractText; anEditCmd: Longint; firstTaskIndex: Integer); procedure DoTask; OVERRIDE; procedure DoTyping (theChar: Char; keyCode: Integer; VAR macEvent: EventRecord); procedure Undo; OVERRIDE; procedure Redo; OVERRIDE; procedure Free; OVERRIDE; procedure CancelTyping; procedure SelectionChanged; function CanStillType: Boolean; procedure DoNormalChar (theChar: Char); procedure DoBackspace; procedure DoFwdDelete; procedure SaveRange (whichRange: tRangeSelector); procedure DeleteRange (whichRange: tRangeSelector); procedure RestoreRange (whichRange: tRangeSelector; killData: Boolean); procedure StoreToClip (whichClip: tClipSelector); end; {****************************************************************************} { CTextStyleTask } {} {****************************************************************************} type CTextStyleTask = object(CTask) itsTextPane: CAbstractText; { target text pane } oldStyle: TextStyle; { original style before command } oldAlignCmd: Longint; { original alignment before command} oldSpacingCmd: Longint; { original spacing before command } styleCmd: Longint; { command that initiated this task } styleAttribute: Integer; { style attributes affected by this task} procedure ITextStyleTask (aTextPane: CAbstractText; aStyleCmd: Longint; taskIndex: Integer); procedure Free; OVERRIDE; procedure DoTask; OVERRIDE; procedure Undo; OVERRIDE; procedure SaveStyle; procedure RestoreStyle; end; const { style modes used by CTextStyleTask in addition to those that} { are defined in TextEdit unit } doAlign = 32; { change text alignment} doSpacing = 64; { change line spacing} {****************************************************************************} { CFile} { } { TCL 1.1 CHANGES} { [} { - changed interface of all methods returning OSErr to void. These} { methods now use the exception mechanism to report failure. If} { you need or prefer the old interface, use the compatibility} { class BFile.} { - added ExistsOnDisk, GetMacFileInfo, SpecifyFSSpec, GetFSSpec,} { and ResolveFileAlias methods} { ]} { } {****************************************************************************} type CFile = object(CObject) name: Str255; volNum: Integer; dirID: Longint; procedure IFile; procedure Free; OVERRIDE; procedure Specify (aName: Str255; aVolNum: Integer); procedure SpecifyHFS (aName: Str255; aVolNum: Integer; aDirID: Longint); procedure SFSpecify (macSFReply: SFReply); procedure SpecifyFSSpec (aFileSpec: FSSpec); procedure ResolveFileAlias; procedure Open (permission: SignedByte); procedure Close; function ExistsOnDisk: Boolean; procedure GetName (var theName: Str255); procedure GetMacFileInfo (var fileInfo: FInfo); procedure GetFSSpec (var aFileSpec: FSSpec); procedure CreateNew (creator: OSType; fType: OSType); procedure ThrowOut; procedure ChangeName (newName: Str255); end; {****************************************************************************} { CDataFile} {} { TCL 1.1 CHANGES} { [} { - changed interface of all methods returning OSErr. Most } { now return void, except GetLength, GetMark, and ReadAll.} { All methods now use the exception mechanism to report failure.} { If you need or prefer the old interface, use the compatibility} { class ODataFile.} { ]} {} {****************************************************************************} type CDataFile = object(CFile) refNum: Integer; procedure IDataFile; procedure SetLength (aLength: Longint); function GetLength: Longint; procedure SetMark (howFar: Longint; fromWhere: Integer); function GetMark: Longint; procedure Open (permission: SignedByte); OVERRIDE; procedure Close; OVERRIDE; function ReadAll: Handle; procedure ReadSome (info: univ Ptr; howMuch: Longint); procedure WriteAll (contents: univ Handle); procedure WriteSome (info: univ Ptr; howMuch: Longint); end; {**************************************************} { GlobalVars} {} { Global Variables for the THINK Class Library} {} {**************************************************} var gApplication: CApplication; { Application object } gDesktop: CDesktop; { The visible Desktop } gBartender: CBartender; { Manages all menus } gClipboard: CClipboard; { Copies and Pastes data } gGopher: CBureaucrat; { First in line to get commands } gError: CError; { Error handler } gDecorator: CDecorator; { Decorator for arranging windows } gSleepTime: longint; { MultiFinder thingy } gHasWNE: Boolean; { Is WaitNextEvent implemented? } gInBackground: Boolean; { In background under MultiFinder } gSignature: OSType; { Creator for Application's files } gLastMouseDown: EventRecord; { Previous mousedown event } gLastMouseUp: EventRecord; { Previous mouseup event } gLastViewHit: CView; { Last view clicked in } gClicks: integer; { Click counter; = 1 single click, } { = 2 double click ,} { etc. } gIBeamCursor: CursHandle; { I-beam for text views } gWatchCursor: CursHandle; { Watch cursor for waiting } gUtilRgn: RgnHandle; { Utility region } {**************************************************} { Utilities} {} { Utility routines used by the THINK Class Library.} { These routines are defined in the implementation section (below)} {} {**************************************************} { Operating System utilities } function TrapAvailable (theTrap: integer): Boolean; EXTERNAL; function WNEIsImplemented: Boolean; function TempMemCallsAvailable: Boolean; function ColorQDIsPresent: Boolean; procedure FlushCache; { TCL 1.1.1 DLP 9/26/91 } { Window Manager utilities } function IsSystemWindow (macWindow: WindowPeek): Boolean; function IsMyWindow (macWindow: WindowPeek): Boolean; procedure BringBehind (macWindow, behindWindow: WindowPtr); { Dialog Manager utilities } function IsDialogWindow (macWindow: WindowPeek): Boolean; procedure PositionDialog (theType: ResType; theID: integer); procedure FindDlogPosition (theType: ResType; theID: integer; var corner: Point); { Font utility } procedure GetFontNumber (fontName: Str255; var fontNum: integer); { Keyboard utility } function KeyIsDown (theKeyCode: integer): Boolean; { QuickDraw utilities } procedure DrawSICN (SICNid, index: integer; location: Point); procedure PinInRect (theRect: LongRect; var thePoint: LongPt); procedure SetHiliteMode; {$IFC MAC68K} inline $08B8, $0007, $0938; { bclr #7 , 0x938 (HiliteMode) } {$ENDC} { other utilities } function HiByte (shortNum: integer): integer; function LoByte (shortNum: integer): integer; function topLeft (aRect: Rect): Point; function Max (val1, val2: longint): longint; function Min (val1, val2: longint): longint; function MenuEnabled (macMenu: MenuHandle): Boolean; function GrowZoneFunc (bytesNeeded: Size): longint; procedure CheckResource (r: Handle); procedure CheckAllocation (p: Ptr); procedure CountClicks (hitView: CView; var macEvent: EventRecord); implementation uses Script, LowMem, Traps; {$IFC POWERPC} procedure CallTheThumbFunc (theScrollBar: CScrollBar; delta: integer; thumbFunc: ControlActionUPP); const TheThumbFunc = $000002C0; { PROCEDURE (4 byte param, 2 byte param); } begin if CallUniversalProc(thumbFunc, TheThumbFunc, theScrollBar, delta) <> 0 then ; end; procedure SetHiliteMode; begin LMSetHiliteMode(0); end; {$ENDC} { Operating System utilities } {**************************************************} { FlushCache TCL 1.1.1 DLP 9/26/91 } { Clear the CPU cache. This is required on 68040 machines } { after modifying code in memory, e.g. when setting up } { a stub code resource for CMenuDefProc } {**************************************************} {$IFC MAC68K} procedure CallCacheFlush; inline $A0BD; procedure FlushCache; { TCL 1.1.1 DLP 9/26/91 } const _CacheFlushTrap = $A0BD; begin if TrapAvailable(_CacheFlushTrap) then CallCacheFlush; end; {$ENDC} {**************************************************} { TrapAvailable} {} { Check whether a certain trap exists on this machine. } { this function uses the new approved method as per IM-VI} { p. 3-8 } {} {**************************************************} function TrapAvailable (theTrap: Integer): Boolean; var UPPForTheUNIMPLEMENTEDProcedure: UniversalProcPtr; UPPForTheTrap: UniversalProcPtr; begin UPPForTheTrap := GetOSTrapAddress(theTrap); UPPForTheUNIMPLEMENTEDProcedure:= GetOSTrapAddress(_Unimplemented); TrapAvailable:= UPPForTheTrap <> UPPForTheUNIMPLEMENTEDProcedure; end; (* function TrapAvailable (theTrap: Integer): Boolean; var tType: TrapType; numToolBoxTraps: Integer; begin { first determine the trap type } if BAND(theTrap, $0800) > 0 then tType := ToolTrap else tType := OSTrap; { next find out how may traps there are } if NGetTrapAddress(_InitGraf, ToolTrap) = NGetTrapAddress($AA6E, ToolTrap) then numToolBoxTraps := $200 else numToolBoxTraps := $400; { check if trap number is too big for current trap table } if tType = ToolTrap then begin theTrap := BAND(theTrap, $07FF); if theTrap >= numToolBoxTraps then theTrap := _Unimplemented; end; { the trap is implemented if its address is different } { from the unimplemented trap's address } TrapAvailable := NGetTrapAddress(theTrap, tType) <> NGetTrapAddress(_Unimplemented, ToolTrap); end; *) {**************************************************} { WNEIsImplemented} {} { See if WaitNextEvent is implemented } {} {**************************************************} function WNEIsImplemented: Boolean; const _WaitNextEvent = $A860; { WaitNextEvent trap } var theWorld: SysEnvRec; { System environment } errCode: OSErr; begin errCode := SysEnvirons(1, theWorld); { Check environment } if theWorld.machineType < 0 then { Old ROMs, definitely not present } WNEIsImplemented := FALSE else { Check for WNE trap } WNEIsImplemented := TrapAvailable(_WaitNextEvent) end; {**************************************************} { TempMemCallsAvailable} {} { Check whether the MultiFinder temporary memory calls are available} {} {**************************************************} function TempMemCallsAvailable: Boolean; const _OSDispatch = $A88F; { Temporary MF memory calls } begin { Check for the OSDispatch trap } TempMemCallsAvailable := TrapAvailable(_OSDispatch); end; {**************************************************} { ColorQDIsPresent} {} { Check whether Color QuickDraw is present} {} {**************************************************} function ColorQDIsPresent: Boolean; var theWorld: SysEnvRec; { System environment } errCode: OSErr; begin errCode := SysEnvirons(1, theWorld); { Check environment } ColorQDIsPresent := theWorld.hasColorQD; { Return environment field } end; { Window Manager utilities } {**************************************************} { IsSystemWindow} {} { Determine if the window belongs to a DA} {} {**************************************************} function IsSystemWindow (macWindow: WindowPeek): Boolean; begin { System windows (DAs) have a negative windowKind } if macWindow <> nil then IsSystemWindow := macWindow^.windowKind < 0 else IsSystemWindow := FALSE; end; {**************************************************} { IsMyWindow} {} { Check whether a window is an application window} {} {**************************************************} function IsMyWindow (macWindow: WindowPeek): Boolean; var wKind: integer; begin { All application windows have a kind >= userKind } if macWindow <> nil then begin wKind := macWindow^.windowKind; IsMyWindow := ((wKind >= userKind) and (wKind < pascalKind)) or (wKind = dialogKind); end else IsMyWindow := FALSE; end; {**************************************************} { BringBehind} {} { Move a window from far back to right behind another window} {} {**************************************************} procedure BringBehind (macWindow, behindWindow: WindowPtr); var savePort: GrafPtr; { Current port } corner: Point; { Top left of visible region } begin GetPort(savePort); { Save current port } SetPort(macWindow); { Use this window's port } { Save portion of window which is originally visible} CopyRgn(macWindow^.visRgn, gUtilRgn); { Adjust the window's plane } SendBehind(macWindow, behindWindow); { We must draw the newly exposed portion of the window. Find the } { difference between the present structure region and what was } { originally visible. Before doing this, we must convert the } { originally visible region to global coords. } corner := gUtilRgn^^.rgnBBox.topLeft; LocalToGlobal(corner); OffsetRgn(gUtilRgn, (corner.h - gUtilRgn^^.rgnBBox.left), (corner.v - gUtilRgn^^.rgnBBox.top)); { Now we can difference the regions. Save space by putting the } { result back in theRgn. Before calling DiffRgn, gUtilRgn is the } { originally visible region. Afterwards, gUtilRgn is the newly } { exposed region of the window. } DiffRgn(WindowPeek(macWindow)^.strucRgn, gUtilRgn, gUtilRgn); { Draw newly exposed region } PaintOne(WindowRef(macWindow), gUtilRgn); { Since window has moved forward, we must adjust the visible } { regions of this window and those behind it. } CalcVisBehind(WindowRef(macWindow), (WindowPeek(macWindow)^.strucRgn)); { Restore the original port } SetPort(savePort); end; { Dialog Manager utilities } {**************************************************} { IsDialogWindow} {} { Determine if the window is a dialog box} {} {**************************************************} function IsDialogWindow (macWindow: WindowPeek): Boolean; begin { Dialog boxes have a windowKind of dialogKind } if macWindow <> nil then IsDialogWindow := macWindow^.windowKind = dialogKind else IsDialogWindow := FALSE; end; {**************************************************} { PositionDialog} {} { Center the bounding box of a dialog or alert in the upper third} { of the screen. This is the preferred location according to the} { Human Interface Guidelines.} {} {**************************************************} procedure PositionDialog (theType: ResType; theID: integer); var theRect: Rect; theRectPtr: RectPtr; { Ptr to bounding box of dialog } theTemplate: Handle; { Handle to resource template } left, { Left side of centered rect } top: integer; { Top side of centered rect } begin { The first field of the resource template for DLOG's and ALRT's } { is its bounding box. Get a pointer to this rectangle. This } { handle dereferencing is safe since the remaining statements in } { this function do not move memory (assignment and simple math). } theTemplate := GetResource(theType, theID); FailNILRes(theTemplate); theRectPtr := RectPtr(theTemplate^); theRect := theRectPtr^; { Center horizontally on screen } left := (qd.screenBits.bounds.right - (theRect.right - theRect.left)) div 2; { Leave twice as much space as above } top := (qd.screenBits.bounds.bottom - (theRect.bottom - theRect.top)) div 3; { Don't put rect under menu bar } if top < GetMBarHeight + 7 then top := GetMBarHeight + 7; theRect.right := theRect.right + left - theRect.left; theRect.left := left; theRect.bottom := theRect.bottom + top - theRect.top; theRect.top := top; theRectPtr^ := theRect; end; {**************************************************} { FindDlogPosition} {} { Return the coordinates of the top left corner of a dialog or alert} { which centers the box in the upper third of the main screen. This is} { the preferred location according to the Human Interface Guidelines.} {} {**************************************************} procedure FindDlogPosition (theType: ResType; theID: integer; var corner: Point); var theRect: Rect; { Bounding box of dialog } left, top: integer; { Left, top side of centered rect } begin { The first field of the resource template for DLOG's and ALRT's } { is its bounding box. Access this rectangle. This } { handle dereferencing is safe since the remaining statements in } { this function do not move memory (assignment and simple math). } theRect := RectHandle(GetResource(theType, theID))^^; { Center horizontally on screen } corner.h := (qd.screenBits.bounds.right - (theRect.right - theRect.left)) div 2; { Leave twice as much space as above } corner.v := (qd.screenBits.bounds.bottom - (theRect.bottom - theRect.top)) div 3; { Don't put rect under menu bar } if corner.v < GetMBarHeight + 7 then corner.v := GetMBarHeight + 7; end; { Font utility } {**************************************************} { GetFontNumber} {} { Find font number given the font name. If not found, a negative} { font number is returned.} {} {**************************************************} procedure GetFontNumber (fontName: Str255; var fontNum: integer); var sysFontName: Str255; begin GetFNum(fontName, fontNum); { Find corresponding font number } if fontNum = systemFont then begin { fontNum is set to sysFont if fontName is not found. } { We must check for the special case where the system } { font is indeed being retrieved, by comparing the name } { of the font with that of the system font. } GetFontName(systemFont, sysFontName); if not EqualString(fontName, sysFontName, FALSE, FALSE) then fontNum := -1; { Font not found } end; end; { Keyboard utility } {**************************************************} { KeyIsDown} {} { Determine whether or not the specified key is being pressed. Keys} { are specified by hardware-specific key code (NOT the character).} {} {**************************************************} function KeyIsDown (theKeyCode: integer): Boolean; var theKeys: KeyMap; begin GetKeys(theKeys); KeyIsDown := theKeys[theKeyCode]; end; { Quickdraw utilities } {**************************************************} { DrawSICN} {} { Draw a SICN, a resource type which defines a 16 by 16 bit image,} { at the given location. SICN is specified by a resource ID number,} { and a one-based index into the SICN list. The location specifies} { the top left corner of the SICN in the local coordinates of the } { current port.} {} {**************************************************} procedure DrawSICN (SICNid: integer; index: integer; location: Point); var theSICN: Handle; theImage: BitMap; theBounds: Rect; begin theSICN := GetResource('SICN', SICNid); FailNILRes(theSICN); HLock(theSICN); { A SICN resource is really a list } { of small icons, each of which } { has 32 bytes of data; } { 16 x 16 = 256 bits = 32 bytes } { } { Create a bitmap so we can copy } { the SICN image on the screen } { } { Index into handle to get a ptr } { to the SICN bit image } theImage.baseAddr := Ptr(LongPtr(theSICN)^ + (index - 1) * 32); theImage.rowBytes := 2; { 16 bits is 2 bytes } { Place bitmap at desired location } SetRect(theBounds, location.h, location.v, location.h + 16, location.v + 16); theImage.bounds := theBounds; { Copy image onto the screen } CopyBits(theImage, qd.thePort^.portBits, theBounds, theBounds, srcCopy, nil); HUnlock(theSICN); end; {**************************************************} { PinInRect} {} { Pin a point inside a rectangle. Similar to the PinRect Toolbox} { trap except that the point is changed in place and one (1) is not} { subtracted at the right and bottom edges.} {} {**************************************************} procedure PinInRect (theRect: LongRect; var thePoint: LongPt); begin thePoint.h := Max(theRect.left, thePoint.h); thePoint.h := Min(theRect.right, thePoint.h); thePoint.v := Max(theRect.top, thePoint.v); thePoint.v := Min(theRect.bottom, thePoint.v); end; { Other utilities } {**************************************************} { HiByte} {} { Return the high byte of an integer} {} {**************************************************} function HiByte (shortNum: integer): integer; begin HiByte := BitAnd(BSR(shortNum, 8), $FF); end; {**************************************************} { LoByte} {} { Return the low byte of an integer} {} {**************************************************} function LoByte (shortNum: integer): integer; begin LoByte := BitAnd(shortNum, $FF); end; {**************************************************} { topLeft} {} { Return the topLeft point of a rect} {} {**************************************************} function topLeft (aRect: Rect): Point; begin topLeft := aRect.topLeft; end; {**************************************************} { Max} {} { Return the maximum of two values} {} {**************************************************} function Max (val1, val2: longint): longint; begin if val1 < val2 then Max := val2 else Max := val1 end; {**************************************************} { Min} {} { Return the minimum of two values} {} {**************************************************} function Min (val1, val2: longint): longint; begin if val1 < val2 then Min := val1 else Min := val2 end; {**************************************************} { MenuEnabled} {} { Determine whether or not the given menu is enabled} {} {**************************************************} function MenuEnabled (macMenu: MenuHandle): Boolean; begin MenuEnabled := BAND(macMenu^^.enableFlags, 1) <> 0; end; {**************************************************} { GrowZoneFunc} {} { Called by the System when a memory request can't be filled. Send } { GrowMemory message to the Application. The bracketing calls to } { the Toolbox traps SetCurrentA5 and SetA5 are required because we } { don't know if A5 is set up properly. See TechNotes 136 and 208. } {} {**************************************************} function GrowZoneFunc (bytesNeeded: Size): longint; var result: longint; { Success or failure code } dontMove: Handle; { Block which we must not move } saveHState: SignedByte; {Original attributes of dontMove } oldA5, temp: longint; begin oldA5 := SetCurrentA5; dontMove := GZSaveHnd; if dontMove <> nil then begin saveHState := HGetState(dontMove); HLock(dontMove); end; result := gApplication.GrowMemory(bytesNeeded); if dontMove <> nil then HSetState(dontMove, saveHState); GrowZoneFunc := result; temp := SetA5(oldA5); end; {**************************************************} { CheckResource } {} { Check for a nil resource handle, which indicates that a resource } { could not be found or read into memory. If handle is nil, post } { a severe error alert. } {} {**************************************************} procedure CheckResource (r: Handle); begin if r = nil then gError.SevereMacError(resNotFound); end; {**************************************************} { CheckAllocation } {} { Check for a nil pointer or handle, which indicates that a } { requested memory block could not be allocated. } {} {**************************************************} procedure CheckAllocation (p: Ptr); begin if p = nil then gError.SevereMacError(MemError); end; {**************************************************} { CountClicks } {} { Check if mouse down event is part of a multiple click } {} {**************************************************} procedure CountClicks (hitView: CView; var macEvent: EventRecord); begin if (hitView = gLastViewHit) & ((macEvent.when - gLastMouseUp.when) < GetDblTime) & (hitView.HitSamePart(gLastMouseDown.where, macEvent.where)) then gClicks := gClicks + 1 else gClicks := 1; gLastViewHit := hitView; end; {****************************************************************************} { QDToLongPt} { } { Convert a Point to a LongPt} {****************************************************************************} procedure QDToLongPt (srcPt: Point; var destPt: LongPt); begin destPt.h := srcPt.h; destPt.v := srcPt.v; end; {****************************************************************************} { LongToQDPt} { } { Convert a LongPt to a Point. Values are clipped to 16 bits.} {****************************************************************************} procedure LongToQDPt (srcPt: LongPt; var destPt: Point); begin destPt.h := Min(Max(MININT, srcPt.h), MAXINT); destPt.v := Min(Max(MININT, srcPt.v), MAXINT); end; {****************************************************************************} { SetLongPt} { } { Set the members of a LongPt. } {****************************************************************************} procedure SetLongPt (var pt: LongPt; h: Longint; v: Longint); begin pt.h := h; pt.v := v; end; {****************************************************************************} { AddLongPt} { } { Adds srcPt and destPt, returns the result in destPt.} {****************************************************************************} procedure AddLongPt (srcPt: LongPt; var destPt: LongPt); begin destPt.h := destPt.h + srcPt.h; destPt.v := destPt.v + srcPt.v; end; {****************************************************************************} { SubLongPt} { } { Subtracts srcPt from destPt, returns the result in destPt.} {****************************************************************************} procedure SubLongPt (srcPt: LongPt; var destPt: LongPt); begin destPt.h := destPt.h - srcPt.h; destPt.v := destPt.v - srcPt.v; end; {****************************************************************************} { EqualLongPt} { } { Returns TRUE if two LongPts are equal.} {****************************************************************************} function EqualLongPt (pt1: LongPt; pt2: LongPt): Boolean; begin EqualLongPt := (pt1.h = pt2.h) and (pt1.v = pt2.v); end; {****************************************************************************} { PtInQDSpace} { } { Returns TRUE if a LongPt is within the 16-bit QuickDraw coordinate space} {****************************************************************************} function PtInQDSpace (pt: LongPt): Boolean; begin PtInQDSpace := ((pt.h >= MININT) and (pt.h <= MAXINT) and (pt.v >= MININT) and (pt.v <= MAXINT)); end; {****************************************************************************} { QDToLongRect} { } { Convert a Rect to a LongRect} {****************************************************************************} procedure QDToLongRect (srcRect: Rect; var destRect: LongRect); begin destRect.left := srcRect.left; destRect.top := srcRect.top; destRect.right := srcRect.right; destRect.bottom := srcRect.bottom; end; {****************************************************************************} { LongToQDRect} { } { Convert aLongRect to a Rect. Values are clipped to 16 bit QuickDraw space.} {****************************************************************************} procedure LongToQDRect (srcRect: LongRect; var destRect: Rect); begin destRect.left := Min(Max(MININT, srcRect.left), MAXINT); destRect.top := Min(Max(MININT, srcRect.top), MAXINT); destRect.right := Min(Max(MININT, srcRect.right), MAXINT); destRect.bottom := Min(Max(MININT, srcRect.bottom), MAXINT); end; {****************************************************************************} { SetLongRect} { } { Fill in the members of a LongRect.} {****************************************************************************} procedure SetLongRect (var r: LongRect; left: Longint; top: Longint; right: Longint; bottom: Longint); begin r.left := left; r.right := right; r.top := top; r.bottom := bottom; end; {****************************************************************************} { OffsetLongRect} { } { Translates a LongRect. Positive values are to the right and down.} {****************************************************************************} procedure OffsetLongRect (var r: LongRect; dh: Longint; dv: Longint); begin r.left := r.left + dh; r.right := r.right + dh; r.top := r.top + dv; r.bottom := r.bottom + dv; end; {****************************************************************************} { InsetLongRect} { } { Insets the sides of a LongRect. Positive values move the sizes inward.} {****************************************************************************} procedure InsetLongRect (var r: LongRect; dh: Longint; dv: Longint); begin r.left := r.left + dh; r.right := r.right - dh; r.top := r.top + dv; r.bottom := r.bottom - dv; end; {****************************************************************************} { SectLongRect} { } { Calculates the intersection of two LongRects and returns the result} { in destRect. destRect may be the same as either src1 or src2. Returns TRUE} { if the result is non-empty.} {****************************************************************************} function SectLongRect (src1: LongRect; src2: LongRect; var destRect: LongRect): Boolean; begin destRect.left := Max(src1.left, src2.left); destRect.right := Min(src1.right, src2.right); destRect.top := Max(src1.top, src2.top); destRect.bottom := Min(src1.bottom, src2.bottom); SectLongRect := not EmptyLongRect(destRect); end; {****************************************************************************} { UnionLongRect} { } { Calculates the union of two LongRects and returns the result} { in destRect. destRect may be the same as either src1 or src2.} {****************************************************************************} procedure UnionLongRect (src1: LongRect; src2: LongRect; var destRect: LongRect); begin destRect.left := Min(src1.left, src2.left); destRect.right := Max(src1.right, src2.right); destRect.top := Min(src1.top, src2.top); destRect.bottom := Max(src1.bottom, src2.bottom); end; {****************************************************************************} { PtInLongRect} { } { Returns TRUE if pt lies within r.} {****************************************************************************} function PtInLongRect (pt: LongPt; r: LongRect): Boolean; begin PtInLongRect := ((pt.h >= r.left) and (pt.h < r.right) and (pt.v >= r.top) and (pt.v < r.bottom)); end; {****************************************************************************} { Pt2LongRect} { } { Calculates the minimal rect enclosing the two given points.} {****************************************************************************} procedure Pt2LongRect (pt1: LongPt; pt2: LongPt; var r: LongRect); begin r.left := Min(pt1.h, pt2.h); r.top := Min(pt1.v, pt2.v); r.right := Max(pt1.h, pt2.h); r.bottom := Max(pt1.v, pt2.v); end; {****************************************************************************} { EqualLongRect} { } { Returns true if r1 and r2 are equal.} {****************************************************************************} function EqualLongRect (r1: LongRect; r2: LongRect): Boolean; begin EqualLongRect := EqualLongPt(r1.topLeft, r2.topLeft) & EqualLongPt(r1.botRight, r2.botRight); end; {****************************************************************************} { EmptyLongRect} { } { Returns TRUE if r encloses no points.} {****************************************************************************} function EmptyLongRect (r: LongRect): Boolean; begin EmptyLongRect := ((r.top >= r.bottom) or (r.left >= r.right)); end; {****************************************************************************} { RectInQDSpace} { } { Returns TRUE if r is entirely within QD space.} {****************************************************************************} function RectInQDSpace (r: LongRect): Boolean; begin RectInQDSpace := PtInQDSpace(r.topLeft) & PtInQDSpace(r.botRight); end; {****************************************************************************} { AbortInQueue} { } { Walk the event queue, return TRUE if a Command-'.' is there. The} { event is removed from the queue.} { } {****************************************************************************} function AbortInQueue: Boolean; { TCL 1.1.1 DLP 9/25/91 } type EventRecordPtr = ^EventRecord; var qEvt: EvQElPtr; foundAbort: Boolean; begin foundAbort := FALSE; qEvt := EvQElPtr(GetEvQHdr^.qHead); while qEvt <> nil do begin if IsCancelEvent(EventRecordPtr(@qEvt^.evtQWhat)^) then begin { Flush all keydown events from the event queue } { This will get rid of the abort as well as } { any other pending keydowns } FailOSErr(Dequeue(QElemPtr(qEvt), GetEvQHdr)); foundAbort := TRUE; LEAVE; end; qEvt := EvQElPtr(qEvt^.qLink); end; AbortInQueue := foundAbort; end; function IsCancelEvent (VAR theEvent: EventRecord): Boolean; const kMaskModifiers = $FE00; { we need the modifiers without the } { command key for KeyTrans } kUpKeyMask = $0080; kMaskASCII1 = $00FF0000; { get the key out of the ASCII1 byte } kMaskASCII2 = $000000FF; { get the key out of the ASCII2 byte } var isCancel: Boolean; keyCode: Integer; virtualKey, keyInfo, lowChar, highChar, state, keyCId: Longint; hKCHR: Handle; KCHRPtr: Ptr; begin isCancel := FALSE; hKCHR := nil; if (theEvent.what = keyDown) | (theEvent.what = autoKey) then begin { see if the command key is down. If it is, find out the ASCII } { equivalent for the accompanying key. } if BAND(theEvent.modifiers, cmdKey) <> 0 then begin { get virtual key and keycode for KeyTrans } virtualKey := BSR(BAND(theEvent.message, keyCodeMask), 8); { and out the command key and or in the virtualKey } keyCode := BOR(BAND(theEvent.modifiers, kMaskModifiers), virtualKey); { make it look like a keyup event, to prevent dead key processing } keyCode := BOR(keyCode, kUpKeyMask); KCHRPtr := Ptr(GetScriptManagerVariable(smKCHRCache)); if KCHRPtr = nil then begin keyCId := GetScriptVariable(GetScriptManagerVariable(smKeyScript), smScriptKeys); hKCHR := GetResource('KCHR', keyCId); KCHRPtr := hKCHR^; end; if KCHRPtr <> nil then begin state := 0; keyInfo := KeyTranslate(KCHRPtr, keyCode, state); if hKCHR <> nil then ReleaseResource(hKCHR); end else keyInfo := theEvent.message; lowChar := BAND(keyInfo, kMaskASCII2); highChar := BSR(BAND(keyInfo, kMaskASCII1), 16); if (lowChar = ord('.')) | (highChar = ord('.')) then isCancel := true; end; end; IsCancelEvent := isCancel; end; {****************************************************************************} { TCLUtilities} {****************************************************************************} {****************************************************************************} { ErrorAlert} { } { Displays an alert for the given error and message codes. The error message} { may be customized as follows:} { } { - If the low word of the message is non-zero, it is assumed to be} { the index of a string in a STR# resource.} { } { - if the high word of the message is zero, the STR# ID is the} { TCL's private STR# 301} { } { - if the high word is non-zero, it is taken as an offset from the} { base ID of 1024. For example, if the message is 2,563, or $0A03 hex,} { the high word is 10 decimal and low word is 3 decimal. Since the high} { word is non-zero it is added to 1024. The TCL will do a } { GetIndString( string, 1034, 3) to get the error string.} { } { The SpecifyMsg function in Exceptions.c will build the message longword} { for you. SpecifyMsg( 1034, 3) returns 2,563.} { } { - if the low word of the message is zero the TCL looks for an 'Estr' } { resource matching the error. If none is found, a generic error string } { is used.} { } {****************************************************************************} procedure ErrorAlert (error: Integer; message: Longint); var errStr: Str255; numStr: Str255; strIndex: Integer; strID: Integer; alertID: Integer; itemHit: Integer; strH: StringHandle; begin errStr := ''; { mark string empty } {) { * First see if anyone filled in the} { * message field} { } { string index goes in low word of message } strIndex := LoWord(message); if (strIndex > 0) then begin { the STR# resource ID is either 131 or some value specified from } { an implicit base value of 1024 } strID := HiWord(message); if (strID = 0) then strID := STR_TCLfailMsgs else strID := strID + kUserFailMsgBase; GetIndString(errStr, strID, strIndex); end; if Length(errStr) = 0 then begin { Next, see if there is a custom 'Estr' resource for the error. } { If there isn't just get the default error string. } strH := StringHandle(GetResource(ErrMsg_Res, error)); if (strH = nil) then strH := GetString(STRosError2); if (strH <> nil) then errStr := strH^^; end; NumToString(error, numStr); ParamText(errStr, numStr, '', ''); if (gApplication = nil) | (gApplication.GetPhase <> appRunning) then alertID := ALRT_ExceptionAbort else alertID := ALRT_Exception; { avoid infinite recursion if the ALRT resource is missing by } { testing for it here. } if (GetResource('ALRT', alertID) = nil) | (GetResource('DITL', alertID) = nil) then begin if gError <> nil then gError.MissingResources else ExitToShell; { nothing else we can do... } end; PositionDialog('ALRT', alertID); InitCursor; itemHit := StopAlert(alertID, nil) end; {****************************************************************************} { NewHandleCanFail} {} { Attempts to allocate a handle without drawing upon the memory reserve.} { Raises an exception if the allocation fails.} {****************************************************************************} function NewHandleCanFail (size: Longint): Handle; var h: Handle; savedAlloc: Boolean; begin savedAlloc := SetAllocation(kAllocCanFail); h := NewHandle(size); savedAlloc := SetAllocation(savedAlloc); NewHandleCanFail := h; end; {****************************************************************************} { ResizeHandleCanFail} {} { Attempts to resize a handle without drawing upon the memory reserve.} { Raises an exception if the allocation fails.} {} {****************************************************************************} procedure ResizeHandleCanFail (theHandle: univ Handle; newSize: Longint); var savedAlloc: Boolean; begin savedAlloc := SetAllocation(kAllocCanFail); SetHandleSize(theHandle, newSize); savedAlloc := SetAllocation(savedAlloc); { MemError now has error code, caller can FailMemError } end; {****************************************************************************} { SetAllocation} {} { Changes the parameters gApplication uses when the grow zone function is} { invoked. This happens when the Memory Mgr can't satisfy a requested} { memory allocation. This method also returns the previous setting, } { so you can do something like:} {} { Boolean oldAlloc := SetAllocation( kAllocCanFail);} {} { ...attempt something that could fail gracefully...} {} { SetAllocation( oldAlloc);} {} { If canFail is TRUE, this function does gApplication->RequestMemory( no loan, can fail)} { otherwise it does gApplication->RequestMemory( no loan, can't fail),} { i.e. this utility always sets loan approved FALSE.} {} {****************************************************************************} function SetAllocation (canFail: Boolean): Boolean; var oldFail: Boolean; begin oldFail := gApplication.canFail; gApplication.RequestMemory(canFail); SetAllocation := oldFail; end; {****************************************************************************} {SetCriticalOperation} {Changes the parameters gApplication uses when the grow zone function} {is called. If the application is in a critical operation, then more } {of the memory reserve is eligible to be released to satisfy a memory} {request.} {****************************************************************************} procedure SetCriticalOperation (aCriticalOp: Boolean); begin gApplication.SetCriticalOperation(aCriticalOp); end; {****************************************************************************} { ForgetHandle} { } { If the handle isn't already NIL, it disposes of the handle and NILs it.} {****************************************************************************} procedure ForgetHandle (var h: univ Handle); var hndl: Handle; begin hndl := h; if (hndl <> nil) then begin h := nil; DisposeHandle(hndl); end; end; {****************************************************************************} { ForgetObject} { } { If the object isn't already NIL, it sends it a Dispose message, then} { NILs it.} {****************************************************************************} procedure ForgetObject (var obj: univ CObject); var theObj: CObject; begin theObj := obj; if (theObj <> nil) then begin obj := nil; theObj.Free; end; end; {****************************************************************************} { ForgetPtr} { } { If the pointer isn't already NIL, it disposes of the pointer and NILs it.} {****************************************************************************} procedure ForgetPtr (var p: univ Ptr); var thePtr: Ptr; begin thePtr := p; if (thePtr <> nil) then begin p := nil; DisposePtr(thePtr); end; end; {****************************************************************************} { ForgetResource} { } { If the resource isn't already NIL, it releases and NILs it.} {****************************************************************************} procedure ForgetResource (var res: univ Handle); var theRes: Handle; begin theRes := res; if (theRes <> nil) then begin res := nil; ReleaseResource(theRes); end; end; {****************************************************************************} { SetMinimumStack} { } { Sets the stack to at least minSize. Only call this once, as the very} { first statement in your program} {****************************************************************************} procedure SetMinimumStack (minSize: Longint); var defaultStack: LongIntPtr; newApplLimit: Longint; begin defaultStack := LongIntPtr(LMGetDefltStack); if (minSize > defaultStack^) then begin newApplLimit := ord4(GetApplLimit) - (minSize - defaultStack^); SetApplLimit(Ptr(newApplLimit)); end; end; {****************************************************************************} { %_ALLOCOBJ} { } { Called by TCLRuntime.lib to allocate a handle for an object. This } { routine attempts to allocate the handle without hitting into the } { toolbox memory reserve, and calls raises an exception if the } { allocation failed. } {****************************************************************************} {$PUSH} {$Z+} function _ALLOCOBJ (objSize: Longint): Handle; var obj: Handle; savedAlloc: Boolean; begin if (gApplication <> nil) then begin savedAlloc := SetAllocation(kAllocCanFail); obj := NewHandleClear(objSize); savedAlloc := SetAllocation(savedAlloc); FailNIL(obj); end else obj := NewHandleClear(objSize); _ALLOCOBJ := obj; end; {****************************************************************************} { %_FAILEDDISPATCH} { } { Called by TCLRuntime.lib if an error was detected during method } { dispatch. An error code of kBadObj means the object handle was } { NIL or odd. An error code of kLookupFailed means that a } { method with the given selector wasn't found. This may happen } { if you use a disposed or corrupted object. } { All dispatch errors raise an exception. } {****************************************************************************} procedure _FAILEDDISPATCH (errCode: Integer); const kBadObj = 1; kLookupFailed = 2; begin if (errCode = kBadObj) then Failure(paramErr, excMsgNullObject) else if (errCode = kLookupFailed) then Failure(paramErr, excMsgLookupFailed) else Failure(errCode, 0); end; {****************************************************************************} { %_OBDISP} { } { Called by TCLRuntime.lib to dispose of an object handle } {****************************************************************************} procedure _OBDISP (var obj: CObject); begin if (obj = nil) | odd(Longint(obj)) then Failure(excMsgNullObject, 0); DisposeHandle(Handle(obj)); obj := nil; end; {$POP} {****************************************************************************} { ForceNextPrepare} {} { Clear cPreparedView to force the next Prepare to do a full Prepare.} {****************************************************************************} procedure ForceNextPrepare; begin cPreparedView := nil; end; procedure ExitApplication; begin if (gApplication <> nil) then gApplication.ExitApp; ExitToShell; end; function ApplicationIsRunning: Boolean; begin ApplicationIsRunning := (gApplication <> nil) & (gApplication.GetPhase = appRunning); end; end.