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
GrowWindow
function. 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
. ThesizeRect
parameter toGrowWindow
specifies both the lower and upper size limits in a single structure of typeRect
. The values in thesizeRect
structure 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,
GrowWindow
returns 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. WhenGrowWindow
returns any value other than 0, you callSizeWindow
to 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
HiWord
andLoWord
to retrieve the high-order and low-order words, respectively.Listing 4-13 illustrates the application-defined procedure
DoGrowWindow
for 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-definedDoGrowWindow
procedure. TheDoGrowWindow
procedure
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,GrowWindow
returns a nonzero value, andDoGrowWindow
prepares to resize the window. FirstDoGrowWindow
saves 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. TheGrowWindow
procedure 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,
DoGrowWindow
calls the Window Manager procedureSizeWindow
to draw the window in its new
size. TheDoGrowWindow
procedure 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-definedMyResizeWindow
procedure.After calling
SizeWindow
,DoGrowWindow
calculates 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 theMyResizeWindow
procedure 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. TheMyGetLocalUpdateRgn
procedure uses the QuickDraw routinesCopyRgn
andOffsetRgn
, 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}