home *** CD-ROM | disk | FTP | other *** search
- /*
- File: WindowExtensions.c
-
- Contains: Routines to support floating windows
-
- Written by: Dean Yu
-
- Copyright: © 1993 Apple Computer, Inc.
-
- */
-
- #include <Types.h>
- #include <Events.h>
- #include <GestaltEqu.h>
- #include <Memory.h>
- #include <Menus.h>
- #include <Processes.h>
- #include <Resources.h>
- #include <SysEqu.h>
- #include <ToolUtils.h>
- #include <Windows.h>
-
- #include "WindowExtensions.h"
-
- // Internal routine prototypes
-
- static void ActivateWindow(WindowRef theWindow);
- static void DeactivateWindow(WindowRef theWindow);
- static void HighlightAndActivateWindow(WindowRef theWindow, Boolean activate);
- static WindowRef GetWindowList(void);
- static void SetWindowList(WindowRef windowReference);
-
- //
- // NewWindowReference
- //
- // Create a new window, and return a reference to it.
- //
-
- pascal OSErr NewWindowReference(WindowRef *windowReference, const Rect *boundsRect,
- ConstStr255Param title, Boolean visible, WindowAttributes attributes, WindowRef behind,
- long refCon, ActivateHandlerUPP activateHandlerProc)
- {
- WindowAttributes titleBarType;
- WindowRef newWindowReference;
- WindowRef lastFloater;
- long gestaltResult;
- OSErr result = noErr;
- OSErr gestaltError;
- short procID;
- Boolean hasGoAway = false;
-
- // Determine the type of title bar this window has, if any.
-
- titleBarType = attributes & kWindowTitlebarMask;
- if (titleBarType != 0) {
- switch (titleBarType) {
- case kHasRoundedTitlebarMask:
- case kHasDocumentTitlebarMask: if ((behind == (WindowRef) -1) &&
- ((lastFloater = LastFloatingWindow()) != nil))
- behind = lastFloater;
-
- if (titleBarType == kHasRoundedTitlebarMask)
- procID = kRoundedWindowProc;
- else
- procID = kStandardDocumentWindowProc;
- break;
- case kHasPaletteTitlebarMask: if (((behind == nil) && (FrontNonFloatingWindow() != nil)) ||
- ((behind != (WindowRef) -1) && (GetWindowKind(behind) != kApplicationFloaterKind))) {
- *windowReference = 0;
- return kInvalidWindowOrderingError;
- }
- procID = kFloatingWindowProc;
- break;
- default: procID = kStandardDocumentWindowProc;
- result = kUndefinedTitleBarTypeError;
- break;
- }
-
- // This window has a title bar. See what kind of gadgets it has in it.
-
- if (attributes & kHasModalBorderMask) // Moveable modals don’t get zoom, close, or grow boxes
- procID += movableDBoxProc;
- else {
- if (attributes & kHasCloseBoxMask)
- hasGoAway = true;
- if (attributes & kHasZoomBoxMask)
- procID += zoomDocProc;
- if (!(attributes & kHasGrowBoxMask))
- procID += noGrowDocProc;
- }
- }
-
- // This window has no title bar, so it’s a dialog of some sort.
- // We’re going to be dictatorial and say that these types of windows
- // can only come up in front.
-
- else {
- if (behind != (WindowRef) -1) {
- *windowReference = 0;
- return kInvalidWindowOrderingError;
- }
-
- procID = dBoxProc; // Start with the standard dialog type
- if (!(attributes & kHasModalBorderMask)) {
- procID = plainDBox; // This isn’t the standard modal type
- if (attributes & kHasThickDropShadowMask) // These types can have a deeper drop shadow
- procID = altDBoxProc;
- }
- }
-
- newWindowReference = (WindowRef) NewPtr(sizeof(WindowRecordExtensions));
-
- if (MemError() == noErr) {
-
- // Call the real Window Manager routine to create the window:
- // If Color Quickdraw is available, always create a color window. If Color Quickdraw
- // is not around, or Gestalt spewed, create a classic window.
-
- gestaltError = Gestalt(gestaltQuickdrawVersion, &gestaltResult);
- if ((gestaltError != noErr) || (gestaltResult == gestaltOriginalQD))
- NewWindow(newWindowReference, boundsRect, title, false, procID, (WindowPtr) behind,
- hasGoAway, refCon);
- else
- NewCWindow(newWindowReference, boundsRect, title, false, procID, (WindowPtr) behind,
- hasGoAway, refCon);
-
- // If a window was successfully created, set its activate event handler proc and show
- // it if the caller wanted a visible window.
-
- *windowReference = newWindowReference; // Return a reference to the window
- SetActivateHandlerProc(newWindowReference, activateHandlerProc);
-
- if (attributes & kHasPaletteTitlebarMask) // Set the windowKind for floating windows
- SetWindowKind(newWindowReference, kApplicationFloaterKind);
-
- if (visible) // Show the window
- ShowReferencedWindow(newWindowReference);
- }
- else {
- *windowReference = 0;
- result = kWindowNotCreatedError;
- }
-
- return result;
- }
-
- //
- // GetNewWindowReference
- //
- // Create a window based on information in the specified resource.
- //
-
- pascal OSErr GetNewWindowReference(WindowRef *windowReference, short windResourceID,
- WindowRef behind, ActivateHandlerUPP activateHandler)
- {
- WindowRef newWindowReference;
- WindowRef lastFloatingWindow;
- WindowRef windowReferenceStorage;
- long gestaltResult;
- OSErr gestaltError;
- OSErr result;
- short defProcID;
-
- result = noErr;
- windowReferenceStorage = (WindowRef) NewPtr(sizeof(WindowRecordExtensions));
-
- if (MemError() == noErr) {
-
- // Create a window based on the specified 'WIND' resource. If Color Quickdraw
- // is around, create a color window, otherwise, make a black and white one.
-
- gestaltError = Gestalt(gestaltQuickdrawVersion, &gestaltResult);
- if ((gestaltError != noErr) || (gestaltResult == gestaltOriginalQD))
- newWindowReference = (WindowRef) GetNewWindow(windResourceID, windowReferenceStorage, (WindowPtr) behind);
- else
- newWindowReference = (WindowRef) GetNewCWindow(windResourceID, windowReferenceStorage, (WindowPtr) behind);
-
- // If we got a window, create the reference, then make sure the windowKind field is
- // set correctly for floating windows.
-
- if (newWindowReference != nil) {
- *windowReference = newWindowReference;
- SetActivateHandlerProc(newWindowReference, activateHandler);
-
- // Figure out if this is a floating window, based upon the resource ID of the 'WDEF'.
- // This is a really wierd way of doing it, but this allows the 'WIND' resource to
- // describe the floatability of a window.
- //
- // A little known fact about GetResInfo is that if you specify nil for any of the
- // info parameters, then it won’t return that information. Handy, huh?
-
- GetResInfo(GetWindowDefProc(newWindowReference), &defProcID, nil, nil);
-
- if (defProcID == rFloatingWindowProc) {
-
- // Return an error if it’s a floating window being created behind a non floating window.
-
- if (((behind == nil) && (FrontNonFloatingWindow() != nil)) ||
- ((behind != (WindowRef) -1) && (GetWindowKind(behind) != kApplicationFloaterKind))) {
- *windowReference = 0;
- return kInvalidWindowOrderingError;
- }
- else {
- SetWindowKind(newWindowReference, kApplicationFloaterKind);
- HiliteWindow((WindowPtr) newWindowReference, true);
- }
- }
- else
-
- // If we’re not creating a floating window, but the application wanted it in the
- // front, create the window behind the last floating window.
-
- if (behind == (WindowRef) -1) {
- lastFloatingWindow = LastFloatingWindow();
-
- if (lastFloatingWindow != nil)
- SendBehind((WindowPtr) newWindowReference, (WindowPtr) lastFloatingWindow);
- else
- BringToFront((WindowPtr) newWindowReference);
- }
- }
- else {
- DisposePtr((Ptr) windowReferenceStorage);
- *windowReference = 0;
- result = kWindowNotCreatedError;
- }
- }
- else {
- *windowReference = 0;
- result = kWindowNotCreatedError;
- }
-
- return result;
- }
-
- //
- // DisposeWindowReference
- //
- // Free the memory used by a window. If it is visible, hide it first so
- // that the proper activate and deactivate events are sent.
- //
-
- pascal void DisposeWindowReference(WindowRef windowReference)
- {
- if (GetWindowVisible(windowReference))
- HideReferencedWindow(windowReference);
- CloseWindow((WindowPtr) windowReference);
- DisposePtr((Ptr) windowReference);
- }
-
- //
- // SelectedReferencedWindow
- //
- // Select the specified window, and bring it to the front if its portion
- // of the window list.
- //
-
- pascal void SelectReferencedWindow(WindowRef windowToSelect)
- {
- WindowRef currentFrontWindow;
- WindowRef lastFloatingWindow;
- Boolean isFloatingWindow;
-
- if (GetWindowKind(windowToSelect) == kApplicationFloaterKind) {
- isFloatingWindow = true;
- currentFrontWindow = (WindowRef) FrontWindow();
- }
- else {
- isFloatingWindow = false;
- currentFrontWindow = FrontNonFloatingWindow();
- lastFloatingWindow = LastFloatingWindow();
- }
-
- // Be fast (and lazy) and do nothing if we don’t have to.
-
- if (currentFrontWindow != windowToSelect) {
-
- // Selecting floating windows are easy, since they’re always active
-
- if (isFloatingWindow)
- BringToFront((WindowPtr) windowToSelect);
- else {
-
- // If there are no floating windows, we can call SelectWindow like the good ol’ days
-
- if (lastFloatingWindow == nil)
- SelectWindow((WindowPtr) windowToSelect);
- else {
-
- // Deactivate the window currently in front.
-
- DeactivateWindow(currentFrontWindow);
-
- // Bring it behind the last floating window and activate it.
- // Note that Inside Mac 1 states that you need to call PaintOne() and CalcVis() on a
- // window if you are using SendBehind() to bring it closer to the front. With System 7,
- // this is no longer necessary.
-
- SendBehind((WindowPtr) windowToSelect, (WindowPtr) lastFloatingWindow);
- ActivateWindow(windowToSelect);
- }
- }
- }
- }
-
- //
- // ShowReferencedWindow
- //
- // Show the specified window. If the window is the frontmost document window,
- // unhighlight the window behind it, deactivate it, and activate this one.
- //
-
- pascal void ShowReferencedWindow(WindowRef windowToShow)
- {
- WindowRef windowBehind;
- WindowRef frontNonFloatingWindow;
- ActivateHandlerUPP activateHandlerProc;
- short windowClass;
- Boolean windowIsInFront = false;
-
- if (GetWindowVisible(windowToShow) != false)
- return;
-
- windowClass = GetWindowKind(windowToShow);
-
- // If the window behind the window to show is currently the frontmost document window,
- // unhighlight it, and highlight the new front window.
-
- if (windowClass != kApplicationFloaterKind) {
- windowBehind = GetNextWindow(windowToShow);
- if (windowBehind == FrontNonFloatingWindow()) {
- if (windowBehind != nil)
- DeactivateWindow(windowBehind);
-
- // Set the highlight state so the window appears highlighted from the start.
-
- SetWindowHilite(windowToShow, true);
- windowIsInFront = true;
- }
- }
- else {
-
- // A floating window is about to be shown. Make sure the windows in the window list
- // are all in the right place.
-
- ValidateWindowList();
-
- // Check to see if a modal window is up before trying to highlight it.
-
- frontNonFloatingWindow = FrontNonFloatingWindow();
- if ((frontNonFloatingWindow != nil) &&
- (frontNonFloatingWindow == (WindowRef) FrontWindow()) &&
- (WindowIsModal(frontNonFloatingWindow)))
- SetWindowHilite(windowToShow, false);
- else {
- SetWindowHilite(windowToShow, true);
- windowIsInFront = true;
- }
- }
-
- // Show the window
-
- ShowHide((WindowPtr) windowToShow, true);
-
- // If this is the new frontmost document window or a floating window, send it an activate event
-
- if (windowIsInFront) {
- activateHandlerProc = GetActivateHandlerProc(windowToShow);
- if (activateHandlerProc != nil)
- CallActivateHandlerProc(activateHandlerProc, windowToShow, kActivateWindow);
- }
- }
-
- //
- // HideReferencedWindow
- //
- // Hide the specified window. If it is frontmost, move it behind the window immediately
- // behind it, like HideWindow does.
- //
-
- pascal void HideReferencedWindow(WindowRef windowToHide)
- {
- WindowRef frontFloater;
- WindowRef frontNonFloater;
- WindowRef lastFloater;
- WindowRef windowBehind;
-
- // Don’t do anything if the window is already invisible.
-
- if (GetWindowVisible(windowToHide) == false)
- return;
-
- // Get the first visible floating window, if any.
-
- frontFloater = (WindowRef) FrontWindow();
- if (GetWindowKind(frontFloater) != kApplicationFloaterKind)
- frontFloater = nil;
-
- // Get the first visible document window, if any.
-
- frontNonFloater = FrontNonFloatingWindow();
-
- // Hide the window.
-
- ShowHide((WindowPtr) windowToHide, false);
-
- // If the frontmost floating window is being hidden, move it behind the floating window
- // behind it, if there is one.
-
- if (windowToHide == frontFloater) {
- windowBehind = GetNextWindow(windowToHide);
-
- // Only do the rearrangement if there’s another floating window.
-
- if ((windowBehind != nil) &&
- (GetWindowKind(windowBehind) == kApplicationFloaterKind)) {
- SetNextWindow(windowToHide, GetNextWindow(windowBehind));
- SetNextWindow(windowBehind, windowToHide);
- SetWindowList(windowBehind);
- }
- }
- else {
-
- // If the frontmost document window is behind hidden, send it behind the window
- // behind it.
-
- if (windowToHide == frontNonFloater) {
- windowBehind = GetNextWindow(windowToHide);
-
- if (windowBehind != nil) {
- SetNextWindow(windowToHide, GetNextWindow(windowBehind));
- SetNextWindow(windowBehind, windowToHide);
-
- // Set the next link of the last floating window to point to the previously second
- // to front document window. If there was no floating window, change the beginning
- // of the window list.
-
- lastFloater = LastFloatingWindow();
- if (lastFloater != nil)
- SetNextWindow(lastFloater, windowBehind);
- else
- SetWindowList(windowBehind);
-
- // The window behind it is now the front document window. Highlight it and send it
- // and activate event.
-
- ActivateWindow(windowBehind);
- }
- }
- }
- }
-
- pascal void DragReferencedWindow(WindowRef windowToDrag, Point startPoint, const Rect *draggingBounds)
- {
- Rect dragRect;
- KeyMap keyMap;
- GrafPtr savePort;
- GrafPtr windowManagerPort;
- RgnHandle dragRegion;
- RgnHandle windowContentRegion;
- long dragResult;
- short topLimit;
- short newHorizontalWindowPosition;
- short newVerticalWindowPosition;
- short horizontalOffset;
- short verticalOffset;
- Boolean commandKeyDown = false;
-
- if (WaitMouseUp()) {
-
- // Adjust the top of the dragging rectangle so that it’s below the menu bar
-
- topLimit = GetMBarHeight() + 4;
- dragRect = *draggingBounds;
- if (dragRect.top < topLimit)
- dragRect.top = topLimit;
-
- // Set up the Window Manager port.
-
- GetPort(&savePort);
- GetWMgrPort(&windowManagerPort);
- SetPort(windowManagerPort);
- SetClip(GetGrayRgn());
-
- // Check to see if the command key is down. If it is, don’t bring the window to the
- // front after the move. Trying to do Pascal stuff in C is so much fun. GetKeys()
- // is a total pain to try to use properly from C, so I’m going to hard code where the
- // command key is in the KeyMap array.
-
- GetKeys(keyMap);
- if (keyMap[1] & 0x8000)
- commandKeyDown = true;
-
- if ((commandKeyDown == true) ||
- (GetWindowKind(windowToDrag) != kApplicationFloaterKind)) {
-
- if (commandKeyDown == false)
-
- // If there are floating windows, clip the dragging outline to draw behind the floaters.
-
- ClipAbove((WindowPeek) FrontNonFloatingWindow());
- else
-
- // If the command key was down, clip the outline to draw behind any windows above
- // the window being dragged.
-
- ClipAbove((WindowPeek) windowToDrag);
- }
-
- // Create a region to drag
-
- dragRegion = NewRgn();
- CopyRgn(GetStructureRegion(windowToDrag), dragRegion);
-
- // Drag the window around
-
- dragResult = DragGrayRgn(dragRegion, startPoint, &dragRect, &dragRect, noConstraint, nil);
-
- // Restore the port for coordinate conversion.
-
- SetPort(savePort);
-
- if (dragResult != 0) {
- horizontalOffset = dragResult & 0xFFFF;
- verticalOffset = dragResult >> 16;
-
- // Only move it if it stayed inside the dragging box.
-
- if (verticalOffset != -32768) {
- windowContentRegion = GetContentRegion(windowToDrag);
- newHorizontalWindowPosition = (**windowContentRegion).rgnBBox.left + horizontalOffset;
- newVerticalWindowPosition = (**windowContentRegion).rgnBBox.top + verticalOffset;
-
- MoveWindow((WindowPtr) windowToDrag, newHorizontalWindowPosition, newVerticalWindowPosition, false);
-
- }
- }
-
- // Bring the window forward if the command key wasn’t down
-
- if (commandKeyDown == false)
- SelectReferencedWindow(windowToDrag);
-
- // Get rid of the dragging region
-
- DisposeRgn(dragRegion);
- }
- }
-
- //
- // FrontNonFloatingWindow
- //
- // Return the first visible window that is not a floating window.
- //
-
- pascal WindowRef FrontNonFloatingWindow(void)
- {
- WindowRef theWindow;
-
- // Get the first visible window in the window list.
-
- theWindow = (WindowRef) FrontWindow();
-
- // Keep searching until a visible window whose windowKind is not
- // kApplicationFloaterKind is found, or the end of the window list is reached.
-
- while ((theWindow != nil) && (GetWindowKind(theWindow) == kApplicationFloaterKind)) {
- do {
- theWindow = GetNextWindow(theWindow);
- } while ((theWindow != nil) && (GetWindowVisible(theWindow) == false));
- }
-
- return theWindow;
- }
-
- //
- // LastFloatingWindow
- //
- // Return the last floating window, whether it is visible or not, or nil if there are
- // no floating windows.
- //
-
- pascal WindowRef LastFloatingWindow(void)
- {
- WindowRef theWindow;
- WindowRef lastFloatingWindow;
-
- theWindow = GetWindowList();
- lastFloatingWindow = nil;
-
- // We have to search the entire window list because we don’t know what the windowKind
- // of other windows in the list might be, and we have account for the fact that a modal
- // dialog is up.
-
- while (theWindow != nil) {
- if (GetWindowKind(theWindow) == kApplicationFloaterKind)
- lastFloatingWindow = theWindow;
- theWindow = GetNextWindow(theWindow);
- }
-
- return lastFloatingWindow;
- }
-
- //
- // WindowIsModal
- //
- // Determines if a window is modal based upon the value of its windowKind and window variant.
- //
-
- pascal Boolean WindowIsModal(WindowRef windowReference)
- {
- short windowVariant;
-
- windowVariant = GetWVariant((WindowPtr) windowReference);
- if ((GetWindowKind(windowReference) == dialogKind) &&
- ((windowVariant == dBoxProc) ||
- (windowVariant == movableDBoxProc)))
- return true;
- else
- return false;
- }
-
- //
- // DeactivateFloatersAndFirstDocumentWindow
- //
- // Send deactivate events to all visible floating windows and the active document
- // window. This routine is called before a modal dialog is presented.
- //
-
- pascal void DeactivateFloatersAndFirstDocumentWindow(void)
- {
- WindowRef firstWindow;
- WindowRef secondDocumentWindow;
- WindowRef currentWindow;
-
- // First, make sure the window ordering hasn’t been changed behind our back
- ValidateWindowList();
-
- // Start from the frontmost window on the screen, and keep going until
- // we’ve reached the second document window.
-
- firstWindow = (WindowRef) FrontWindow();
- secondDocumentWindow = FrontNonFloatingWindow();
- if (secondDocumentWindow != nil)
- secondDocumentWindow = GetNextWindow(secondDocumentWindow);
-
- currentWindow = firstWindow;
- while (currentWindow != secondDocumentWindow) {
- if (GetWindowVisible(currentWindow))
- DeactivateWindow(currentWindow);
- currentWindow = GetNextWindow(currentWindow);
- }
- }
-
- //
- // ActivateFloatersAndFirstDocumentWindow
- //
- // ActivateFloatersAndFirstDocumentWindow should be called after a modal dialog
- // is dismissed. If the application is in the background when this routine is
- // called (like when a moveable modal progress dialog was up and then disappears)
- // this routine calls SuspendFloatingWindows to hide any visible floating windows
- // instead.
- //
-
- pascal void ActivateFloatersAndFirstDocumentWindow(void)
- {
- ProcessSerialNumber currentPSN;
- ProcessSerialNumber frontPSN;
- WindowRef firstWindow;
- WindowRef secondDocumentWindow;
- WindowRef currentWindow;
- OSErr getFrontProcessResult;
- OSErr getCurrentProcessResult;
- OSErr sameProcessResult;
- Boolean isSameProcess;
-
- // See if the this process is in the background. If it is, then the floating
- // windows should be hidden instead of reactivated, so SuspendFloatingWindows()
- // is called instead.
-
- getFrontProcessResult = GetFrontProcess(&frontPSN);
- getCurrentProcessResult = GetCurrentProcess(¤tPSN);
-
- if ((getFrontProcessResult == noErr) && (getCurrentProcessResult == noErr))
- sameProcessResult = SameProcess(&frontPSN, ¤tPSN, &isSameProcess);
-
- if ((sameProcessResult == noErr) && (isSameProcess == false))
- SuspendFloatingWindows();
- else {
- firstWindow = (WindowRef) FrontWindow();
- secondDocumentWindow = FrontNonFloatingWindow();
- if (secondDocumentWindow != nil)
- secondDocumentWindow = GetNextWindow(secondDocumentWindow);
-
- currentWindow = firstWindow;
- while (currentWindow != secondDocumentWindow) {
- if (GetWindowVisible(currentWindow))
- ActivateWindow(currentWindow);
- currentWindow = GetNextWindow(currentWindow);
- }
- }
- }
-
- //
- // SuspendFloatingWindows
- //
- // Hide any visible floating windows, and deactivate the frontmost document window.
- // This routine should be called when an application recieves a suspend event.
- //
-
- pascal void SuspendFloatingWindows(void)
- {
- WindowRef currentWindow;
- Boolean windowIsVisible;
-
- currentWindow = (WindowRef) GetWindowList();
- if (GetWindowKind(currentWindow) != kApplicationFloaterKind)
- return;
-
- do {
- windowIsVisible = GetWindowVisible(currentWindow);
- SetWasVisible(currentWindow, windowIsVisible);
- if (windowIsVisible)
- ShowHide((WindowPtr) currentWindow, false);
- currentWindow = GetNextWindow(currentWindow);
- } while ((currentWindow != nil) &&
- (GetWindowKind(currentWindow) == kApplicationFloaterKind));
-
- // The floating windows are now hidden. Deactivate the first visible
- // document window.
-
- currentWindow = FrontNonFloatingWindow();
- if (currentWindow != nil)
- DeactivateWindow(currentWindow);
- }
-
- //
- // ResumeFloatingWindows
- //
- // Reveal floating windows that were hidden by SuspendFloatingWindows. An
- // activate event is sent to each one as it is revealed. The frontmost document
- // is also sent an activate event.
- //
-
- pascal void ResumeFloatingWindows(void)
- {
- WindowRef currentWindow;
- Boolean windowWasVisible;
-
- currentWindow = GetWindowList();
- if (GetWindowKind(currentWindow) != kApplicationFloaterKind)
- return;
-
- do {
- windowWasVisible = GetWasVisible(currentWindow);
- if (windowWasVisible) {
- ShowHide((WindowPtr) currentWindow, true);
- ActivateWindow(currentWindow);
- }
- currentWindow = GetNextWindow(currentWindow);
- } while ((currentWindow != nil) &&
- (GetWindowKind(currentWindow) == kApplicationFloaterKind));
-
- // The floating windows have been revealed. Activate the first document
- // window as well.
-
- currentWindow = FrontNonFloatingWindow();
- if (currentWindow != nil)
- ActivateWindow(currentWindow);
- }
-
- //
- // ActivateWindow
- //
- // Activates the window by highlighting it, and calling its activate handler.
- //
-
- void ActivateWindow(WindowRef theWindow)
- {
- HighlightAndActivateWindow(theWindow, kActivateWindow);
- }
-
- //
- // DeactivateWindow
- //
- // Deactivates the window by unhighlighting it and calling its activate handler.
- //
-
- void DeactivateWindow(WindowRef theWindow)
- {
- HighlightAndActivateWindow(theWindow, kDeactivateWindow);
- }
-
- //
- // HighlightAndActivateWindow
- //
- // Common code for ActivateWindow and DeactivateWindow. Does actual highlighting
- // and calling of the activate handler.
- //
-
- void HighlightAndActivateWindow(WindowRef theWindow, Boolean activate)
- {
- ActivateHandlerUPP activateHandlerProc;
-
- activateHandlerProc = GetActivateHandlerProc(theWindow);
- HiliteWindow((WindowPtr) theWindow, activate);
- if (activateHandlerProc != nil)
- CallActivateHandlerProc(activateHandlerProc, theWindow, activate);
- }
-
- //
- // ValidateWindowList
- //
- // Code external to the application might call SelectWindow or FrontWindow because they
- // don’t know any better. If the application has floating windows that are invisible
- // when some other code calls FrontWindow then SelectWindow, a document window will get
- // pulled in front of the invisible floating windows. This routine makes sure everything
- // is right with the world, or at least the window list. It assumes that the floating
- // windows are invisible, so visually, nothing changes on the screen. This means that
- // the code doesn’t call CalcVBehind or PaintBehind. If I wanted to be more general,
- // those two calls would have to be made. Ideally, this routine only needs to be called
- // the first time window ordering changes after a foreign window was opened in your
- // applicaiton. I’m actually calling it every time ShowReferencedWindow is called on
- // a floating window, and when new document windows are created or closed, just to be
- // safe.
- //
-
- pascal void ValidateWindowList(void)
- {
- WindowRef currentWindow = GetWindowList();
- WindowRef lastFloatingWindow = LastFloatingWindow();
- WindowRef firstFloatingWindow = nil;
- WindowRef documentWindowsToMove = nil;
- WindowRef lastDocumentWindowAdded = nil;
- WindowRef previousWindow = nil;
-
- if (currentWindow) {
-
- // First, gather up all the document windows in front of floating windows. We iterate
- // through the window list until a floating window is encountered.
-
- do {
- if (GetWindowKind(currentWindow) == kApplicationFloaterKind) {
- firstFloatingWindow = currentWindow;
- break;
- }
- else {
- SetNextWindow(previousWindow, GetNextWindow(currentWindow));
-
- if (documentWindowsToMove == nil)
- documentWindowsToMove = currentWindow;
- else
- SetNextWindow(lastDocumentWindowAdded, currentWindow);
- lastDocumentWindowAdded = currentWindow;
-
- previousWindow = currentWindow;
- currentWindow = GetNextWindow(currentWindow);
- }
- } while (currentWindow);
-
- // Now put them back in their place.
-
- if (documentWindowsToMove && firstFloatingWindow) {
- SetNextWindow(lastDocumentWindowAdded, GetNextWindow(lastFloatingWindow));
- SetNextWindow(lastFloatingWindow, documentWindowsToMove);
-
- // If the first window in the window list was a document window, and there are
- // floating windows, then make the floating window the first window in the window
- // list.
- if (documentWindowsToMove == GetWindowList())
- SetWindowList(firstFloatingWindow);
- }
- }
- }
-
- //
- // Getters and Setters
- //
-
- // GetWindowPortRect — returns the portRect from the window’s GrafPort.
-
- pascal void GetWindowPortRect(WindowRef windowReference, Rect *portRect)
- {
- *portRect = ((WindowPtr) windowReference)->portRect;
- }
-
-
- // Get/SetWindowKind — get and set the windowKind field of the window
-
- pascal short GetWindowKind(WindowRef windowReference)
- {
- return ((WindowPeek) windowReference)->windowKind;
- }
-
- pascal void SetWindowKind(WindowRef windowReference, short windowKind)
- {
- ((WindowPeek) windowReference)->windowKind = windowKind;
- }
-
-
- // Get/SetWindowVisible — get and set the visible field for a window
-
- pascal Boolean GetWindowVisible(WindowRef windowReference)
- {
- return (windowReference->theWindow.visible);
- }
-
- pascal void SetWindowVisible(WindowRef windowReference, Boolean windowVisible)
- {
- windowReference->theWindow.visible = windowVisible;
- }
-
-
- // Get/SetWindowHilite — get and set the hilited field of a window
-
- pascal Boolean GetWindowHilite(WindowRef windowReference)
- {
- return (windowReference->theWindow.hilited);
- }
-
- pascal void SetWindowHilite(WindowRef windowReference, Boolean windowHilite)
- {
- windowReference->theWindow.hilited = windowHilite;
- }
-
-
- // Get/SetNextWindow — get and set the window after this window
-
- pascal WindowRef GetNextWindow(WindowRef windowReference)
- {
- return ((WindowRef) (windowReference->theWindow.nextWindow));
- }
-
- pascal void SetNextWindow(WindowRef windowReference, WindowRef nextWindow)
- {
- windowReference->theWindow.nextWindow = (WindowPeek) nextWindow;
- }
-
-
- // GetContentRegion — return the window’s content region
-
- pascal RgnHandle GetContentRegion(WindowRef windowReference)
- {
- return (windowReference->theWindow.contRgn);
- }
-
-
- // GetStructureRegion — return the window’s structure region
-
- pascal RgnHandle GetStructureRegion(WindowRef windowReference)
- {
- return (windowReference->theWindow.strucRgn);
- }
-
-
- // GetWindowDefPRoc - return a handle to the window’s definition procedure
-
- pascal Handle GetWindowDefProc(WindowRef windowReference)
- {
- return (windowReference->theWindow.windowDefProc);
- }
-
-
- // Get/SetActivateHandlerProc — get and set the activate event handler for this window
-
- pascal ActivateHandlerUPP GetActivateHandlerProc(WindowRef windowReference)
- {
- return (windowReference->activateHandlerProc);
- }
-
- pascal void SetActivateHandlerProc(WindowRef windowReference, ActivateHandlerUPP activateHandlerProc)
- {
- windowReference->activateHandlerProc = activateHandlerProc;
- }
-
-
- // Get/SetWasVisible — save and restore the visible field of a window
-
- pascal Boolean GetWasVisible(WindowRef windowReference)
- {
- return (windowReference->wasVisible);
- }
-
- pascal void SetWasVisible(WindowRef windowReference, Boolean wasVisible)
- {
- windowReference->wasVisible = wasVisible;
- }
-
-
- // GetWindowList — Return the first window in the application’s window list from low memory.
-
- WindowRef GetWindowList(void)
- {
- return (* (WindowRef *) WindowList);
- }
-
- // SetWindowList — Set the first window in this process’ window list.
-
- void SetWindowList(WindowRef windowReference)
- {
- (* (WindowRef *) WindowList) = windowReference;
- }