Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Sources/MSWindow.c
// MSWindow.c |
// |
// Original version by Jon Lansdell and Nigel Humphreys. |
// 4.0 and 3.1 updates by Greg Sutton. |
// ©Apple Computer Inc 1996, all rights reserved. |
/* |
Changes for 3.1 : |
12-Oct-95 : CW : Cleaned up DoContent and added call to DoWindowContentDrag |
Clean up CloseMyWindow and added call to RemoveDragHandlers |
Added InstallDragHandlers call to NewDocument |
Use HiliteControl on suspend/resume instead of Show/HideControl |
1-Nov-95 : DS : Made Changes for GX Printing. |
Changes for 4.0 : |
17-Apr-96 : GS : Changed pascal calling conventions to C where possible. |
*/ |
#include <Scrap.h> |
#include <Packages.h> |
#ifdef THINK_C |
#include "PLStrs.h" |
#else |
#include <PLStringFuncs.h> |
#endif |
#include <GXPrinting.h> |
#include <PrintingMessages.h> |
#include "MSWindow.h" |
#include "MSMain.h" |
#include "MSDrag.h" |
#include "MSAERecording.h" |
#include "MSGXPrinting.h" |
#include "MSResultWind.h" |
#include "MSAEWindowUtils.h" |
#define kControlInvisible 0 |
#define kControlVisible 0xFF |
#define kScrollbarWidth 16 |
#define kScrollbarAdjust (kScrollbarWidth - 1) |
#define kScrollTweek 2 |
#define kTextOffset 5 |
#define kButtonScroll 10 |
#define kHOffset 20 // Stagger window offsets |
#define kVOffset 20 |
#define kTBarHeight 20 |
#define kMBarHeight 20 |
#pragma segment Window |
DPtr DPtrFromWindowPtr(WindowPtr theWindow) |
{ |
if ( theWindow && IsDocumentWindow( theWindow ) ) |
return((DPtr)GetWRefCon(theWindow)); |
else |
return(NULL); |
} // DPtrFromWindowPtr |
#pragma segment main |
// Scroll the TERec around to match up to the potentially updated scrollbar |
// values. This is really useful when the window resizes such that the |
// scrollbars become inactive and the TERec had been previously scrolled. |
void AdjustTE( DPtr theDoc ) |
{ |
short h; |
short v; |
TEHandle myText; |
myText = theDoc->theText; |
h = ((*myText)->viewRect.left - (*myText)->destRect.left) - |
GetCtlValue(theDoc->hScrollBar) + kTextOffset; |
v = ((*myText)->viewRect.top - (*myText)->destRect.top) - |
GetCtlValue(theDoc->vScrollBar) + kTextOffset; |
if (h || v) |
{ |
TEScroll(h, v, theDoc->theText); |
DrawPageExtras(theDoc); |
} |
} // AdjustTE |
// Calculate the new control maximum value and current value, whether it is the horizontal or |
// vertical scrollbar. The vertical max is calculated by comparing the number of lines to the |
// vertical size of the viewRect. The horizontal max is calculated by comparing the maximum document |
// width to the width of the viewRect. The current values are set by comparing the offset between |
// the view and destination rects. If necessary and we canRedraw, have the control be re-drawn by |
// calling ShowControl. |
// TEStyleSample-vertical max originally used line by line calculations-lineheight was a |
// constant value so it was easy to figure out what the range should be and pin the value |
// within range. Now we need to use max and min values in pixels rather than in nlines. |
#pragma segment main |
void AdjustHV( Boolean isVert, ControlHandle control, DPtr theDoc, Boolean canRedraw ) |
{ |
TEHandle docTE; |
short value; |
short max; |
short oldValue; |
short oldMax; |
Rect sizeRect; |
GetRectOfPage( theDoc, &sizeRect ); |
docTE = theDoc->theText; |
oldValue = GetCtlValue(control); |
oldMax = GetCtlMax(control); |
if (isVert) |
{ |
// new for TEStyleSample |
max = TEGetHeight((*docTE)->nLines, 0, docTE) - |
((*docTE)->viewRect.bottom - (*docTE)->viewRect.top); |
} |
else |
max = sizeRect.right - ((*docTE)->viewRect.right - (*docTE)->viewRect.left); |
max += kTextOffset + kTextOffset; // Allow over scroll by kTextOffset |
if (max < 0) |
max = 0; // check for negative values |
SetCtlMax(control, max); |
if (isVert) |
value = (*docTE)->viewRect.top - (*docTE)->destRect.top; |
else |
value = (*docTE)->viewRect.left - (*docTE)->destRect.left; |
value += kTextOffset; |
if (value < 0) |
value = 0; |
else |
if (value > max) |
value = max; // pin the value to within range |
SetCtlValue(control, value); |
if (canRedraw && ((max != oldMax) || (value != oldValue))) |
ShowControl(control); // check to see if the control can be re-drawn |
} // AdjustHV |
#pragma segment Main |
// Simply call the common adjust routine for the vertical and horizontal scrollbars. |
void AdjustScrollValues( DPtr theDoc, Boolean canRedraw ) |
{ |
AdjustHV(true, theDoc->vScrollBar, theDoc, canRedraw); |
AdjustHV(false, theDoc->hScrollBar, theDoc, canRedraw); |
} // AdjustScrollValues |
// Return a rectangle that is inset from the portRect by the size of |
// the scrollbars and a little extra margin. |
void GetTERect( WindowPtr window, Rect *teRect ) |
{ |
*teRect = window->portRect; |
(*teRect).bottom -= kScrollbarAdjust; // and for the scrollbars |
(*teRect).right -= kScrollbarAdjust; |
} // GetTERect |
// Re-calculate the position and size of the viewRect and the scrollbars. |
// kScrollTweek compensates for off-by-one requirements of the scrollbars |
// to have borders coincide with the growbox. |
void AdjustScrollSizes( DPtr theDoc ) |
{ |
Rect teRect; |
Rect myPortRect; |
GetTERect(theDoc->theWindow, &teRect); // start with teRect |
myPortRect = theDoc->theWindow->portRect; |
(*(theDoc->theText))->viewRect = teRect; |
MoveControl(theDoc->vScrollBar, myPortRect.right - kScrollbarAdjust, - 1); |
SizeControl(theDoc->vScrollBar, |
kScrollbarWidth, |
(myPortRect.bottom - myPortRect.top) - (kScrollbarAdjust - kScrollTweek)); |
MoveControl(theDoc->hScrollBar, - 1, myPortRect.bottom - kScrollbarAdjust); |
SizeControl(theDoc->hScrollBar, |
(myPortRect.right - myPortRect.left) - (kScrollbarAdjust - kScrollTweek), |
kScrollbarWidth); |
} // AdjustScrollSizes |
#pragma segment Window |
// Turn off the controls by jamming a zero into their contrlVis fields |
// (HideControl erases them and we don't want that). If the controls are to |
// be resized as well, call the procedure to do that, then call the procedure |
// to adjust the maximum and current values. Finally reset the controls |
// to be visible if not in background. |
void AdjustScrollbars( DPtr theDoc, Boolean needsResize ) |
{ |
(*(theDoc->vScrollBar))->contrlVis = kControlInvisible; // turn them off |
(*(theDoc->hScrollBar))->contrlVis = kControlInvisible; |
if (needsResize) // move and size if needed |
AdjustScrollSizes(theDoc); |
AdjustScrollValues(theDoc, !needsResize); // fool with max and current value |
// Now, restore visibility in case we never had to ShowControl during adjustment |
if (!gInBackground) |
{ |
(*(theDoc->vScrollBar))->contrlVis = kControlVisible; // turn them on |
(*(theDoc->hScrollBar))->contrlVis = kControlVisible; |
} |
else |
{ // make sure they stay invisible |
if ((*(theDoc->vScrollBar))->contrlVis) |
HideControl(theDoc->vScrollBar); |
if ((*(theDoc->vScrollBar))->contrlVis) |
HideControl(theDoc->hScrollBar); |
} |
} // AdjustScrollbars |
#pragma segment Window |
void GetWinContentRect( WindowPtr theWindow, Rect *r ) |
{ |
*r = theWindow->portRect; |
r->right -= kScrollbarAdjust; |
r->bottom -= kScrollbarAdjust; |
} // GetWinContentRect |
#pragma segment Window |
void InvalidateDocument( DPtr theDoc ) |
{ |
GrafPtr oldPort; |
GetPort(&oldPort); |
SetPort(theDoc->theWindow); |
InvalRect(&theDoc->theWindow->portRect); |
SetPort(oldPort); |
} |
// Called when the window has been resized to fix up the controls and content. |
void ResizeWindow( DPtr theDoc ) |
{ |
AdjustScrollbars(theDoc, true); |
AdjustTE(theDoc); |
InvalidateDocument(theDoc); |
} // ResizeWindow |
// Called when the window has been resized to fix up the controls and content |
void ResizePageSetupForDocument( DPtr theDoc ) |
{ |
Rect pageRect; |
GetRectOfPage( theDoc, &pageRect ); |
(*(theDoc->theText))->destRect.right = (*(theDoc->theText))->destRect.left + pageRect.right; |
TECalText(theDoc->theText); |
ResizeWindow(theDoc); |
} // ResizePageSetupForDocument |
#pragma segment Main |
// Common algorithm for setting the new value of a control. It returns the actual amount |
// the value of the control changed. Note the pinning is done for the sake of returning |
// the amount the control value changed. |
void CommonAction( ControlHandle control, short *amount ) |
{ |
short value; |
short max; |
value = GetCtlValue(control); // get current value |
max = GetCtlMax(control); // and max value |
*amount = value - *amount; |
if (*amount < 0) |
*amount = 0; |
else if (*amount > max) |
*amount = max; |
SetCtlValue(control, *amount); |
*amount = value - *amount; // calculate true change |
} // CommonAction |
#pragma segment Main |
// Determines how much to change the value of the vertical scrollbar by and how |
// much to scroll the TE record. |
pascal void VActionProc( ControlHandle control, short part ) |
{ |
short amount; |
WindowPtr window; |
DPtr theDoc; |
if ( part ) |
{ |
window = (*control)->contrlOwner; |
theDoc = DPtrFromWindowPtr(window); |
switch (part) |
{ |
case inUpButton: |
case inDownButton: |
amount = 24; |
break; |
case inPageUp: |
case inPageDown: |
amount = (*(theDoc->theText))->viewRect.bottom - |
(*(theDoc->theText))->viewRect.top; |
break; |
} // case |
if (part == inDownButton || part == inPageDown) |
amount = -amount; // reverse direction |
CommonAction(control, &amount); |
if (amount) |
{ |
TEScroll(0, amount, theDoc->theText); |
DrawPageExtras(theDoc); |
} |
} // if |
} // VActionProc |
#pragma segment Main |
// Determines how much to change the value of the horizontal scrollbar by and how |
// much to scroll the TE record. |
pascal void HActionProc(ControlHandle control, short part) |
{ |
short amount; |
WindowPtr window; |
DPtr theDoc; |
if ( part ) |
{ |
window = (*control)->contrlOwner; |
theDoc = DPtrFromWindowPtr(window); |
switch ( part ) |
{ |
case inUpButton: |
case inDownButton: |
amount = kButtonScroll; // a few pixels |
break; |
case inPageUp: |
case inPageDown: |
amount = (*(theDoc->theText))->viewRect.right - |
(*(theDoc->theText))->viewRect.left; // a page |
break; |
} // switch |
if (part == inDownButton || part == inPageDown) |
amount = - amount; // reverse direction |
CommonAction(control, &amount); |
if (amount) |
{ |
TEScroll(amount, 0, theDoc->theText); |
DrawPageExtras(theDoc); |
} |
} // if |
} // HActionProc |
// Name: ShowSelect |
// Purpose: Scrolls the text selection into view. |
#pragma segment Window |
void ShowSelect( DPtr theDoc ) |
{ |
AdjustScrollbars(theDoc, false); |
// Let TextEdit do the hard work of keeping the selection visibleÉ |
TEAutoView(true, theDoc->theText); |
TESelView(theDoc->theText); |
TEAutoView(false, theDoc->theText); |
// Now rematch the text and the scrollbarsÉ |
SetCtlValue(theDoc->hScrollBar, |
(*(theDoc->theText))->viewRect.left - |
(*(theDoc->theText))->destRect.left + kTextOffset); |
SetCtlValue(theDoc->vScrollBar, |
(*(theDoc->theText))->viewRect.top - |
(*(theDoc->theText))->destRect.top + kTextOffset); |
} // ShowSelect |
#pragma segment Window |
void OffsetWindow( WindowPtr aWindow ) |
{ |
short theWidth; |
short theHeight; |
short theHScreen; |
short theVScreen; |
short xWidth; |
short xHeight; |
short hMax; |
short vMax; |
short wLeft; |
short wTop; |
long docCount; |
theWidth = aWindow->portRect.right - aWindow->portRect.left; |
theHeight = aWindow->portRect.bottom - aWindow->portRect.top + kTBarHeight; |
theHScreen = qd.screenBits.bounds.right - qd.screenBits.bounds.left; |
theVScreen = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top; |
xWidth = theHScreen - theWidth; |
xHeight = theVScreen - (theHeight + kMBarHeight); |
hMax = (xWidth / kVOffset) + 1; |
vMax = (xHeight / kVOffset) + 1; |
docCount = CountDocuments( ); |
if ( ! IsVisible( aWindow ) ) |
docCount++; // Offset has been called on a window still hidden |
wLeft = ( docCount % hMax ) * kVOffset; |
wTop = ( ( docCount % vMax ) * kVOffset ) + kTBarHeight + kMBarHeight; |
MoveWindow(aWindow, wLeft, wTop, false); |
} |
/* |
// Returns the update region in local coordinates. |
void GetLocalUpdateRgn( WindowPtr window, RgnHandle localRgn ) |
{ |
CopyRgn(((WindowPeek)window)->updateRgn, localRgn); // save old update region |
OffsetRgn(localRgn, |
window->portBits.bounds.left, |
window->portBits.bounds.top); // convert to local coords |
} // GetLocalUpdateRgn |
*/ |
#pragma segment Window |
void MyGrowWindow( WindowPtr w, Point p ) |
{ |
GrafPtr savePort; |
long theResult; |
Rect r; |
GetPort(&savePort); |
SetPort(w); |
SetRect(&r, 80, 80, qd.screenBits.bounds.right, qd.screenBits.bounds.bottom); |
theResult = GrowWindow(w, p, &r); |
if (theResult) |
IssueSizeWindow(w, LoWord(theResult), HiWord(theResult)); |
SetPort(savePort); |
} |
#pragma segment Window |
// Because windows can be hidden we must check for menu changes |
void ShowMSWindow( WindowPtr theWindow ) |
{ |
ShowWindow( theWindow ); |
if ( FrontWindow( ) == theWindow ) |
{ |
DoActivate( GetNthWindow( 2 ), false ); |
DoActivate( theWindow, true ); |
} |
CheckMenus( ); |
} |
void HideMSWindow( WindowPtr theWindow ) |
{ |
Boolean fActivate; |
fActivate = ( FrontWindow( ) == theWindow ); |
HideWindow( theWindow ); |
if ( fActivate ) |
{ |
DoActivate( theWindow, false ); |
DoActivate( GetNthWindow( 1 ), true ); |
} |
CheckMenus( ); |
} |
#pragma segment Window |
void DoZoom( WindowPtr w, short c, Point p ) |
{ |
GrafPtr savePort; |
GetPort(&savePort); |
SetPort(w); |
if (TrackBox(w, p, c)) |
{ |
EraseRect(&w->portRect); |
IssueZoomCommand(w, c); |
} |
} |
#pragma segment Window |
void DoContent( WindowPtr theWindow, EventRecord theEvent ) |
{ |
short cntlCode; |
short part; |
short value; |
ControlHandle theControl; |
GrafPtr savePort; |
Boolean extend; |
DPtr theDoc; |
Point localPt; |
GetPort ( &savePort ); |
SetPort ( theWindow ); |
theDoc = DPtrFromWindowPtr ( theWindow ); |
localPt = theEvent.where; |
GlobalToLocal ( &localPt ); |
cntlCode = FindControl ( localPt, theWindow, &theControl ); |
if ( cntlCode == 0 ) |
{ |
if ( UserWantsToDrag ( theWindow, theEvent.where ) ) |
{ |
if ( DoWindowContentDrag ( theWindow, &theEvent ) ) |
TEClick ( localPt, false, theDoc->theText ); |
} |
else |
{ |
// only extend the selection if the shiftkey is down |
extend = (theEvent.modifiers & shiftKey); |
if ( PtInDocument ( localPt, theDoc ) ) |
TEClick ( localPt, extend, theDoc->theText ); |
} |
} |
else if ( cntlCode == inThumb ) |
{ |
value = GetCtlValue(theControl); |
part = TrackControl(theControl, localPt, nil); |
if (part) |
{ |
value -= GetCtlValue(theControl); |
if (value) |
{ |
if (theControl == theDoc->vScrollBar) |
TEScroll(0, value, theDoc->theText); |
else |
TEScroll(value, 0, theDoc->theText); |
DrawPageExtras(theDoc); |
} |
} |
} |
else |
{ |
if (theControl == theDoc->vScrollBar) |
part = TrackControl(theControl, localPt, (ControlActionUPP) gVScrollActionUPP); |
else |
part = TrackControl(theControl, localPt, (ControlActionUPP) gHScrollActionUPP); |
} |
SetPort(savePort); |
} |
void DoBackgroundContent( WindowPtr theWindow, EventRecord theEvent) |
{ |
Point thePoint; |
GrafPtr savePort; |
RgnHandle dragRgn; |
DPtr theDoc; |
GetPort ( &savePort ); |
SetPort ( theWindow ); |
theDoc = DPtrFromWindowPtr ( theWindow ); |
thePoint = theEvent.where; |
GlobalToLocal ( &thePoint ); |
dragRgn = NewRgn ( ); |
GetSelectedTextRgn ( theDoc, dragRgn ); |
if ( PtInRgn ( thePoint, dragRgn ) ) |
{ |
if ( DoWindowContentDrag ( theWindow, &theEvent ) ) |
SelectWindow (theWindow ); |
} |
else |
SelectWindow ( theWindow ); |
SetPort ( savePort ); |
return; |
} |
#pragma segment Window |
OSErr DoActivate( WindowPtr theWindow, Boolean activate ) |
{ |
Rect r; |
DPtr theDoc; |
OSErr err = noErr; |
if (theWindow) |
if (Ours(theWindow)) |
{ |
theDoc = DPtrFromWindowPtr(theWindow); |
SetPort(theWindow); |
DrawGrowIcon(theWindow); |
GetWinContentRect(theWindow, &r); |
InvalRect(&r); |
if ( activate ) |
{ |
if ( theDoc->windowType == kOrdinaryWind ) |
TEActivate(theDoc->theText); |
HiliteControl ( theDoc->vScrollBar, 0 ); |
HiliteControl ( theDoc->hScrollBar, 0 ); |
SetMenuItemState ( false, myMenus[editM], undoCommand ); |
err = TEFromScrap(); |
CheckMenus( ); |
} |
else |
{ |
TEDeactivate( theDoc->theText ); |
HiliteControl ( theDoc->vScrollBar, 255 ); |
HiliteControl ( theDoc->hScrollBar, 255 ); |
err = ZeroScrap(); |
err = TEToScrap(); |
} |
} |
return err; |
} |
#pragma segment Window |
void GetPageEnds( short pageHeight, TEHandle theText, |
PageEndsArray pageBounds, short *nPages) |
{ |
short pageBase; // total pixel offset of pages so far |
short thisLine; |
short lastLine; |
short pageSoFar; |
short thisPage; // Current page being calced |
short thisLineH; // Height of text line |
short pageFirstLine; // Line # of top of page |
pageBase = 0; |
thisLine = 1; |
lastLine = (*theText)->nLines; |
thisPage = 0; |
pageSoFar = 0; |
while ((thisLine <= lastLine) || (pageSoFar!=0)) |
{ |
pageFirstLine = thisLine; |
thisLineH = TEGetHeight(thisLine, thisLine, theText); |
while ((thisLineH+pageSoFar<pageHeight) && (thisLine <= lastLine)) |
{ |
pageSoFar += thisLineH; |
thisLine++; |
thisLineH = TEGetHeight(thisLine, thisLine, theText); |
} |
if (pageSoFar) |
{ |
pageBounds[thisPage] = pageSoFar+pageBase; |
pageBase = pageBounds[thisPage]; |
thisPage++; |
pageSoFar = 0; |
} |
// Special case text line taller than page |
if ((thisLine == pageFirstLine) && |
(thisLineH > pageHeight)) |
{ |
do { |
pageBounds[thisPage] = pageBase+pageHeight; |
pageBase = pageBounds[thisPage]; |
thisPage += 1; |
thisLineH -= pageHeight; |
} while (thisLineH >= pageHeight); |
pageSoFar = thisLineH; // Carry bottom of large line to next page |
thisLine += 1; // carry xs on as pageSoFar and start measuring next line |
} |
} |
*nPages = thisPage; |
} // GetPageEnds |
void DrawPageBreaks( DPtr theDoc ) |
{ |
PageEndsArray pageEnds; |
short nPages; |
short ctr; |
short lineBase; |
short pageHeight; |
Rect viewRect; |
Rect pageRect; |
GetRectOfPage( theDoc, &pageRect ); |
pageHeight = pageRect.bottom - pageRect.top; |
GetPageEnds(pageHeight, theDoc->theText, pageEnds, &nPages); |
lineBase = (*(theDoc->theText))->destRect.top; |
viewRect = (*(theDoc->theText))->viewRect; |
PenPat(&qd.gray); |
for (ctr = 0; ctr<nPages-1; ctr++) |
{ |
MoveTo(viewRect.left, lineBase+pageEnds[ctr]); |
LineTo(viewRect.right,lineBase+pageEnds[ctr]); |
} |
PenNormal(); |
} // DrawPageBreaks |
void DrawPageExtras( DPtr theDoc ) |
{ |
GrafPtr oldPort; |
RgnHandle oldClip; |
Rect rectToClip; |
GetPort(&oldPort); |
SetPort(theDoc->theWindow); |
oldClip = NewRgn(); |
GetClip(oldClip); |
GetWinContentRect(theDoc->theWindow,&rectToClip); |
ClipRect(&rectToClip); |
// and then the page breaks |
DrawPageBreaks(theDoc); |
SetClip(oldClip); |
DisposeRgn(oldClip); |
SetPort(oldPort); |
} // DrawPageExtras |
void DoUpdate( WindowPtr theWindow ) |
{ |
GrafPtr savePort; |
Rect rectClip; |
DPtr theDocument; |
theDocument = DPtrFromWindowPtr ( theWindow ); |
if ( Ours ( theWindow ) ) |
{ |
GetPort ( &savePort ); |
SetPort ( theWindow ); |
BeginUpdate ( theWindow ); |
ClipRect(&theWindow->portRect); |
EraseRect(&theWindow->portRect); |
DrawControls(theWindow); |
DrawGrowIcon(theWindow); |
GetWinContentRect(theWindow, &rectClip); |
ClipRect(&rectClip); |
TEUpdate(&theWindow->portRect, theDocument->theText); |
DrawPageExtras(theDocument); |
EndUpdate(theWindow); |
ClipRect(&theWindow->portRect); |
SetPort ( savePort ); |
} |
return; |
} // DoUpdate |
#pragma segment Window |
DPtr NewDocument( Boolean isForOldDoc, WindowPtr behindWindow ) |
{ |
Rect destRect; |
Rect viewRect; |
Rect vScrollRect; |
Rect hScrollRect; |
DPtr myDoc; |
WindowPtr myWindow; |
ControlHandle vScroll; |
ControlHandle hScroll; |
Str255 theName; |
Str255 newNumber; |
Rect pageRect; |
myDoc = nil; |
myWindow = GetNewWindow(WindowID, nil, behindWindow); |
if (myWindow) |
{ |
if (isForOldDoc==false) |
{ |
GetWTitle(myWindow, theName); |
NumToString(++gNewDocCount, newNumber); |
if (gNewDocCount>1) |
{ |
PLstrcat(theName, (unsigned char *)"\p #"); |
PLstrcat(theName, newNumber); |
SetWTitle(myWindow, theName); |
} |
} |
OffsetWindow(myWindow); |
SetPort(myWindow); |
myDoc = (DPtr)NewPtr(sizeof(DocRec)); |
SetWRefCon(myWindow, (long)myDoc); |
myDoc->theWindow = myWindow; |
myDoc->windowType = kOrdinaryWind; |
vScrollRect = myWindow->portRect; |
vScrollRect.left = vScrollRect.right - kScrollbarAdjust; |
vScrollRect.right = vScrollRect.left + kScrollbarWidth; |
vScrollRect.bottom = vScrollRect.bottom - 14; |
vScrollRect.top = vScrollRect.top - 1; |
vScroll = NewControl(myWindow, &vScrollRect, (unsigned char *)"\pScrollBar", true, 0, 0, 0, scrollBarProc, 0); |
hScrollRect = myWindow->portRect; |
hScrollRect.top = hScrollRect.bottom - kScrollbarAdjust; |
hScrollRect.bottom = hScrollRect.top + kScrollbarWidth; |
hScrollRect.right = hScrollRect.right - 14; |
hScrollRect.left = hScrollRect.left - 1; |
hScroll = NewControl(myWindow, &hScrollRect, (unsigned char *)"\pScrollBar", true, 0, 0, 0, scrollBarProc, 0); |
myDoc->vScrollBar = vScroll; |
myDoc->hScrollBar = hScroll; |
myDoc->dirty = false; |
GetTERect(myWindow, &viewRect); |
destRect = viewRect; |
myDoc->theFont = times; |
myDoc->theStyle = 0; |
myDoc->theSize = 12; |
myDoc->documentJob = nil; |
myDoc->thePrintSetup = nil; |
if (gGXIsPresent) |
{ |
if (GXNewJob(&(myDoc->documentJob)) == noErr) |
GXInstallApplicationOverride(myDoc->documentJob, |
gxPrintingEventMsg, |
NewGXPrintingEventProc(GXPrintingEventOverride)); |
} |
else |
{ |
myDoc->thePrintSetup = (THPrint)NewHandle(sizeof(TPrint)); |
PrOpen(); |
PrintDefault(myDoc->thePrintSetup); |
PrClose(); |
} |
GetRectOfPage( myDoc, &pageRect ); |
destRect.right = destRect.left + pageRect.right; |
OffsetRect(&destRect, kTextOffset, kTextOffset); |
TextFont(times); |
TextSize(12); |
TextFace(0); |
myDoc->theText = TEStylNew(&destRect, &viewRect); |
// SetClikLoop(@AutoScroll, myDoc->theText); |
myDoc->theFileName[0] = 0; |
myDoc->everSaved = false; |
myDoc->theWindow = myWindow; |
ResizeWindow(myDoc); |
InstallDragHandlers ( myWindow ); |
myDoc->theScriptID = kOSANullScript; |
} |
return(myDoc); |
} |
#pragma segment Window |
void CloseMyWindow( WindowPtr aWindow ) |
{ |
DPtr aDocument; |
TEHandle theText; |
if (IsThisResultWind(aWindow)) |
CloseResultWind(aWindow); |
else |
{ |
HideMSWindow(aWindow); |
aDocument = DPtrFromWindowPtr(aWindow); |
theText = aDocument->theText; |
TEDispose(theText); |
if (aDocument->thePrintSetup) |
DisposHandle((Handle)aDocument->thePrintSetup); |
if (aDocument->documentJob) |
GXDisposeJob(aDocument->documentJob); |
RemoveDragHandlers ( aWindow ); |
DisposPtr((Ptr)aDocument); |
DisposeWindow(aWindow); |
} |
} |
// Name : PrintWindow |
// Function : Prints the document supplied in theDoc. askUser controls interaction |
// with the user. |
// |
// Uses extra memory equal to the size of the textedit use in the |
// printed document. |
void PrintWindow( DPtr theDoc, Boolean askUser ) |
{ |
GrafPtr oldPort; |
TEHandle printerTE; |
TPPrPort printerPort; |
Rect printView; |
PageEndsArray pageBounds; |
short nPages; |
short pageCtr; |
Boolean abort; |
Rect rectToClip; |
TPrStatus thePrinterStatus; |
DialogPtr progressDialog; |
WindowPtr tempWind; // Temp window to create TERec in |
Rect tempWindRect = {0,0,0,0}; // Bounds for temp window |
abort = false; |
// Preserve the current port |
GetPort(&oldPort); |
PrOpen(); |
if (askUser) |
abort = !PrJobDialog(theDoc->thePrintSetup); |
if (abort) |
{ |
PrClose(); |
return; |
} |
progressDialog = GetNewDialog(1005, nil, (WindowPtr)-1); |
DrawDialog(progressDialog); |
printerPort = PrOpenDoc(theDoc->thePrintSetup, nil, nil); |
SetPort((GrafPtr)printerPort); |
// Create a temporary window(which is not shown) |
tempWind = NewWindow( nil, &tempWindRect, "\p", |
false, documentProc, (WindowPtr)-1, false, 0); |
// Duplicate the text edit rec |
printView = (*(theDoc->thePrintSetup))->prInfo.rPage; |
DuplicateStyleTERec ( theDoc->theText, &printerTE, &printView, (GrafPtr)tempWind ); |
// Work out the offsets |
(*printerTE)->destRect = printView; // GetPageEnds calls TECalText |
GetPageEnds(printView.bottom-printView.top, |
printerTE, |
pageBounds, |
&nPages); |
TEDeactivate(printerTE); |
// Set the TERec to the printer port |
(*printerTE)->inPort = (GrafPtr)printerPort; |
for (pageCtr = 0; pageCtr <= nPages-1; pageCtr++) |
if (!abort) |
{ |
PrOpenPage(printerPort, nil); |
rectToClip = printView; |
if (pageCtr > 0) |
rectToClip.bottom = rectToClip.top + (pageBounds[pageCtr]-pageBounds[pageCtr-1]); |
else |
rectToClip.bottom = rectToClip.top + pageBounds[pageCtr]; |
ClipRect(&rectToClip); |
if (PrError() == iPrAbort) |
abort = true; |
if (! abort) |
TEUpdate(&printView, printerTE); |
if (PrError() == iPrAbort) |
abort = true; |
PrClosePage(printerPort); |
TEScroll(0,rectToClip.top-rectToClip.bottom, printerTE); |
} |
TEDispose(printerTE); |
DisposeWindow ( tempWind ); |
PrCloseDoc(printerPort); |
if (( (*(theDoc->thePrintSetup))->prJob.bJDocLoop == bSpoolLoop ) && |
( PrError() == noErr ) && (! abort)) |
PrPicFile( theDoc->thePrintSetup, nil, nil, nil, &thePrinterStatus); |
PrClose(); |
DisposDialog(progressDialog); |
SetPort(oldPort); |
InvalRect(&oldPort->portRect); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14