TweetFollow Us on Twitter

MACINTOSH C

Demonstration Program

Go to Contents
// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
// FloatingWindows.c
// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
//
// This program utilises custom libraries titled FloatingLib68K (for the 68K project) and
// FloatingLibPPC (for the PowerPC project), for which the source code is provided.  
// At startup, it open two floating windows and a document window.  Subsequently,
// document windows, a modal alert box, a movable modal dialog, and the Standard File 
// open dialog box may be opened and closed, and the floating windows may be hidden and 
// shown, so as to prove correct behaviour of all windows in a floating windows
// environment.
//
// The program utilises the following resources:
//
// ¥  An 'MBAR' resource, and 'MENU' resources for Apple, File, Edit and Floaters menus
//    (preload, non-purgeable).
//
// ¥  'WIND' resources (purgeable) (initially not visible) for the document and floating
//    windows.  
//
// ¥  An 'ALRT' resource (purgeable), and associated 'DITL', 'alrx', and 'dftb' resources 
//    (purgeable), for an alert invoked by the user choosing the About FloatingWindows 
//    item in the Apple  menu.
//
// ¥  A 'DLOG' resource (purgeable), and associated 'DITL', 'dlgx', and 'dftb' resources 
//    (purgeable), for a movable modal dialog box invoked when the user chooses the Find
//    item in the Edit menu.
//
// ¥  'PICT' resources (non-purgeable) containing pictures to  be drawn in the floating 
//    windows.
//
// ¥  A 'STR# ' resource (purgeable) containing error strings for an error alert box.
//
// ¥  An icon family (purgeable), which provides an icon drawn in the document windows.
//
// ¥  A 'SIZE' resource with the acceptSuspendResumeEvents, doesActivateOnFGSwitch, and
//    is32BitCompatible flags set.
//
// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

// ............................................................................. includes

#include <Appearance.h>
#include <Devices.h>
#include <StandardFile.h>
#include <ToolUtils.h>

// .............................................................................. defines  

#define rMenuBar               128
#define mApple                 128
#define  iAbout                1
#define mFile                  129
#define  iNew                  1
#define  iOpen                 2
#define  iClose                4
#define  iQuit                 12
#define mEdit                  130
#define  iFind                 9
#define mFloaters              131
#define  iColours              1
#define  iTools                2
#define rDocumentWindow        128
#define rFloaterColoursWindow  129
#define rFloaterToolsWindow    130
#define rColoursPictActive     128
#define rColoursPictInactive   129
#define rToolsPictActive       130
#define rToolsPictInactive     131
#define rAboutAlert            128
#define rFindDialog            129
#define rIconSuite             128
#define rErrorStrings          128

#define kFloaterKind                  7
#define eWindowNotCreatedError        -2
#define eInvalidWindowOrderingError   -3

// ............................................................................. typedefs

typedef pascal void (*ActivateHandlerProcPtr)
                    (WindowPtr theWindow,Boolean activateWindow);
typedef struct
{
  Handle iconSuiteHdl;
} docStruc;

typedef docStruc **docStrucHandle;

// ..................................................................... global variables

Boolean    gDone;
Boolean    gInBackground;
WindowPtr  gColoursFloaterPtr;
WindowPtr  gToolsFloaterPtr;
Handle     gIconSuiteHdl;

// .................................................................. function prototypes

void        main                              (void);
void        doInitManagers                    (void);
void        doOpenDocumentWindow              (void);
void        doOpenFloatingWindows             (void);
void        doEvents                          (EventRecord *);
void        doMouseDown                       (EventRecord *);
void        doUpdate                          (EventRecord *eventStrucPtr);
pascal void doActivateWindow                  (WindowPtr, Boolean);
pascal void doActivateColoursFloater          (WindowPtr, Boolean);
pascal void doActivateToolsFloater            (WindowPtr, Boolean);
void        doAdjustMenus                     (void);
void        doMenuChoice                      (SInt32);
void        doFloatersMenu                    (SInt16 theItem);
void        doAboutBox                        (void);
void        doStandardFileOpen                (void);
void        doOpenFindDialog                  (void);
void        doCloseDocWindow                  (void);
void        doDrawWindowContent               (WindowPtr,Boolean);
void        doErrorAlert                      (OSErr);

// .......................... function prototypes - functions in floating windows library 

OSErr        FW_GetNewCWindow                  (WindowPtr *,SInt16,WindowPtr,
                                               ActivateHandlerProcPtr,Boolean);
void         FW_DisposeWindow                  (WindowPtr);
void         FW_SelectWindow                   (WindowPtr);
void         FW_HideWindow                     (WindowPtr);
void         FW_ShowWindow                     (WindowPtr);
void         FW_DragWindow                     (WindowPtr, Point, const Rect *);
void         FW_doSuspendEvent                 (void);
void         FW_doResumeEvent                  (void);
void         FW_activateFloatsAndFirstDocWin   (void);
void         FW_deactivateFloatsAndFirstDocWin (void);
WindowPtr    FW_findFrontNonFloatWindow        (void);
void         FW_validateWindowList             (void);
SInt32       FW_GetWRefCon                     (WindowPtr);
void         FW_SetWRefCon                     (WindowPtr, SInt32);

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× main

void  main()
{
  Handle      menubarHdl;
  MenuHandle  menuHdl;
  EventRecord  eventStructure;

  // ................................................................ initialise managers

  doInitManagers();

  // .......................................................... set up menu bar and menus
  
  menubarHdl = GetNewMBar(rMenuBar);
  if(menubarHdl == NULL)
    ExitToShell();
  SetMenuBar(menubarHdl);
  DrawMenuBar();

  menuHdl = GetMenuHandle(mApple);
  if(menuHdl == NULL)
    ExitToShell();
  else
    AppendResMenu(menuHdl,'DRVR');

  // ..................................................................... get icon suite

  GetIconSuite(&gIconSuiteHdl,rIconSuite,kSelectorAllLargeData);

  // ..................................................................... set up windows
  
  doOpenDocumentWindow();
  doOpenFloatingWindows();

  // ................................................................... enter event loop

  gDone = false;
  
  while(!gDone) 
  {
    if(WaitNextEvent(everyEvent,&eventStructure,1500,NULL))
      doEvents(&eventStructure);
  }
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doInitManagers

void  doInitManagers(void)
{
  MaxApplZone();
  MoreMasters();

  InitGraf(&qd.thePort);
  InitFonts();
  InitWindows();
  InitMenus();
  TEInit();
  InitDialogs(NULL);

  InitCursor();
  FlushEvents(everyEvent,0);
  
  RegisterAppearanceClient();
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doOpenDocumentWindow

void  doOpenDocumentWindow(void)
{
  WindowPtr       windowPtr;
  OSErr           osError;
  docStrucHandle  docStrucHdl;
  
  FW_validateWindowList();

  osError = FW_GetNewCWindow(&windowPtr,rDocumentWindow,(WindowPtr) -1,
                             (ActivateHandlerProcPtr) &doActivateWindow,false);
  if(osError == noErr) 
  {
    if(!(docStrucHdl = (docStrucHandle) NewHandle(sizeof(docStruc))))
      ExitToShell();
    FW_SetWRefCon(windowPtr,(SInt32) docStrucHdl);
    (*docStrucHdl)->iconSuiteHdl = gIconSuiteHdl;

    FW_ShowWindow(windowPtr);
  }
  else
    doErrorAlert(osError);
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doOpenFloatingWindows

void  doOpenFloatingWindows(void)
{
  OSErr      osError;
  PicHandle  thePicture;
  
  osError = FW_GetNewCWindow(&gColoursFloaterPtr,rFloaterColoursWindow,(WindowPtr) -1,
                             (ActivateHandlerProcPtr) &doActivateColoursFloater,true);
  if(osError == noErr) 
  {
    thePicture = GetPicture(rColoursPictActive);
    SetWindowPic(gColoursFloaterPtr,thePicture);
    FW_ShowWindow(gColoursFloaterPtr);
  }
  else
    doErrorAlert(osError);

  osError = FW_GetNewCWindow(&gToolsFloaterPtr,rFloaterToolsWindow,(WindowPtr) -1,
                             (ActivateHandlerProcPtr) &doActivateToolsFloater,true);
  if(osError == noErr) 
  {
    thePicture = GetPicture(rToolsPictActive);
    SetWindowPic(gToolsFloaterPtr,thePicture);
    FW_ShowWindow(gToolsFloaterPtr);
  }
  else
    doErrorAlert(osError);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doEvents

void  doEvents(EventRecord *eventStrucPtr)
{
  SInt8  charCode;
  
  switch (eventStrucPtr->what) 
  {
    case mouseDown:      
      doMouseDown(eventStrucPtr);
      break;

    case keyDown:
    case autoKey:
      charCode = eventStrucPtr->message & charCodeMask;
      if((eventStrucPtr->modifiers & cmdKey) != 0)
      {
        doAdjustMenus();
        doMenuChoice(MenuEvent(eventStrucPtr));
      }
      break;

    case updateEvt:
      doUpdate(eventStrucPtr);
      break;

    case osEvt:  
      switch((eventStrucPtr->message >> 24) & 0x000000FF) 
      {
        case suspendResumeMessage:  
          if(eventStrucPtr->message & resumeFlag) 
          {
            gInBackground = false;
            FW_doResumeEvent();
          }
          else 
          {
            gInBackground = true;
            FW_doSuspendEvent();
          }
          break;
      }
      break;
  }
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doMouseDown

void  doMouseDown(EventRecord *eventStrucPtr)
{
  SInt16      partCode;
  WindowPtr   windowPtr;
  WindowPtr   frontWindowPtr;
  Rect        growRect;
  UInt32      newSize;

  partCode = FindWindow(eventStrucPtr->where,&windowPtr);

  switch (partCode) 
  {
    case inMenuBar:
      doAdjustMenus();
      doMenuChoice(MenuSelect(eventStrucPtr->where));
      break;

    case inContent:
      frontWindowPtr = FW_findFrontNonFloatWindow();
      if(windowPtr != frontWindowPtr)
        FW_SelectWindow(windowPtr);
      break;

    case inDrag:
      FW_DragWindow(windowPtr,eventStrucPtr->where,&qd.screenBits.bounds);
      break;

    case inGrow:
      growRect = qd.screenBits.bounds;
      growRect.top   = 80; 
      growRect.left = 160;
      newSize = GrowWindow(windowPtr,eventStrucPtr->where,&growRect);
      if(newSize != 0)
        SizeWindow(windowPtr,LoWord(newSize),HiWord(newSize),true);
      break;

    case inGoAway:
      if(TrackGoAway(windowPtr,eventStrucPtr->where))
      {
        if(((WindowPeek) windowPtr)->windowKind == kFloaterKind)
          FW_HideWindow(windowPtr);
        else
          FW_DisposeWindow(windowPtr);
      }
      break;

    case inZoomIn:
    case inZoomOut:
      if(TrackBox(windowPtr,eventStrucPtr->where,partCode))
      {
        SetPort(windowPtr);
        EraseRect(&windowPtr->portRect);
        ZoomWindow(windowPtr,partCode,false);
      }
      break;
  }
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doUpdate

void  doUpdate(EventRecord *eventStrucPtr)
{
  WindowPtr  windowPtr;

  windowPtr = (WindowPtr) eventStrucPtr->message;
  SetPort(windowPtr);

  BeginUpdate(windowPtr);

  EraseRgn(windowPtr->visRgn);
  doDrawWindowContent(windowPtr,((WindowPeek) windowPtr)->hilited);

  EndUpdate(windowPtr);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doActivateWindow

pascal void  doActivateWindow(WindowPtr windowPtr,Boolean becomingActive)
{
  GrafPtr  oldPort;

  GetPort(&oldPort);
  SetPort(windowPtr);

  doDrawWindowContent(windowPtr,becomingActive);

  SetPort(oldPort);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doActivateColoursFloater

pascal void  doActivateColoursFloater(WindowPtr theWindow,Boolean becomingActive)
{
  GrafPtr   oldPort;
  PicHandle thePicture;
  SInt16    pictResourceID;

  GetPort(&oldPort);
  SetPort(theWindow);

  if(becomingActive)
    pictResourceID = rColoursPictActive;
  else
    pictResourceID = rColoursPictInactive;
  thePicture = GetPicture(pictResourceID);

  DrawPicture(thePicture,&((*thePicture)->picFrame));
  SetWindowPic(theWindow,thePicture);

  if(becomingActive == false)
    SetPort(oldPort);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doActivateToolsFloater

pascal void  doActivateToolsFloater(WindowPtr theWindow,Boolean becomingActive)
{
  GrafPtr   oldPort;
  PicHandle thePicture;
  SInt16    pictResourceID;

  GetPort(&oldPort);
  SetPort(theWindow);

  if(becomingActive)
    pictResourceID = rToolsPictActive;
  else
    pictResourceID = rToolsPictInactive;
  thePicture = GetPicture(pictResourceID);

  DrawPicture(thePicture,&((*thePicture)->picFrame));
  SetWindowPic(theWindow,thePicture);

  if(becomingActive == false)
    SetPort(oldPort);
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doAdjustMenus

void  doAdjustMenus(void)
{
  MenuHandle  fileMenuHdl, floatMenuHdl;
  Boolean     isVisible;

  fileMenuHdl = GetMenuHandle(mFile);
  floatMenuHdl = GetMenuHandle(mFloaters);

  if(FW_findFrontNonFloatWindow() == NULL)
    DisableItem(fileMenuHdl,iClose);
  else
    EnableItem(fileMenuHdl,iClose);

  isVisible = ((WindowPeek) gColoursFloaterPtr)->visible;  
  if(isVisible)
    CheckItem(floatMenuHdl,iColours,true);
  else
    CheckItem(floatMenuHdl,iColours,false);

  isVisible = ((WindowPeek) gToolsFloaterPtr)->visible;  
  if(isVisible)
    CheckItem(floatMenuHdl,iTools,true);
  else
    CheckItem(floatMenuHdl,iTools,false);

  DrawMenuBar();
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doMenuChoice

void  doMenuChoice(SInt32 menuChoice)
{
  SInt16    menuID, menuItem;
  Str255    itemName;
  SInt16    daDriverRefNum;

  menuID = HiWord(menuChoice);
  menuItem = LoWord(menuChoice);

  if(menuID == 0)
    return;

  switch(menuID) 
  {
    case mApple:    
      if(menuItem == iAbout)
        doAboutBox();
      else 
      {
        GetMenuItemText(GetMenuHandle(mApple),menuItem,itemName);
        daDriverRefNum = OpenDeskAcc(itemName);
      }
      break;

    case mFile:
      switch(menuItem) 
      {
        case iNew:
          doOpenDocumentWindow();
          break;
      
        case iOpen:
          doStandardFileOpen();
          break;
      
        case iClose:
          doCloseDocWindow();
          break;
      
        case iQuit:
          gDone = true;
          break;
      }
      break;

    case mEdit:
      if(menuItem == iFind)
        doOpenFindDialog();
      break;

    case mFloaters:  
      doFloatersMenu(menuItem);
      break;
  }

  HiliteMenu(0);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doFloatersMenu

void  doFloatersMenu(SInt16 menuItem)
{
  WindowPtr  floaterWindowPtr;
  Boolean    isVisible;

  if(menuItem == iColours)
    floaterWindowPtr = gColoursFloaterPtr;
  else if(menuItem == iTools)
    floaterWindowPtr = gToolsFloaterPtr;

  isVisible = ((WindowPeek) floaterWindowPtr)->visible;  

  if(isVisible)
    FW_HideWindow(floaterWindowPtr);
  else
    FW_ShowWindow(floaterWindowPtr);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doAboutBox

void  doAboutBox()
{
  SInt16  alertResult;

  FW_deactivateFloatsAndFirstDocWin();

  alertResult = Alert(rAboutAlert,NULL);

  FW_activateFloatsAndFirstDocWin();
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doStandardFileOpen

void  doStandardFileOpen()
{
  SFTypeList        fileTypes;
  StandardFileReply  fileReply;

  fileTypes[0] = '****';

  FW_deactivateFloatsAndFirstDocWin();

  StandardGetFile(NULL,-1,fileTypes,&fileReply);

  FW_activateFloatsAndFirstDocWin();
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doOpenFindDialog

void  doOpenFindDialog(void)
{
  DialogPtr dialogPtr;
  SInt16    itemHit;

  FW_deactivateFloatsAndFirstDocWin();

  dialogPtr = GetNewDialog(rFindDialog,NULL,(WindowPtr) -1);
  SetDialogDefaultItem(dialogPtr,kStdOkItemIndex);

  do
  {
    ModalDialog(NULL,&itemHit);
  } while((itemHit != kStdOkItemIndex) && (itemHit != kStdCancelItemIndex));

  DisposeDialog(dialogPtr);

  FW_activateFloatsAndFirstDocWin();
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doCloseDocWindow

void  doCloseDocWindow()
{
  WindowPtr       windowPtr;
  docStrucHandle  docStrucHdl;

  FW_validateWindowList();

  windowPtr = FW_findFrontNonFloatWindow();

  if(windowPtr != NULL)
  {
    docStrucHdl = (docStrucHandle) (FW_GetWRefCon(windowPtr));;
    DisposeHandle((Handle) docStrucHdl);

    FW_DisposeWindow(windowPtr);
  }
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doDrawWindowContent

void  doDrawWindowContent(WindowPtr windowPtr,Boolean isActive)
{
  docStrucHandle  docStrucHdl;
  Rect            theRect;
  Handle          iconSuiteHdl;
    
  docStrucHdl = (docStrucHandle) (FW_GetWRefCon(windowPtr));
  iconSuiteHdl = (*docStrucHdl)->iconSuiteHdl;

  SetRect(&theRect,5,5,37,37);

  if(isActive)
    PlotIconSuite(&theRect,kAlignNone,kTransformNone,iconSuiteHdl);
  else
    PlotIconSuite(&theRect,kAlignNone,kTransformDisabled,iconSuiteHdl);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doErrorAlert

void  doErrorAlert(OSErr errorCode)
{
  AlertStdAlertParamRec paramRec;
  Str255                errorString;
  SInt16                itemHit;

  paramRec.movable        = true;
  paramRec.helpButton     = false;
  paramRec.filterProc     = NULL;
  paramRec.defaultText    = (StringPtr) kAlertDefaultOKText;
  paramRec.cancelText     = NULL;
  paramRec.otherText      = NULL;
  paramRec.defaultButton  = kAlertStdAlertOKButton;
  paramRec.cancelButton   = 0;
  paramRec.position       = kWindowDefaultPosition;

  if(errorCode == eWindowNotCreatedError)
    GetIndString(errorString,rErrorStrings,1);
  else if(errorCode == eInvalidWindowOrderingError)
    GetIndString(errorString,rErrorStrings,2);

  StandardAlert(kAlertStopAlert,errorString,NULL,¶mRec,&itemHit);
  ExitToShell();
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
// FloatingLib.c
// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

// ............................................................................. includes

#include <LowMem.h>

// .............................................................................. defines  

#define kFloaterKind                  7
#define eWindowNotCreatedError        -2
#define eInvalidWindowOrderingError   -3

#define CallActivateHandler(userRoutine,theWindow,activateWindow) \
                           (*userRoutine) (theWindow,activateWindow)

// ............................................................................. typedefs  

typedef pascal void (*ActivateHandlerProcPtr)
                    (WindowPtr theWindow,Boolean activateWindow);

typedef struct 
{
  ActivateHandlerProcPtr  activateHandler;
  Boolean                 wasVisible;
  SInt32                  replacementRefCon;
} refConExtend;

typedef refConExtend **refConExtendHandle;

// .................................................................. function prototypes

OSErr                FW_GetNewCWindow                  (WindowPtr *,SInt16,WindowPtr,
                                                       ActivateHandlerProcPtr,Boolean);
void                 FW_DisposeWindow                  (WindowPtr);
void                 FW_SelectWindow                   (WindowPtr);
void                 FW_HideWindow                     (WindowPtr);
void                 FW_ShowWindow                     (WindowPtr);
void                 FW_DragWindow                     (WindowPtr,Point,const Rect *);
void                 FW_doSuspendEvent                 (void);
void                 FW_doResumeEvent                  (void);
void                 FW_deactivateFloatsAndFirstDocWin (void);
void                 FW_activateFloatsAndFirstDocWin   (void);
WindowPtr            FW_findFrontNonFloatWindow        (void);
void                 FW_validateWindowList             (void);
SInt32               FW_GetWRefCon                     (WindowPtr);
void                 FW_SetWRefCon                     (WindowPtr,SInt32);
void                 activateWindow                    (WindowPtr);
void                 deactivateWindow                  (WindowPtr);
void                 highlightAndActivateWindow        (WindowPtr,Boolean);
WindowPtr            findLastFloatingWindow            (void);
OSErr                checkWindowOrdering               (Boolean,WindowPtr *);
WindowPtr            getNextVisibleWindow              (WindowPtr);
Boolean              getWasVisible                     (WindowPtr);
void                 setWasVisible                     (WindowPtr,Boolean);
Boolean              isWindowModal                     (WindowPtr);
void                 bringFloatersToFront              (WindowPtr);
Boolean              isFrontProcess                    (void);
Boolean              getIsWindowVisible                (WindowPtr);
WindowPtr            getNextWindow                     (WindowPtr);
SInt16               getWindowKind                     (WindowPtr);
RgnHandle            getStructureRegion                (WindowPtr);
RgnHandle            getContentRegion                  (WindowPtr);
ActivateHandlerProcPtr  getActivateHandler             (WindowPtr);
void                setActivateHandler                 (WindowPtr,ActivateHandlerProcPtr);

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_GetNewCWindow

OSErr  FW_GetNewCWindow(WindowPtr *windowPtr,SInt16 windResourceID,WindowPtr behind,
                        ActivateHandlerProcPtr activateHandler,Boolean isFloater)
{
  OSErr               result;
  refConExtendHandle  refConExtendHdl;
  WindowPtr           newWindowPtr;
  SInt32              replacementRefCon;
  Boolean             isVisible;

  *windowPtr = NULL;

   result = checkWindowOrdering(isFloater,&behind);
   if(result != noErr)
     return result;  

  refConExtendHdl = (refConExtendHandle) NewHandle(sizeof(refConExtend));
  
  if((result = MemError()) == noErr)
  {
    newWindowPtr = GetNewCWindow(windResourceID,NULL,behind);

    if(newWindowPtr != NULL)
    {
      *windowPtr = newWindowPtr;

      replacementRefCon = GetWRefCon(newWindowPtr);
      SetWRefCon(newWindowPtr,(SInt32) refConExtendHdl);
      FW_SetWRefCon(newWindowPtr,replacementRefCon);

      setActivateHandler(newWindowPtr,activateHandler);

      if(isFloater)
      {
        ((WindowPeek) newWindowPtr)->windowKind = kFloaterKind;

        isVisible = ((WindowPeek) newWindowPtr)->visible;

        if(isVisible)
        {
          if(!isFrontProcess())
          {
            ShowHide(newWindowPtr,false);
            setWasVisible(newWindowPtr,true);
          }  
        }
      }
    }
    else
    {
      DisposeHandle((Handle) refConExtendHdl);
      result = eWindowNotCreatedError;
    }
  }
  return result;
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_DisposeWindow

void  FW_DisposeWindow(WindowPtr windowPtr)
{
  refConExtendHandle  refConExtendHdl;

  if(getIsWindowVisible(windowPtr))
    FW_HideWindow(windowPtr);

  refConExtendHdl = (refConExtendHandle) GetWRefCon(windowPtr);
  if(refConExtendHdl != NULL)
    DisposeHandle((Handle) refConExtendHdl);

  DisposeWindow(windowPtr);
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_SelectWindow

void  FW_SelectWindow(WindowPtr windowPtr)
{
  Boolean    frontProcess, isFloatingWindow;
  WindowPtr  currentFrontWindowPtr, lastFloatingWindowPtr;

  frontProcess = isFrontProcess();

  if(getWindowKind(windowPtr) == kFloaterKind) 
  {
    isFloatingWindow = true;
    currentFrontWindowPtr = FrontWindow();
  }
  else 
  {
    isFloatingWindow = false;
    currentFrontWindowPtr = FW_findFrontNonFloatWindow();
    lastFloatingWindowPtr = findLastFloatingWindow();
  }

  if(currentFrontWindowPtr != windowPtr) 
  {
    if(isFloatingWindow)
    {
      BringToFront(windowPtr);
    }
    else
    {
      if(frontProcess)
        deactivateWindow(currentFrontWindowPtr);

      if(lastFloatingWindowPtr == NULL)
      {
        BringToFront(windowPtr);
      }
      else
      {
        SendBehind(windowPtr,lastFloatingWindowPtr);
      }

      if(frontProcess)
        activateWindow(windowPtr);
    }
  }
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_HideWindow

void  FW_HideWindow(WindowPtr windowPtr)
{
  WindowPtr  frontFloatWindowPtr, frontNonFloatWindowPtr, windowBehind;

  if(getIsWindowVisible(windowPtr) == false)
    return;
  
  frontFloatWindowPtr = FrontWindow();
  if(getWindowKind(frontFloatWindowPtr) != kFloaterKind)
    frontFloatWindowPtr = NULL;

  frontNonFloatWindowPtr = FW_findFrontNonFloatWindow();
  
  ShowHide(windowPtr,false);
  
  if(windowPtr == frontFloatWindowPtr)
  {
    windowBehind = getNextVisibleWindow(windowPtr);

    if((windowBehind != NULL) && (getWindowKind(windowBehind) == kFloaterKind))
      BringToFront(windowBehind);
  }
  else if(windowPtr == frontNonFloatWindowPtr)
  {
    windowBehind = getNextVisibleWindow(windowPtr);
    
    if(windowBehind != NULL)
    {
      SendBehind(windowPtr,windowBehind);

      if(isFrontProcess())
        activateWindow(windowBehind);
    }
  }
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_ShowWindow

void  FW_ShowWindow(WindowPtr windowPtr)
{
  Boolean                 frontProcess, needsActivate, highlightState;
  Boolean                 modalUp, showingModal;
  SInt16                  windowKind;
  WindowPtr               windowBehind;
  WindowPtr               frontNonFloatWindowPtr;
  ActivateHandlerProcPtr  activateHandler;

  if(getIsWindowVisible(windowPtr) != false)
    return;

  frontProcess = isFrontProcess();

  windowKind = getWindowKind(windowPtr);

  modalUp = isWindowModal(FrontWindow());

  showingModal = isWindowModal(windowPtr);
  if(showingModal)
    BringToFront(windowPtr);

  FW_validateWindowList();

  if(!frontProcess && windowKind == kFloaterKind)
  {
    setWasVisible(windowPtr,true);
    return;
  }

  if(frontProcess)
  {
    if(showingModal)
    {
      highlightState = true;
      needsActivate = true;
    }
    else if(modalUp)
    {
      highlightState = false;
      needsActivate = false;
    }
    else
    {
      if(windowKind == kFloaterKind)
      {
        highlightState = true;
        needsActivate = true;
      }
      else
      {
        frontNonFloatWindowPtr = FW_findFrontNonFloatWindow();
        if(frontNonFloatWindowPtr == NULL)
        {
          highlightState = true;
          needsActivate = true;
        }
        else
        {
          highlightState = false;
          needsActivate = false;

          windowBehind = getNextWindow(windowPtr);
          while(windowBehind != NULL)
          {
            if(windowBehind == frontNonFloatWindowPtr)
            {
              deactivateWindow(frontNonFloatWindowPtr);
              highlightState = true;
              needsActivate = true;
              break;
            }
            windowBehind = getNextVisibleWindow(windowBehind);
          }
        }
      }
    }
  }
  else
  {
    highlightState = false;
    needsActivate = false;
  }

  HiliteWindow(windowPtr,highlightState);
  ShowHide(windowPtr,true);

  if(needsActivate) 
  {
    activateHandler = getActivateHandler(windowPtr);
    if(activateHandler != NULL)
      CallActivateHandler(activateHandler,windowPtr,true);
  }
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_DragWindow

void  FW_DragWindow(WindowPtr windowPtr,Point startPoint,const Rect *draggingBounds)
{
  SInt16    topLimit, newHorizontalWindowPosition, newVerticalWindowPosition;
  Rect      dragRect;
  SInt16    horizontalOffset, verticalOffset;
  GrafPtr   savePort, windowManagerPort;
  KeyMap    keyMap;
  Boolean   commandKeyDown = false;
  RgnHandle dragRegionHdl, windowContentRegionHdl;
  SInt32    dragResult;

  if(StillDown()) 
  {
    topLimit = LMGetMBarHeight() + 4;
    dragRect = *draggingBounds;
    if(dragRect.top < topLimit)
      dragRect.top = topLimit;
  
    GetPort(&savePort);
    GetWMgrPort(&windowManagerPort);
    SetPort(windowManagerPort);

    SetClip(GetGrayRgn());

    GetKeys(keyMap);
    if(keyMap[1] & 0x8000)
      commandKeyDown = true;
  
    if((commandKeyDown == true) || (getWindowKind(windowPtr) != kFloaterKind)) 
    {
      if(commandKeyDown == false)
        ClipAbove(FW_findFrontNonFloatWindow());
      else
        ClipAbove(windowPtr);
    }

    dragRegionHdl = NewRgn();
    CopyRgn(getStructureRegion(windowPtr),dragRegionHdl);
  
    dragResult = DragGrayRgn(dragRegionHdl,startPoint,&dragRect,&dragRect,noConstraint,
                             NULL);
    SetPort(savePort);

    if(dragResult != 0) 
    {
      horizontalOffset = dragResult & 0xFFFF;
      verticalOffset = dragResult >> 16;

      if(verticalOffset != -32768) 
      {
        windowContentRegionHdl = NewRgn();
        CopyRgn(getContentRegion(windowPtr),windowContentRegionHdl);
  
        newHorizontalWindowPosition = (**windowContentRegionHdl).rgnBBox.left + 
                                      horizontalOffset;
        newVerticalWindowPosition = (**windowContentRegionHdl).rgnBBox.top + 
                                    verticalOffset;
        MoveWindow(windowPtr,newHorizontalWindowPosition,newVerticalWindowPosition,
                   false);
                   
        DisposeRgn(windowContentRegionHdl);
      }
    }

    if(commandKeyDown == false)
      FW_SelectWindow(windowPtr);

    DisposeRgn(dragRegionHdl);
  }
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_doSuspendEvent

void  FW_doSuspendEvent(void)
{
  WindowPtr  currentWindowPtr;
  Boolean    windowIsVisible;

  currentWindowPtr = LMGetWindowList();

  if(isWindowModal(FrontWindow()))
    return;

  while((currentWindowPtr != NULL) && 
        (getWindowKind(currentWindowPtr) == kFloaterKind))
  {
    windowIsVisible = getIsWindowVisible(currentWindowPtr);
    setWasVisible(currentWindowPtr,windowIsVisible);

    if(windowIsVisible)
      ShowHide(currentWindowPtr,false);
      
    currentWindowPtr = getNextWindow(currentWindowPtr);
  }

  currentWindowPtr = FW_findFrontNonFloatWindow();
  if(currentWindowPtr != NULL)
    deactivateWindow(currentWindowPtr);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_doResumeEvent

void  FW_doResumeEvent(void)
{
  WindowPtr  currentWindowPtr;
  Boolean    windowWasVisible;

  currentWindowPtr = LMGetWindowList();

  if(isWindowModal(FrontWindow()))
    return;
    
  while((currentWindowPtr != NULL) &&
        (getWindowKind(currentWindowPtr) == kFloaterKind))
  {
    windowWasVisible = getWasVisible(currentWindowPtr);
    if(windowWasVisible) 
    {
      ShowHide(currentWindowPtr,true);
      activateWindow(currentWindowPtr);
    }

    currentWindowPtr = getNextWindow(currentWindowPtr);
  }

  currentWindowPtr = FW_findFrontNonFloatWindow();
  if(currentWindowPtr != NULL)
    activateWindow(currentWindowPtr);
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_activateFloatsAndFirstDocWin

void  FW_activateFloatsAndFirstDocWin(void)
{
  WindowPtr  firstWindowPtr, secondDocumentWindowPtr, currentWindowPtr;
  Boolean    frontProcess;

  if(isWindowModal(FrontWindow()))
    return;

  frontProcess = isFrontProcess();

  if(frontProcess == false)
    FW_doSuspendEvent();
  else 
  {
    firstWindowPtr = FrontWindow();
    secondDocumentWindowPtr = FW_findFrontNonFloatWindow();

    if(secondDocumentWindowPtr != NULL)
      secondDocumentWindowPtr = getNextWindow(secondDocumentWindowPtr);

    currentWindowPtr = firstWindowPtr;

    while(currentWindowPtr != secondDocumentWindowPtr) 
    {
      if(getIsWindowVisible(currentWindowPtr))
        activateWindow(currentWindowPtr);
      currentWindowPtr = getNextWindow(currentWindowPtr);
    }
  }
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××× FW_deactivateFloatsAndFirstDocWin

void  FW_deactivateFloatsAndFirstDocWin(void)
{
  WindowPtr  firstWindowPtr, secondDocumentWindowPtr, currentWindowPtr;

  FW_validateWindowList();

  firstWindowPtr = FrontWindow();
  secondDocumentWindowPtr = FW_findFrontNonFloatWindow();

  if(secondDocumentWindowPtr != NULL)
    secondDocumentWindowPtr = getNextWindow(secondDocumentWindowPtr);

  currentWindowPtr = firstWindowPtr;

  while(currentWindowPtr != secondDocumentWindowPtr) 
  {
    if(getIsWindowVisible(currentWindowPtr))
      deactivateWindow(currentWindowPtr);
    currentWindowPtr = getNextWindow(currentWindowPtr);
  }
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_findFrontNonFloatWindow

WindowPtr  FW_findFrontNonFloatWindow(void)
{
  WindowPtr  windowPtr;

  windowPtr = FrontWindow();

  while((windowPtr != NULL) && (getWindowKind(windowPtr) == kFloaterKind)) 
  {
    do 
    {
      windowPtr = getNextWindow(windowPtr);
    } while((windowPtr != NULL) && (getIsWindowVisible(windowPtr) == false));
  }

  return windowPtr;
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_validateWindowList

void  FW_validateWindowList(void)
{
  WindowPtr  windowPtr;
  WindowPtr  lastFloatingWindowPtr;

  windowPtr = LMGetWindowList();
  lastFloatingWindowPtr = findLastFloatingWindow();

  if(lastFloatingWindowPtr == NULL)
    return;

  if(getWindowKind(windowPtr) == kFloaterKind)
    return;

  if(isWindowModal(windowPtr))
    return;

  bringFloatersToFront(windowPtr);
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_GetWRefCon

SInt32  FW_GetWRefCon(WindowPtr windowPtr)
{
  refConExtendHandle  refConExtendHdl;

  refConExtendHdl =(refConExtendHandle) GetWRefCon(windowPtr);
  if(refConExtendHdl != NULL)
    return((*refConExtendHdl)->replacementRefCon);
  else
    return 0;
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× FW_SetWRefCon

void  FW_SetWRefCon(WindowPtr windowPtr,SInt32 refCon)
{
  refConExtendHandle  refConExtendHdl;

  refConExtendHdl =(refConExtendHandle) GetWRefCon(windowPtr);
  if(refConExtendHdl != NULL)
  {
    (*refConExtendHdl)->replacementRefCon = refCon;
  }
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× activateWindow

void  activateWindow(WindowPtr windowPtr)
{
  highlightAndActivateWindow(windowPtr,true);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× deactivateWindow

void  deactivateWindow(WindowPtr windowPtr)
{
  highlightAndActivateWindow(windowPtr,false);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× highlightAndActivateWindow

void  highlightAndActivateWindow(WindowPtr windowPtr,Boolean activate)
{
  ActivateHandlerProcPtr  activateHandler;
  
  if(windowPtr == NULL)
    return;

  activateHandler = getActivateHandler(windowPtr);

  HiliteWindow(windowPtr,activate);

  if(activateHandler != NULL)
    CallActivateHandler(activateHandler,windowPtr,activate);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× findLastFloatingWindow

WindowPtr  findLastFloatingWindow(void)
{
  WindowPtr  windowPtr;

  WindowPtr  lastFloatingWindowPtr;

  windowPtr = LMGetWindowList();
  lastFloatingWindowPtr = NULL;
  
  while(windowPtr != NULL) 
  {
    if(getWindowKind(windowPtr) == kFloaterKind)
      lastFloatingWindowPtr = windowPtr;

    windowPtr = getNextWindow(windowPtr);
  }

  return lastFloatingWindowPtr;
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× checkWindowOrdering

OSErr  checkWindowOrdering(Boolean isFloater,WindowPtr *behind)
{
  OSErr      result = noErr;
  WindowPtr  lastFloaterPtr;
  
  if(isFloater)
  {
    if(((*behind == NULL) && (FW_findFrontNonFloatWindow() != NULL)) ||
       ((*behind != (WindowPtr) -1) && (getWindowKind(*behind) != kFloaterKind))  )
    {
      result = eInvalidWindowOrderingError;
    }
  }
   else
  {
    lastFloaterPtr = findLastFloatingWindow();
 
    if(lastFloaterPtr != NULL)
    {
      if(*behind == (WindowPtr) -1)
      {
        *behind = lastFloaterPtr;
      }
      else if(*behind != NULL && *behind != lastFloaterPtr &&
              (getWindowKind(*behind) == kFloaterKind))
      {
        result = eInvalidWindowOrderingError;
      }
    }
  }
  
   return result;
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× getNextVisibleWindow

WindowPtr  getNextVisibleWindow(WindowPtr windowPtr)
{
  WindowPtr  nextWindowPtr;
  
  nextWindowPtr = getNextWindow(windowPtr);

  while(nextWindowPtr != NULL)
  {
    if(getIsWindowVisible(nextWindowPtr))
      break;
    nextWindowPtr = getNextWindow(nextWindowPtr);
  }

  return nextWindowPtr;
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× getWasVisible

Boolean  getWasVisible(WindowPtr windowPtr)
{
  refConExtendHandle  refConExtendHdl;
  
  refConExtendHdl =(refConExtendHandle) GetWRefCon(windowPtr);

  if(refConExtendHdl != NULL)
    return((*refConExtendHdl)->wasVisible);
  else
    return false;
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× setWasVisible

void  setWasVisible(WindowPtr windowPtr,Boolean wasVisible)
{
  refConExtendHandle  refConExtendHdl;

  refConExtendHdl = (refConExtendHandle) GetWRefCon(windowPtr);

  if(refConExtendHdl != NULL)
    (*refConExtendHdl)->wasVisible = wasVisible;
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× isWindowModal

Boolean  isWindowModal(WindowPtr windowPtr)
{
  SInt16  windowVariant;
  SInt16  windowKind;

  windowVariant = GetWVariant(windowPtr);
  windowKind = getWindowKind(windowPtr);

  if(windowKind == kDialogWindowKind && (windowVariant == 2 || windowVariant == 3))
    return true;
  else
    return false;
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× bringFloatersToFront

void  bringFloatersToFront(WindowPtr windowPtr)
{
  WindowPtr  thisFloaterPtr;

  while(windowPtr != NULL && getWindowKind(windowPtr) != kFloaterKind)
    windowPtr = getNextWindow(windowPtr);

  if(windowPtr == NULL)
    return;

  thisFloaterPtr = windowPtr;

  bringFloatersToFront(getNextWindow(windowPtr));

  BringToFront(thisFloaterPtr);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× isFrontProcess

Boolean  isFrontProcess(void)
{
  ProcessSerialNumber  frontPSN, currentPSN;
  OSErr                getFrontProcessResult, getCurrentProcessResult;
  Boolean              isSameProcess = false;

  getFrontProcessResult = GetFrontProcess(&frontPSN);
  getCurrentProcessResult = GetCurrentProcess(¤tPSN);
  
  if((getFrontProcessResult == noErr) && (getCurrentProcessResult == noErr))
    SameProcess(&frontPSN,¤tPSN,&isSameProcess);

  return(isSameProcess);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× getIsWindowVisible

Boolean  getIsWindowVisible(WindowPtr windowPtr)
{
  return(((WindowPeek) windowPtr)->visible);
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× getNextWindow

WindowPtr  getNextWindow(WindowPtr windowPtr)
{
  return((WindowPtr) ((WindowPeek) windowPtr)->nextWindow);
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× getWindowKind

SInt16  getWindowKind(WindowPtr windowPtr)
{
  return(((WindowPeek) windowPtr)->windowKind);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× getStructureRegion

RgnHandle  getStructureRegion(WindowPtr windowPtr)
{
  return(((WindowPeek) windowPtr)->strucRgn);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× getContentRegion

RgnHandle  getContentRegion(WindowPtr windowPtr)
{
  return(((WindowPeek) windowPtr)->contRgn);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× getActivateHandler

ActivateHandlerProcPtr  getActivateHandler(WindowPtr windowPtr)
{
  refConExtendHandle  refConExtendHdl;

  refConExtendHdl = (refConExtendHandle) GetWRefCon(windowPtr);
  if(refConExtendHdl != NULL)
    return((*refConExtendHdl)->activateHandler);
  else
    return NULL;
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× setActivateHandler

void  setActivateHandler(WindowPtr windowPtr,ActivateHandlerProcPtr activateHandler)
{
  refConExtendHandle  refConExtendHdl;

  refConExtendHdl = (refConExtendHandle) GetWRefCon(windowPtr);

  if(refConExtendHdl != NULL)
    (*refConExtendHdl)->activateHandler = activateHandler;
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

Demonstration Program Comments

With regard to the source code file FloatingLib.c, which contains all the special
functions required to implement floating windows, two options are available.
Firstly,FloatingLib.c may be added to the FloatingWindows.µ project, along with
the source codefile FloatingWindows.c, in the normal way.  Secondly, FloatingLib.c
may be compiled as alibrary (68K or PowerPC, as required) and added to the 
FloatingWindows.µ project as such. The latter option has been adopted in the
accompanying demonstration program package.

When this program is run, the user should open and close document windows, hide and show
the floating windows (using the Floater menu items and the windows' close boxes), open
and close the About FloatingWindows... modal alert box, open and close the Find movable
modal dialog box (using the Find item in the Edit menu), open and close the Standard File
open dialog, and send/bring the application to the background/foreground.  In particular,
the user should observe the following:

*   Document window behaviour, in terms of activation and deactivation, is identical to
    that observed in a normal window environment, including when:

*   The program is sent to the background and brought to the foreground.

*   A document window is closed or a new document window is opened.

*   The About FloatingWindows... modal alert box, the Find... movable modal dialog box,
    or the Standard File open dialog is invoked.

*   An inactive document window is dragged with the Command key held down.

*   Floating window behaviour is as follows:

*   The floating window frames are drawn in the inactive state, and their content is
    dimmed, when the alert and dialog boxes are invoked.

*   The floating windows are hidden when the application is sent to the background and 
    shown again when the application is brought to the foreground.

*   When document windows are clicked, the icon at the top left of the window is drawn
    in such a way (normal or dimmed) as to prove that the application "knows" which
    document windows to activate and deactivate.

FloatingWindows.c

#define

rDocumentWindow and the following two constants represent the resource IDs of the 'WIND'
resources for document windows, the "Colours" floating window, and the "Tools" floating
window.  The next four constants represent the resource IDs of four 'PICT' resources used
by the floating windows.

kFloaterKind will be assigned to the windowKind field of the floating window window
structures.  The next two constants represent error codes that may be returned by a call
to the window creation function in FloatingLib.c.

#typedef

A document structure of type docStruc will be created for each document window.  For the
purposes of this demonstration, this is simply to prove the correct operation of the two
substitute functions FW_SetWRefCon and FW_GetWRefCon.  (These functions will
assign/retrieve the handle to the window's document structure to/from a reference
constant field in a special structure created by the window creation function in
FloatingLib.c.)

Global Variables

gColoursFloaterPtr and gToolsFloaterPtr will be assigned pointers to the colour 
graphics port structures for the floating windows.  gIconSuiteHdl will be assigned a 
handle to an icon suite.

main

Following the call to RegisterAppearanceClient, routine descriptors are created for the
three window activation functions.

The call to GetIconSuite creates an icon family.  The appropriate icon from this family
will be drawn in the top left corner of document windows.  The handle will be assigned to
the single field in the document window's document structure.

The next two lines call application-defined functions which open one document window and
both floating windows.

doOpenDocumentWindow

doOpenDocumentWindow opens a document window.

Firstly, FW_ validateWindowList is called as a safety measure to ensure that all floating
windows are in front of all document windows (if any).

FW_GetNewCWindow is called to create the window.  The universal procedure pointer to the
document window activation function is passed in the fourth parameter.  false is passed
in the fifth parameter to indicate to FW_GetNewCWindow that this is not a floating
window.

If FW_GetNewCWindow does not return an error, a block for a document structure is created
and the handle is assigned by FW_SetWRefCon to the reference constant field of a
structure created by FW_GetNewCWindow.  (FW_GetNewCWindow assigns the handle to this
latter structure to the window's refCon field.)  The handle to the icon family is
assigned to the single field of the document structure.

FW_ShowWindow is called to show the window.

If FW_GetNewCWindow does return an error, an application-defined function is called to
handle the error.

doOpenFloatingWindows

doOpenFloatingWindows opens both floating windows.

For each of the two floating windows, FW_GetNewCWindow is called to create the window. 
 A pointer to the appropriate window activation function is passed in the fourth 
parameter.  true is passed in the fifth parameter to indicate to FW_GetNewCWindow that 
this is a floating window.

If FW_GetNewCWindow does not return an error, GetPicture loads the specified 'PICT'
resource, SetWindowPic stores the handle to the picture structure in the windowPic field
of the window structure (meaning that the Window Manager will draw the picture in the
window instead of generating update events for it), and FW_ShowWindow is called to
display the floating window.

If FW_GetNewCWindow does return an error, an application-defined function is called to
handle the error.

doEvents

Note that activate events are ignored in the main event loop area because, in a floating
windows environment, the normal windows activation/deactivation mechanism must be
over-ruled.

At the suspendResumeMessage case in the osEvt case, FW_doResumeEvent is called for a
resume event and FW_doResumeEvent is called for a suspend event.

doMouseDown

At the inContent case, if the window in which the mouse-down occurred is not the front
non-floating window, FW_SelectWindow is called.

At the inDrag case, FW_DragWindow is called.

At the inGoAway case, if the window is one of the floating windows, FW_HideWindow is
called to hide the window.  If the window is a document window, FW_DisposeWindow is
called to dispose of the window.

doUpdate

An update event results in a call to doDrawWindowContent, which draws an icon in the
window in the appropriate state (normal or dimmed).  (Recall that, because of the
setWindowPic calls in the function doOpenFloatingWindows, the floating windows will not
receive update events.  Accordingly, the only windows redrawn by the application in this
demonstration are the document windows.)

doActivateWindow

doActivateWindow is called from functions within FloatingLib.c.  It is not called from
within FloatingWindows.c.

doActivateWindow is the window activation function for document windows.
doDrawWindowContent is called to draw an icon in the window in the state (normal or
dimmed) specified by the becomingActive parameter.

doActivateColoursFloater and doActivateToolsFloater

doActivateColoursFloater and doActivateToolsFloater are called from functions within
FloatingLib.c.  They are not called from within FloatingWindows.c.

These two functions are the window activation functions for the floating windows. 
Depending on whether the window is being activated or deactivated, the appropriate
picture (normal or dimmed) is drawn in the window and SetWindowPict is called to store
the handle to the picture structure in the windowPic field of the window structure
(meaning that the Window Manager will draw the picture in the window instead of
generating update events for it).

doAdjustMenus

FW_findFrontNonFloatWindow() is called to determine whether any document windows are
currently open.  If not, the Close item in the File menu is disabled.

If the floating windows are currently hidden, the relevant item in the Floaters menu is
unchecked, otherwise it is checked.

doFloatersMenu

doFloatersMenu further processes Floater menu choices.

If the floating window relating to the chosen menu item is currently showing,
FW_HideWindow is called to hide the window, otherwise FW_ShowWindow is called to show the
window.

doAboutBox, doStandardFileOpen, and doOpenFindDialog

doAboutBox is called when the user chooses the About FloatingWindows... item in the Apple
menu.  FW_deactivateFloatsAndFirstDocWin is called to deactivate all the document and
floating windows before Alert is called to display the About alert box.  When the alert
box is dismissed, FW_activateFloatsAndFirstDocWin is called to return the windows to the
activation status they were in prior to the call to FW_deactivateFloatsAndFirstDocWin.

The same activation/deactivation procedure is followed in the functions
doStandardFileOpen and doOpenFindDialog.

doCloseDocWindow

doCloseDocWindow is called in response to a choice of the Close item in the File menu and
to a click in a document window's close box.

FW_validateWindowList is called as a safety measure to ensure that all floating windows
are in front of all document windows.

The call to FW_findFrontNonFloatWindow returns a pointer to the front document window
(and also confirms that at least one document window is open.  FW_GetWRefCon is called to
get the handle to the window's document structure, which allows that block to be disposed
of. FW_DisposeWindow is then called to dispose of the block containing the special data
structure created by FW_GetNewCWindow, to remove the window from the screen and window
list, and to discard all the window's data storage.

doDrawWindowContent

doDrawDocWindowContent is called when an update event is received and when the document
window activate function is called from within FloatingLib.c.  It simply draws an icon in
the top left of the window in the state (normal or dimmed) specified by the isActive
formal parameter.

FloatingLib.c

FloatingLib.c contains the special functions required to support a floating windows
environment, including functions which are called in lieu of the usual calls to
GetNewCWindow, DisposeWindow, SelectWindow, HideWindow, ShowWindow, DragWindow,
SetWRefCon, and GetWRefCon.

#define

kFloaterKind will be assigned to the windowKind field of the window structures for 
floating windows.  The next two constants represent error codes returned by 
FW_GetNewCWindow.  CallActivateHandler simply makes the call to the appropriate window 
activation handler at the bottom of the functions FW_ShowWindow and 
highlightAndActivateWindow a little less cryptic.

#typedef

A structure of type refConExtend will be created for all windows, and a handle to 
that structure will be assigned to the window structure's refCon field.  A pointer to 
the relevant window activation function will be assigned to the first field.  The 
second field will be used to keep track of the window's visibility status.  The third 
field may be used by the application for those purposes for which it would normally use 
the window structure's refCon field.

FW_GetNewCWindow

To create a window, FW_GetNewCWindow is called in lieu of the usual call to
GetNewCWindow.  The isFloater parameter specifies whether the window is to be a document
window or a floating window.

At the first line, failure is assumed.  

checkWindowOrdering is called to ensure that the behind formal parameter is not
attempting to open the window at an inappropriate "behind" or "in front of" location in
the window list.  As part of this process, and in the case of document windows,
checkWindowOrdering changes a behind assignment of (WindowPtr) -1 to the pointer to the
last floating window, causing the window to be opened behind that floating window rather
than in front of all windows.  Apart from that particular case, inappropriate behind
specifications will cause an error to be returned.

The call to NewHandle creates a block for a refConExtend structure.  If this call is not
successful, the function exits and an error code is returned to the calling function.

The call to GetNewCWindow creates the window, following which a pointer to the window is 
returned to the calling function.  The next three lines assign the handle to the 
refConExtend structure to the window structure's refCon field and assign the previous 
value in the refCon field to the refConExtend structure's replacementRefCon field.  The 
next line assigns the pointer to the window's activation function to the refConExtend 
structure's activateHandler field.

If the visible field of the window's window structure indicates that the window is
currently visible, and if the application is currently not the front process, ShowHide is
called to hide the window and setWasVisible is called to record the visibility status of
the window by assigning true to the refConExtend structure's wasVisible field.  (This
block caters for the possibility of windows being created while the application is in the
background, for example, by Apple events.  It prevents the window from being highlighted
on creation.)

If the call to GetNewCWindow was not successful, the subsequent if block is bypassed,
DisposeHandle is called to dispose of the refConExtend structure, and an error code is
returned to the calling function.

FW_DisposeWindow

FW_DisposeWindow is called in lieu of the usual call to DisposeWindow.

If the specified window (which will invariably be a document window) is visible, a call
is made to FW_HideWindow so that the next document window in the list (if any) is
activated.  The window's refConExtend structure is then disposed of, following which
DisposeWindow is called to remove the window from the screen, remove it from the window
list, and discard all its data storage.

FW_SelectWindow

FW_SelectWindow is called in lieu of the usual call to SelectWindow.  It selects the
window and brings it to the front of its section of the window list.  Selecting a
floating window makes it the absolute frontmost window on the screen, whereas selecting a
document window makes it the frontmost window behind the floating windows (or, if no
floating windows are open, the absolute frontmost window).

The first line determines whether the application is the front process.

If the window clicked is of the floating kind, that fact is recorded and the pointer to
the current front floating window is retrieved.  Otherwise, if the window clicked is a
document window, that fact is recorded, and pointers to the first document window and
last floating window in the window list are retrieved.

If the window clicked is not the current front window in either the floating or document
window sections of the window list and if the window clicked is a floating window, that
window is brought to the very front of the list by the call to BringToFront.  Otherwise,
if the window clicked is a document window: if the application is the front process, the
current front document window is deactivated; if their are no floating windows,
BringToFront is called to bring the window to the front; if there are floating windows,
SendBehind is called to locate the window immediately behind the last floating window; if
the application is the front process, the window is activated.

FW_HideWindow

FW_HideWindow is called in lieu of the usual call to HideWindow.  If the window is the
frontmost window, it is moved behind the window immediately behind it.

At the first two lines, if the window is not visible, the function returns without doing
anything.

The next line gets the pointer to the frontmost window.  If this window is not a floating
window, a variable is set to record that fact.

The next line gets the pointer to the first document window.

The call to ShowHide hides the specified window without affecting the front-to-back
ordering of the windows.

If the newly hidden window is the front floating window, and if the next window in the
list (if any) is a floating window, BringToFront is called to bring that next window to
the front.  Otherwise, if the newly hidden window is the first document window, and if
there is another visible document window, SendBehind is called to move the newly hidden
window behind that visible document window.  Also, if the application is the front
process, that visible document window is activated.

FW_ShowWindow

FW_ShowWindow is called in lieu of the usual call to ShowWindow.  If the specified
(hidden) window is the frontmost document window, the window behind it is deactivated and
the specified window is activated.  If the window is modal, the function makes sure it is
in front.

At the first two lines, if the specified window is currently visible, the function
returns without doing anything.  The next line determines whether the application is the
front process.

The next line records whether the specified window is a floating window.  The line after
that records whether the front window is a modal window.

At the next block, if the specified window is a modal window, BringToFront is called to
bring it to the front (without activating it).

Before proceeding further, FW_validateWindowList is called as a safety measure to ensure
that all windows in the window list are in the right place.

If the application is not the front process, and the specified window is a floating
window, it is marked as visible so that it will be shown on resume.  (The function
setWasVisible assigns true to the wasVisible field of the window's refConExtend
structure.)

The large if block executes only if the application is the front process.  If the
specified window is modal, two local variables are set to true (ensuring that modal
windows will always be activated and highlighted).  If the front window is modal, these
variables are set to false (ensuring that, whatever the specified window type, it will
not be activated and highlighted when a modal window is up).  If neither the specified
nor front window is modal:

*   If the specified window is a floating window, the two local variables are set to
    true.  (New floating windows are always highlighted and activated.)

*   If the specified window is a document window, and it is the only document window,
    the two local variables are set to true so that it will be highlighted and
    activated.  If it is not the only document window: the two local variables are 
    initially set to false (assume the specified window is behind the front one); the
    window list is walked to determine whether the specified window is coming up in
    front of the frontmost document window, in which case the front document window
    is deactivated and the variables are set so that the specified window will be
    highlighted and activated.

If the application is not the front process (the last else block), the two local
variables are set to false so that no highlighting/activation will occur.

HiliteState is called to either unhighlight or highlight the specified window depending 
on the result of the previous machinations.  If the previous machinations determined 
that the window should be activated, pointer to the window's activation function is 
retrieved from the window's refConExtend structure and passed in a call to 
CallActivateHandlerProc, which causes the activation function to execute.

FW_DragWindow

FW_DragWindow is called in lieu of the usual call to DragWindow.  It drags the specified
window around, ensuring that document windows remain behind floating windows.  Like
DragWindow, FW_DragWindow does not bring the window forward if the Command key is held
down during the drag.

WaitMouseUp tests whether the mouse button has remained down since the last mouse-down
event.  If it has, the following occurs.

The first block adjusts the top of the dragging rectangle so that it is below the menu
bar.  The next block saves the current colour graphics port and sets the window manager
port as the current colour graphics port.  The call to SetClip sets the clipping region
to the region below the menu bar.

The next three lines check whether the Command key is down and, if so, set a variable to
record that fact.  

If the Command key is not down and the window is not a floating window, the ClipAbove
call at sets the clipping region to the gray region minus the structure regions of all
windows in front of the front non-floating window. (In this instance, the front document
window is being dragged, so the windows in front are the floating windows.)  If the
window is not a floating window and the Command key is down, the ClipAbove call sets the
clipping region to the gray region minus the structure regions of all windows in front of
the window being dragged. (In this instance, there could be one or more document windows,
as well as floating windows, above the document window being dragged.)

The next two lines create a region to drag, specifically, the structure region of the
specified window.  This is passed as a parameter to the call to DragGrayRgn, which moves
a dotted outline of the region, following the mouse as it moves and retaining control
until the mouse button is released.

When the mouse button is released, SetPort sets the colour graphics port to the saved
earlier.

DragGrayRgn returns an SInt32.  If the mouse was outside the slop rectangle when the
button was released, -32768 is returned in both words, otherwise the high word contains
the vertical distance moved and the low word contains the horizontal distance moved.  If
the value returned is not zero, the value in both words is retrieved.  If the mouse was
not outside the slop rectangle, the new horizontal and vertical global coordinates are
calculated and passed as a parameter in the MoveWindow call, which moves the window to
the new location without bringing it to the front.

If the Command key was not down during the drag (the third last line), the call to
FW_SelectWindow brings the window to the absolute front of the window list (floating
window) or to the front of the document windows section of the list (document window).

FW_doSuspendEvent

FW_doSuspendEvent hides any visible floating windows and deactivates the frontmost
document window.  It should be called when the application receives a suspend event.

The first line gets the pointer to the front window's window structure from the
low-memory global WindowList.

If the first visible window is modal, the floating and front document windows will
already be deactivated, so the function simply returns.

The while loop executes for all floating windows.  The current visibility status of the
window is saved to the wasVisible field of its window's refConExtend structure.  If the
window is visible, it is hidden without affecting the front-to-back ordering of the open
windows.

At the last block, if there are any document windows, the frontmost document window is
deactivated.

FW_doResumeEvent

FW_doResumeEvent shows all floating windows which were hidden by FW_doSuspendEvent.  As
each window is shown, the activation function for that window is called.  This function
should be called when the application receives a resume event.

The first line gets the pointer to the front window's window structure from the
low-memory global WindowList.  

If the first visible window is modal, the floating and front document windows will
already be activated, so the function simply returns.

The while loop executes for all floating windows.  The saved visibility status of the
window is retrieved from the wasVisible field of its window's refConExtend structure.  If
the window was visible when FW_doSuspendEvent was called, it is shown without affecting
the front-to-back ordering of the open windows.

At the last block, if there are any document windows, the frontmost document window is
activated.

FW_activateFloatsAndFirstDocWin

FW_activateFloatsAndFirstDocWin activates those windows which were visible and activated
before deactivateFloatersAndFirstDocWin was called.  It should be called immediately
after an modal alert or dialog box is dismissed.

The first two lines cause the function to assume that, if a modal dialog is up, the
caller did not really mean to call this function.

The next line determines if the application is the front process.

If the application is in the background, the floating windows should be hidden rather
than shown, so FW_doSuspendEvent is called.

If the application is in the foreground, activateWindow is called on all visible windows
in the list up to but not including the second document window in the list.

FW_deactivateFloatsAndFirstDocWin

FW_deactivateFloatsAndFirstDocWin deactivates all visible floating windows and the active
document window.  It should be called immediately before an modal alert or dialog box is
dismissed.

The first line is a safety check to ensure that the window ordering has not been changed.

deactivateWindow is called on all visible windows in the list up to but not including the
second document window in the list.

FW_findFrontNonFloatWindow

FW_findFrontNonFloatWindow returns a pointer to the first visible window in the window
list that is not a floating window.

FW_validateWindowList

FW_validateWindowList is called from FW_ShowWindow and FW_deactivateFloatsAndFirstDocWin. 
It should also be called from the application immediately before document windows are
opened and closed.  It is intended to cater for the remote possibility that document
windows might somehow have been pulled in front of floating windows, in which case it
will pull the floating windows to the front.

If there are no floating windows, the function simply returns.  If the first window in
the window list is a floating window, the function assumes that all is well.  (Note that
the function does not check whether a document window is "between" the floating windows.) 
If the first window is modal, the function returns.

If a return has not occurred prior to the last line, that line calls a function which
brings the floating windows to the front.

FW_GetWRefCon and FW_SetWRefCon

FW_GetWRefCon and FW_SetWRefCon retrieve/assign values from/to the replacementRefCon
field of the window's refConExtend structure.


activateWindow, deactivateWindow, and highlightAndActivateWindow

activateWindow and/or deactivateWindow are called from FW_SelectWindow, FW_HideWindow, FW_ShowWindow, FW_doSuspendEvent, FW_doResumeEvent, FW_deactivateFloatsAndFirstDocWin, and FW_activateFloatsAndFirstDocWin. They simply set a Boolean variable to indicate whether the specified window is to be highlighted and activated or unhighlighted and deactivated, and then pass further processing to highlightAndActivateWindow. highlightAndActivateWindow highlights or unhighlights the specified window, retrieves the pointer to the window's activation function from the window's refConExtend structure, and calls that function.

findLastFloatingWindow

findLastFloatingWindow returns a pointer to last floating window in the window list.

checkWindowOrdering

checkWindowOrdering is called from FW_GetNewCWindow to ensure that the behind formal
parameter is not attempting to open the window at an inappropriate "behind" or "in front
of" location in the window list.  As part of this process, and in the case of document
windows, checkWindowOrdering changes a behind assignment of (WindowPtr) -1 to the pointer
to the last floating window, causing the window to be opened behind that floating window
rather than in front of all windows.  Apart from that particular case, inappropriate
behind specifications will cause an error to be returned. 

If the window to be created is a floating window, an error will be returned if:

*   The behind formal parameter calls for the window to be created behind all other
    windows when non-floating windows exist.

*   The behind formal parameter specifies the window behind which the new window is to
    be created and that window is not a floating window.

If the window to be created is a document window, and if a floating window exists:

*   If the behind formal parameter specifies that the window should be created in front
    of all other windows, the behind parameter is changed so that the window will be
    created behind the last floating window.

*   If the behind formal parameter specifies that the window behind which the window is
    to be opened is a floating window, but it is not the last floating window, an error
    is returned.

getNextVisibleWindow, getWasVisible, and setWasVisible

getNextVisibleWindow returns the pointer to the next visible window in the window list.

getWasVisible returns the value in the wasVisible field of the specified window's
refConExtend structure.

setWasVisible sets the value in the wasVisible field of the specified window's
refConExtend structure.

isWindowModal

isWindowModal determines whether a window is modal.

If the value in the window structure's windowKind field is kDialogWindowKind and the
window's variant code is 2 or 3 (the variant codes for kWindowModalDialogProc and
kWindowMovableModalDialogProc dialog boxes), true is returned.
This function assumes that an application's modeless dialog boxes will not use
kWindowGrowDocumentProc or kWindowVertZoomDocumentProc windows (which also have variant
codes of 2 and 3).  It also assumes that only kWindowModalDialogProc and
kWindowMovableModalDialogProc windows will be used for modal and movable modal dialog
boxes.  If this is not the case, this function will have to be modified.

bringFloatersToFront

bringFloatersToFront is called from FW_validateWindowList in the unlikely event that the
floating windows are not in front of the document windows.  This is a recursive function
(that is, it calls itself) that brings all floating windows to the front of the window
list.

When the while loop finds a floating window, the function remembers it (thisFloaterPtr =
windowPtr) and then calls itself to look further.  When the end of the window list is
reached (thisWindow == NULL), the function "unwinds", calling BringToFront on each found
floating window.

isFrontProcess

isFrontProcess compares the serial numbers of the current process and the front process
and returns true if they are the same, that is, the application is the front process.

getIsWindowVisible, getNextWindow, getWindowKind, getStructureRegion,
and getContentRegion

getIsWindowVisible returns the value in the visible field of the specified window's
window structure.

getNextWindow returns the value in the nextWindow field of the specified window's window
structure.

getWindowKind returns the value in the windowKind field of the specified window's window
structure.

getStructureRegion returns the RgnHandle in the strucRgn field of the specified window's
window structure.

getContentRegion returns the RgnHandle in the contRgn field of the specified window's
window structure.


getActivateHandler and setActivateHandler

getActivateHandler returns the pointer in the activateHandler field of the specified window's refConExtend structure. setActivateHandler assigns a pointer to the activateHandler field of the specified window's refConExtend structure.
 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Whitethorn Games combines two completely...
If you have ever gone fishing then you know that it is a lesson in patience, sitting around waiting for a bite that may never come. Well, that's because you have been doing it wrong, since as Whitehorn Games now demonstrates in new release Skate... | Read more »
Call of Duty Warzone is a Waiting Simula...
It's always fun when a splashy multiplayer game comes to mobile because they are few and far between, so I was excited to see the notification about Call of Duty: Warzone Mobile (finally) launching last week and wanted to try it out. As someone who... | Read more »
Albion Online introduces some massive ne...
Sandbox Interactive has announced an upcoming update to its flagship MMORPG Albion Online, containing massive updates to its existing guild Vs guild systems. Someone clearly rewatched the Helms Deep battle in Lord of the Rings and spent the next... | Read more »
Chucklefish announces launch date of the...
Chucklefish, the indie London-based team we probably all know from developing Terraria or their stint publishing Stardew Valley, has revealed the mobile release date for roguelike deck-builder Wildfrost. Developed by Gaziter and Deadpan Games, the... | Read more »
Netmarble opens pre-registration for act...
It has been close to three years since Netmarble announced they would be adapting the smash series Solo Leveling into a video game, and at last, they have announced the opening of pre-orders for Solo Leveling: Arise. [Read more] | Read more »
PUBG Mobile celebrates sixth anniversary...
For the past six years, PUBG Mobile has been one of the most popular shooters you can play in the palm of your hand, and Krafton is celebrating this milestone and many years of ups by teaming up with hit music man JVKE to create a special song for... | Read more »
ASTRA: Knights of Veda refuse to pump th...
In perhaps the most recent example of being incredibly eager, ASTRA: Knights of Veda has dropped its second collaboration with South Korean boyband Seventeen, named so as it consists of exactly thirteen members and a video collaboration with Lee... | Read more »
Collect all your cats and caterpillars a...
If you are growing tired of trying to build a town with your phone by using it as a tiny, ineffectual shover then fear no longer, as Independent Arts Software has announced the upcoming release of Construction Simulator 4, from the critically... | Read more »
Backbone complete its lineup of 2nd Gene...
With all the ports of big AAA games that have been coming to mobile, it is becoming more convenient than ever to own a good controller, and to help with this Backbone has announced the completion of their 2nd generation product lineup with their... | Read more »
Zenless Zone Zero opens entries for its...
miHoYo, aka HoYoverse, has become such a big name in mobile gaming that it's hard to believe that arguably their flagship title, Genshin Impact, is only three and a half years old. Now, they continue the road to the next title in their world, with... | Read more »

Price Scanner via MacPrices.net

B&H has Apple’s 13-inch M2 MacBook Airs o...
B&H Photo has 13″ MacBook Airs with M2 CPUs and 256GB of storage in stock and on sale for up to $150 off Apple’s new MSRP, starting at only $849. Free 1-2 day delivery is available to most US... Read more
M2 Mac minis on sale for $100-$200 off MSRP,...
B&H Photo has Apple’s M2-powered Mac minis back in stock and on sale today for $100-$200 off MSRP. Free 1-2 day shipping is available for most US addresses: – Mac mini M2/256GB SSD: $499, save $... Read more
Mac Studios with M2 Max and M2 Ultra CPUs on...
B&H Photo has standard-configuration Mac Studios with Apple’s M2 Max & Ultra CPUs in stock today and on Easter sale for $200 off MSRP. Their prices are the lowest available for these models... Read more
Deal Alert! B&H Photo has Apple’s 14-inch...
B&H Photo has new Gray and Black 14″ M3, M3 Pro, and M3 Max MacBook Pros on sale for $200-$300 off MSRP, starting at only $1399. B&H offers free 1-2 day delivery to most US addresses: – 14″ 8... Read more
Department Of Justice Sets Sights On Apple In...
NEWS – The ball has finally dropped on the big Apple. The ball (metaphorically speaking) — an antitrust lawsuit filed in the U.S. on March 21 by the Department of Justice (DOJ) — came down following... Read more
New 13-inch M3 MacBook Air on sale for $999,...
Amazon has Apple’s new 13″ M3 MacBook Air on sale for $100 off MSRP for the first time, now just $999 shipped. Shipping is free: – 13″ MacBook Air (8GB RAM/256GB SSD/Space Gray): $999 $100 off MSRP... Read more
Amazon has Apple’s 9th-generation WiFi iPads...
Amazon has Apple’s 9th generation 10.2″ WiFi iPads on sale for $80-$100 off MSRP, starting only $249. Their prices are the lowest available for new iPads anywhere: – 10″ 64GB WiFi iPad (Space Gray or... Read more
Discounted 14-inch M3 MacBook Pros with 16GB...
Apple retailer Expercom has 14″ MacBook Pros with M3 CPUs and 16GB of standard memory discounted by up to $120 off Apple’s MSRP: – 14″ M3 MacBook Pro (16GB RAM/256GB SSD): $1691.06 $108 off MSRP – 14... Read more
Clearance 15-inch M2 MacBook Airs on sale for...
B&H Photo has Apple’s 15″ MacBook Airs with M2 CPUs (8GB RAM/256GB SSD) in stock today and on clearance sale for $999 in all four colors. Free 1-2 delivery is available to most US addresses.... Read more
Clearance 13-inch M1 MacBook Airs drop to onl...
B&H has Apple’s base 13″ M1 MacBook Air (Space Gray, Silver, & Gold) in stock and on clearance sale today for $300 off MSRP, only $699. Free 1-2 day shipping is available to most addresses in... Read more

Jobs Board

Medical Assistant - Surgical Oncology- *Apple...
Medical Assistant - Surgical Oncology- Apple Hill Location: WellSpan Medical Group, York, PA Schedule: Full Time Sign-On Bonus Eligible Remote/Hybrid Regular Apply Read more
Omnichannel Associate - *Apple* Blossom Mal...
Omnichannel Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Cashier - *Apple* Blossom Mall - JCPenney (...
Cashier - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Blossom Mall Read more
Operations Associate - *Apple* Blossom Mall...
Operations Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Business Analyst | *Apple* Pay - Banco Popu...
Business Analyst | Apple PayApply now " Apply now + Apply Now + Start applying with LinkedIn Start + Please wait Date:Mar 19, 2024 Location: San Juan-Cupey, PR Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.