Important: The information in this document is obsolete and should not be used for new development.
Resizing a Window
The size box, in the lower-right corner of a window's content region, allows the user to change a window's size.When the user positions the cursor in the size box and presses the mouse button, your application can call the Window Manager's
GrowWindowfunction. This function displays a grow image--a gray outline of the window's frame and scroll bar areas, which expands or contracts as the user drags the size box. The grow image indicates where the window edges would be if the user released the mouse button at any
given moment.To avoid unmanageably large or small windows, you supply lower and upper size limits when you call
GrowWindow. ThesizeRectparameter toGrowWindowspecifies both the lower and upper size limits in a single structure of typeRect. The values in thesizeRectstructure represent window dimensions, not screen coordinates:
Most applications specify a minimum size big enough to include all parts of the structure area and the scroll bars. Because the user cannot move the cursor beyond the edges of the screen, you can safely set the maximum size to the largest possible rectangle.
- You supply the minimum vertical measurement in
sizeRect.top.- You supply the minimum horizontal measurement in
sizeRect.left.- You supply the maximum vertical measurement in
sizeRect.bottom.- You supply the maximum horizontal measurement in
sizeRect.right.
When the user releases the mouse button,
GrowWindowreturns a long integer that describes the window's new height (in the high-order word) and width (in the low-order word). A value of 0 means that the window's size did not change. WhenGrowWindowreturns any value other than 0, you callSizeWindowto resize the window.
When you change a window's size, you must erase and redraw the window's scroll bars.
- Note
- Use the utility functions
HiWordandLoWordto retrieve the high-order and low-order words, respectively.![]()
Listing 4-13 illustrates the application-defined procedure
DoGrowWindowfor tracking mouse activity in the size box and resizing the window.Listing 4-13 Resizing a window
PROCEDURE DoGrowWindow (thisWindow: windowPtr; event: EventRecord); VAR growSize: LongInt; limitRect: Rect; oldViewRect: Rect; locUpdateRgn: RgnHandle; theResult: Boolean; myData: MyDocRecHnd; BEGIN {set up the limiting rectangle: kMinDocSize = 64 } { kMaxDocSize = 65535} SetRect(limitRect, kMinDocSize, kMinDocSize, kMaxDocSize, kMaxDocSize); {call Window Manager to let user drag size box} growSize := GrowWindow(thisWindow, event.where, limitRect); IF growSize <> 0 THEN {if user changed size, } BEGIN { then resize window} myData := MyDocRecHnd(GetWRefCon(thisWindow)); oldViewRect := myData^^.editRec^^.viewRect; locUpdateRgn := NewRgn; {save update region in local coordinates} MyGetLocalUpdateRgn(thisWindow, locUpdateRgn); {resize the window} SizeWindow(thisWindow, LoWord(growSize), HiWord(growSize), TRUE); MyResizeWindow(thisWindow); {find intersection of old viewRect and new viewRect} theResult := SectRect(oldViewRect, myData^^.editRec^^.viewRect, oldViewRect); {validate the intersection (don't update)} ValidRect(oldViewRect); {invalidate any prior update region} InvalRgn(locUpdateRgn); DisposeRgn(locUpdateRgn); END; END;When the user presses the mouse button while the cursor is in the size box, the procedure that handles mouse-down events (DoMouseDown, shown on page 4-39) calls the application-definedDoGrowWindowprocedure. TheDoGrowWindowprocedure
calls the Window Manager functionGrowWindow, which tracks mouse movement as long as the button is held down. If the user drags the size box before releasing the mouse button,GrowWindowreturns a nonzero value, andDoGrowWindowprepares to resize the window. FirstDoGrowWindowsaves the current view rectangle in the variableoldViewRect. It will use this information later, when redrawing the content region of the window in its new size. TheGrowWindowprocedure also saves the current update region, in local coordinates, in the regionLocUpdateRgn, so that it can restore the update region after doing its own update-region maintenance. (This step is necessary only if an application allows user input to accumulate into the update region, drawing in response to update events instead of drawing into the window immediately.)After saving the current view rectangle and the current update region,
DoGrowWindowcalls the Window Manager procedureSizeWindowto draw the window in its new
size. TheDoGrowWindowprocedure then calls the application-defined procedureMyResizeWindow, which adjusts the window scroll bars and window contents to the new size. Listing 4-14 illustrates the application-definedMyResizeWindowprocedure.After calling
SizeWindow,DoGrowWindowcalculates the intersection of the old view rectangle and the new view rectangle. It uses this area to revalidate unchanged portions of the window (that is, to remove them from the update region), because theMyResizeWindowprocedure invalidates the entire window (that is, places the entire window in the update region). This way, only the changed parts of the content area are redrawn when the application receives its next update event.Listing 4-14 Adjusting scroll bars and content region when resizing a window
PROCEDURE MyResizeWindow (window: WindowPtr); BEGIN WITH window^ DO BEGIN {adjust scroll bars and contents-- } { see the chapter "Control Manager" for implementation} MyAdjustScrollbars(window, TRUE); MyAdjustTE(window); {invalidate content region, forcing an update} InvalRect(portRect); END; END; {MyResizeWindow}Listing 4-15 illustrates the application-defined procedureMyGetLocalUpdateRgn, which supplies a window's update region in local coordinates. TheMyGetLocalUpdateRgnprocedure uses the QuickDraw routinesCopyRgnandOffsetRgn, documented in Inside Macintosh: Imaging.Listing 4-15 Converting a window region to local coordinates
PROCEDURE MyGetLocalUpdateRgn (window: WindowPtr; localRgn: RgnHandle); BEGIN {save old update region} CopyRgn(WindowPeek(window)^.updateRgn, localRgn); WITH window^.portBits.bounds DO OffsetRgn(localRgn, left, top); {convert to local coords} END; {MyGetLocalUpdateRgn}