Important: The information in this document is obsolete and should not be used for new development.
Zooming a Window
The zoom box allows the user to alternate quickly between two window positions and sizes: the user state and the standard state.The user state is the window size and location established by the user. If your application does not supply an initial user state, the user state is simply the size and location of the window when it was created, until the user resizes it.
The standard state is the window size and location that your application considers most convenient, considering the function of the document and the screen space available. In a word-processing application, for example, a standard-state window might show a
full page, if possible, or a page of full width and as much length as fits on the screen.
If the user changes the page size through Page Setup, the application might adjust the standard state to reflect the new page size. If your application does not define a standard state, the Window Manager automatically sets the standard state to the entire gray region on the main screen, minus a three-pixel border on all sides. (See Macintosh Human Interface Guidelines for a detailed description of how your application determines where to open and zoom windows.) The user cannot change a window's standard state.The user and standard states are stored in a record whose handle appears in the
dataHandlefield of the window record.
TYPE WStateData = RECORD userState: Rect; {size and location established by user} stdState: Rect; {size and location established by } { application} END;The Window Manager sets the initial values of theuserStateandstdStatefields when it fills in the window record, and it updates theuserStatefield whenever the user resizes the window. You typically compute the standard state every time the user zooms to the standard state, to ensure that you're zooming to an appropriate location.When the user presses the mouse button with the cursor in the zoom box, the
FindWindowfunction specifies whether the window is in the user state or the standard state: when the window is in the standard state,FindWindowreturnsinZoomIn(meaning that the window is to be zoomed "in" to the user state); when the window is in the user state,FindWindowreturnsinZoomOut(meaning that the window is to be zoomed "out" to the standard state).When
FindWindowreturns eitherinZoomInorinZoomOut, your application can call theTrackBoxfunction to handle the highlighting of the zoom box and to determine whether the cursor is inside or outside the box when the button is released. IfTrackBoxreturnsTRUE, your application can call theZoomWindowprocedure to resize the window (after computing a new standard state). IfTrackBoxreturnsFALSE, your application doesn't need to do anything. Listing 4-9 on page 4-39 illustrates the use ofTrackBoxin an event-handling routine.Listing 4-12 illustrates an application-defined procedure,
DoZoomWindow, which an application might call whenTrackBoxreturnsTRUEafterFindWindowreturns eitherinZoomInorinZoomOut. Because the user might have moved the window to a different screen since it was last zoomed, the procedure first determines which screen contains the largest area of the window and then calculates the ideal window size for that screen before zooming the window.The screen calculations in the
DoZoomWindowprocedure depend on the routines for handling graphics devices that were introduced at the same time as Color QuickDraw. Therefore,DoZoomWindowchecks for the presence of Color QuickDraw before comparing the window to be zoomed with the graphics devices in the device list. If Color QuickDraw is not available,DoZoomWindowassumes that it's running on a computer with a single screen.
PROCEDURE DoZoomWindow (thisWindow: windowPtr; zoomInOrOut: Integer); VAR gdNthDevice, gdZoomOnThisDevice: GDHandle; savePort: GrafPtr; windRect, zoomRect, theSect: Rect; sectArea, greatestArea: LongInt; wTitleHeight: Integer; sectFlag: Boolean; BEGIN GetPort(savePort); SetPort(thisWindow); EraseRect(thisWindow^.portRect); {erase to avoid flicker} IF zoomInOrOut = inZoomOut THEN {zooming to standard state} BEGIN IF NOT gColorQDAvailable THEN {assume a single screen and } BEGIN { set standard state to full screen} zoomRect := screenBits.bounds; InsetRect(zoomRect, 4, 4); WStateDataHandle(WindowPeek(thisWindow)^.dataHandle)^^.stdState := zoomRect; END ELSE {locate window on available graphics devices} BEGIN windRect := thisWindow^.portRect; LocalToGlobal(windRect.topLeft); {convert to global coordinates} LocalToGlobal(windRect.botRight); {calculate height of window's title bar} wTitleHeight := windRect.top - 1 - WindowPeek(thisWindow)^.strucRgn^^.rgnBBox.top; windRect.top := windRect.top - wTitleHeight; gdNthDevice := GetDeviceList; greatestArea := 0; {initialize to 0} {check window against all gdRects in gDevice list and remember } { which gdRect contains largest area of window} WHILE gdNthDevice <> NIL DO IF TestDeviceAttribute(gdNthDevice, screenDevice) THEN IF TestDeviceAttribute(gdNthDevice, screenActive) THEN BEGIN {The SectRect routine calculates the intersection } { of the window rectangle and this gDevice } { rectangle and returns TRUE if the rectangles intersect, } { FALSE if they don't.} sectFlag := SectRect(windRect, gdNthDevice^^.gdRect, theSect); {determine which screen holds greatest window area} {first, calculate area of rectangle on current device} WITH theSect DO sectArea := LongInt(right - left) * (bottom - top); IF sectArea > greatestArea THEN BEGIN greatestArea := sectArea; {set greatest area so far} gdZoomOnThisDevice := gdNthDevice; {set zoom device} END; gdNthDevice := GetNextDevice(gdNthDevice); END; {of WHILE} {if gdZoomOnThisDevice is on main device, allow for menu bar height} IF gdZoomOnThisDevice = GetMainDevice THEN wTitleHeight := wTitleHeight + GetMBarHeight; WITH gdZoomOnThisDevice^^.gdRect DO {create the zoom rectangle} BEGIN {set the zoom rectangle to the full screen, minus window title } { height (and menu bar height if necessary), inset by 3 pixels} SetRect(zoomRect, left + 3, top + wTitleHeight + 3, right - 3, bottom - 3); {If your application has a different "most useful" standard } { state, then size the zoom window accordingly.} {set up the WStateData record for this window} WStateDataHandle(WindowPeek(thisWindow)^.dataHandle)^^.stdState := zoomRect; END; END; END; {of inZoomOut} {if zoomInOrOut = inZoomIn, just let ZoomWindow zoom to user state} {zoom the window frame} ZoomWindow(thisWindow, zoomInOrOut, (thisWindow = FrontWindow)); MyResizeWindow(thisWindow); {application-defined window-sizing routine} SetPort(savePort); END; (of DoZoomWindow)If the user is zooming the window to the standard state,DoZoomWindowcalculates a new standard size and location based on the application's own considerations, the current location of the window, and the available screens. TheDoZoomWindowprocedure always places the standard state on the screen where the window is currently displayed or, if the window spans screens, on the screen containing the largest area
of the window.The bulk of the code in Listing 4-12 is devoted to determining which screen should display the window in the standard state. The sample code shown here establishes
a standard state that simply occupies the gray area on the chosen screen, minus
three pixels on all sides. Your application should establish a standard state appropriate
to its own documents. When calculating the standard state, move the window as little
as possible from the user state. If possible, anchor one corner of the standard state rectangle to one corner of the user state rectangle.If the user is zooming the window to the user state,
DoZoomWindowdoesn't have to perform any calculations, because the user state rectangle stored in the state data record should represent a valid screen location.After calculating the standard state, if necessary,
DoZoomWindowcalls theZoomWindowprocedure to redraw the window frame in the new size and location and then calls the application-defined procedureMyResizeWindowto redraw the window's content region. Listing 4-14 on page 4-53 shows theMyResizeWindowprocedure.