TweetFollow Us on Twitter

MACINTOSH C
MACINTOSH C: A Hobbyist's Guide To Programming the Mac OS in C
Version 2.3

© 2000 K. J. Bricknell

Go to Contents

(Chapter 4)

WINDOWS

A link to the associated demonstration program listing is at the bottom of this page




Introduction

A window is a user interface element. More specifically, it is an area on the screen in which the user can enter or view information. A Macintosh application uses windows for most communication with the user, from discrete interactions such as presenting and acknowledging alert boxes to open-ended interactions such as creating and editing documents. Users generally enter data in windows and your application typically lets the user save this data to a file.

The Window Manager, which, amongst other things, provides functions for managing windows, itself depends on QuickDraw. QuickDraw supports drawing into colour graphics ports, which are individual and complete drawing environments with independent coordinate systems. Each window represents a colour graphics port.

Your application typically creates document windows, which allow the user to enter and display text, graphics, or other information. A document window is a view into the document. If the document is larger than the window, the window is a view of a portion of the document.

Window Basics

Standard Window Elements

The Window Manager defines and supports a set of standard window elements through which the user can manipulate windows:

  • Title Bar. The bar at the top of a window that displays the window's name, contains the close, zoom, and collapse boxes, and indicates whether a window is active. You usually display a newly created window with the title "untitled". When the user opens a saved document, you assign the document's filename to the window in which it is displayed.

  • Close Box. Offers the user a quick way to close a window. The close box is sometimes called the go-away box.

  • Full, Vertical, and Horizontal Zoom Boxes. Offer the user a quick way to choose between two different window sizes, one established by the user and one by the application.

  • Collapse Box. Lets the user collapse and uncollapse a window.

  • Size Box. Lets the user change the size of a window.

  • Draggable Area. That part of the window's frame less the title bar.

Historical Note

The vertical zoom box, the horizontal zoom box, the collapse box, and the draggable area were introduced with Mac OS 8 and the Appearance Manager.

Scroll bars, which allow the user to view different parts of a document containing more information than can be displayed on the screen at the one time, are not part of a window's structure and must be separately created and managed. By convention, scroll bars are placed on the right and lower edges of those windows which require them.

Active and Inactive Windows

The window in which the user is currently working is called the active window which is identified by its general appearance (see Fig 1). The active window is the target of all keyboard activity and only the active window interacts with the user.

(Appearance of active and inactive windows)

When the user activates one of your application's windows, the Window Manager redraws the window's title bar and frame, the close box, the title text, the zoom box, the collapse box, and the size box. Your application must reinstate the appearance of the rest of the window to its state prior to the deactivation, activating any controls (scroll bars, etc.), drawing the scroll box in the same position, restoring the insertion point, and highlighting the previous selection, etc.

When a window belonging to your application becomes inactive, the Window Manager redraws the title bar and frame as shown at Fig 1, hiding the close, zoom, collapse, and size boxes. Your application must deactivate any controls, remove highlighting from selections, and so on.

Historical Note

Prior to Mac OS 8 and the Appearance Manager, your application was also required to draw (on window activation and on receipt of update events) and erase (on window deactivation) the size box via a call to DrawGrowIcon. The new Appearance-compliant window definition functions (see below) which were introduced with Mac OS 8 and the Appearance Manager relieve your application of that responsibility and merge the size box into the window frame.

In Appearance-compliant windows, DrawGrowIcon, if called, will simply draw scroll bar delimiting lines (single lines extending left and upwards from the top and left side, respectively, of the size box), and may still be used for that purpose if required.

When the user clicks in an inactive document window, your application should make the window active but should not make any selections in response to the click. To make a selection, the user should be required to click again. This behaviour protects the user from unintentionally losing an existing selection when activating the window.

Types of Appearance-Compliant Windows

The Window Manager defines a large number of Appearance-compliant window types, which may be classified as follows:

  • Document types.

  • Dialog and alert types.

  • Utility window types (sometimes referred to as floating window types).
Window types are often referred to by the constant used in 'WIND' resources, and by certain Window Manager functions, to specify the type of window required. That constant determines both the visual appearance of the window and its behaviour.

Document Types

Fig 2 shows the eight available window types for documents and the constants that represent those types.

(Window types for documents)

Dialog and Alert Types

Fig 3 shows the six available window types for modal and movable modal dialogs and alerts and the constants that represent those types. (The document window type represented by the constant kWindowDocumentProc is used for modeless dialog boxes,)

(Window types for dialogs and alerts)

Utility (Floating) Window Types

Figs 4 and 5 show the sixteen available window types for utility (floating) windows and the constants that represent those types.

(Window types for utility windows)

(Window types for utility windows)

Window Definition IDs

The constants shown at Figs 2, 3, 4, and 5 each represent a specific window definition ID. A window definition ID is a 16-bit value which contains the resource ID of the window's window definition function in the upper 12 bits and a variation code in the lower 4 bits:

  • Window Definition Function. The system software and various Window Manager functions call a window's window definition function (WDEF) when they need to perform certain window-related actions, such as drawing or re-sizing a window's frame. The definition function draws the window's frame, draws the close, zoom, collapse, and size boxes (if any), draws the window title (if any), determines which region the cursor is in within the window, calculates the window's content and structure regions (see below), and performs any special initialisation or disposal tasks.

  • Variation Code. A single WDEF can support up to 16 different window types. The WDEF defines a variation code, an integer from 0 to 15, for each window type it supports.
Four WDEFs (resource IDs 64, 65, 66, and 67) are associated with the three classifications of window types.

Historical Note

These are the resource IDs of the new Appearance-compliant window definition functions first issued with Mac OS 8 and the Appearance Manager. The old WDEFs have resource IDs of 0 (document windows), 1 (rDocProc document window), and 124 (utility windows), and remain in the System file. The new definition functions are located in the Appearance extension in Mac OS 8.0 and 8.1, and in the System file in Mac OS 8.5.

The window definition ID is derived by multiplying the resource ID of the WDEF by 16 and adding the variation code to the result, as is shown in the following:

WDEF
Resource ID
Variation
Code
Window Definition ID
(Value)
Window Definition ID
(Constant)
64 0 64 * 16 + 0 = 1024 kWindowDocumentProc
64 1 64 * 16 + 1 = 1025 kWindowGrowDocumentProc
64 2 64 * 16 + 2 = 1026 kWindowVertZoomDocumentProc
64 3 64 * 16 + 3 = 1027 kWindowVertZoomGrowDocumentProc
64 4 64 * 16 + 4 = 1028 kWindowHorizZoomDocumentProc
64 5 64 * 16 + 5 = 1029 kWindowHorizZoomGrowDocumentProc
64 6 64 * 16 + 6 = 1030 kWindowFullZoomDocumentProc
64 7 64 * 16 + 7 = 1031 kWindowFullZoomGrowDocumentProc
65 0 65 * 16 + 0 = 1040 kWindowPlainDialogProc
65 1 65 * 16 + 1 = 1041 kWindowShadowDialogProc
65 2 65 * 16 + 2 = 1042 kWindowModalDialogProc
65 3 65 * 16 + 3 = 1043 kWindowMovableModalDialogProc
65 4 65 * 16 + 4 = 1044 kWindowAlertProc
65 5 65 * 16 + 5 = 1045 kWindowMovableAlertProc
66 1 66 * 16 + 1 = 1057 kWindowFloatProc
66 3 66 * 16 + 3 = 1059 kWindowFloatGrowProc
66 5 66 * 16 + 5 = 1061 kWindowFloatVertZoomProc
66 7 66 * 16 + 7 = 1063 kWindowFloatVertZoomGrowProc
66 9 66 * 16 + 9 = 1065 kWindowFloatHorizZoomProc
66 11 66 * 16 + 11 = 1067 kWindowFloatHorizZoomGrowProc
66 13 66 * 16 + 13 = 1069 kWindowFloatFullZoomProc
66 15 66 * 16 + 15 = 1071 kWindowFloatFullZoomGrowProc
67 1 67 * 16 + 1 = 1073 kWindowFloatSideProc
67 3 67 * 16 + 3 = 1075 kWindowFloatSideGrowProc
67 5 67 * 16 + 5 = 1077 kWindowFloatSideVertZoomProc
67 7 67 * 16 + 7 = 1079 kWindowFloatSideVertZoomGrowProc
67 9 67 * 16 + 9 = 1081 kWindowFloatSideHorizZoomProc
67 11 67 * 16 + 11 = 1083 kWindowFloatSideHorizZoomGrowProc
67 13 67 * 16 + 13 = 1085 kWindowFloatSideFullZoomProc
67 15 67 * 16 + 15 = 1087 kWindowFloatSideFullZoomGrowProc

Historical Note

The old pre-Mac OS 8, pre-Appearance Manager window types, and their Appearance-compliant (Fig 3) equivalents, are as follows.
Pre-Appearance Appearance-Compliant Description
noGrowDocProc kWindowDocumentProc Movable window.
documentProc kWindowGrowDocumentProc Movable window, size box.
zoomNoGrow kWindowFullZoomDocumentProc Movable window, full zoom box.
zoomDocProc kWindowFullZoomGrowDocumentProc Movable window, full zoom box, size box.
rDocProc (None) Round-cornered window.
dBoxProc kWindowModalDialogProc Modal dialog box.
(None) kWindowAlertProc Modal alert box.
movableDBoxProc kWindowMovableModalDialogProc Movable modal dialog box.
(None) kWindowMovableAlertProc Movable modal alert box.
plainDBox kWindowPlainDialogProc Modeless dialog box.
altDBoxProc kWindowShadowDialogProc Modeless dialog box, shadow.
floatProc kWindowFloatProc Utility.
floatGrowProc kWindowFloatGrowProc Utility, size box.
floatZoomProc kWindowFloatFullZoomProc Utility, full zoom box.
floatZoomGrowProc kWindowFloatFullZoomGrowProc Utility, full zoom box, size box.
floatSideProc kWindowFloatSideProc Utility, side title.
floatSideGrowProc kWindowFloatSideGrowProc Utility, side title, size box.
floatSideZoomProc kWindowFloatSideFullZoomProc Utility, side title, full zoom box.
floatSideZoomGrowProc kWindowFloatSideFullZoomGrowProc Utility , side title, size box, full zoom box.

Window Type Usage

Window Types For Documents. A kWindowFullZoomGrowDocumentProc window is normally used for document windows because it supports all window manipulation elements, that is, title bar, close box, zoom box, and size box. Note that, because you can optionally suppress the close box when you create the window, the Window Manager does not necessarily draw that particular element. Also note that, when the related document contains more data that will fit in the window, you must add scroll bars.

Window Types For Modal Alert Boxes and Modal Dialog Boxes. Modal alert boxes and modal dialog boxes are merely special-purpose windows that require no window manipulation elements. Modal alert boxes generally use the window type kWindowAlertProc and modal dialog boxes generally use window type kWindowModalDialogProc; however, kWindowPlainDialogProc and kWindowShadowDialogProc may also be used.

Window Types For Movable Modal Alert Boxes and Movable Modal Dialog Boxes. Movable modal alert boxes and movable modal dialog boxes are used when you want the user to be able to move the alert or dialog window or to bring another application to the foreground before the dialog is dismissed. Movable modal alert boxes use the window type kWindowMovableAlertProc and movable modal dialog boxes use the window type kWindowMovableModalDialogProc.

Historical Note

Movable Modal Alert boxes were introduced with Mac OS 8 and the Appearance Manager.

Window Types For Modeless Dialog Boxes. Modeless dialog boxes allow the user to perform other tasks within the application without first dismissing the dialog box. User interface guidelines require that the kWindowDocumentProc window type, which can be moved or closed but not resized or zoomed, be used for modeless dialog boxes.

The creation and handling of alert and dialog boxes is addressed in detail at Chapter 8- Dialogs and Alerts.

Window Regions

The Window Manager recognises the special-purpose regions shown at Fig 6.

A region is an arbitrary area, or set of areas, on the QuickDraw coordinate plane. The outline of a region is one or more closed loops. Regions are explained in more detail at Chapter 12 - Drawing With QuickDraw.

(Window regions)

Handles to these regions, which are represented by constants of type RegionWindowCode, may be obtained via a call to GetWindowRegion. The definitions of these regions, and the constants which represent them, are as follows:

Region Constant Definition
Title bar region kWindowTitleBarRgn The entire area occupied by a window's title bar, including the title text region.
Title text region kWindowTitleTextRgn That portion of a window's title bar that is occupied by the name of the window.
Close box region kWindowCloseBoxRgn The area occupied by a window's close box.
Zoom box region kWindowZoomBoxRgn The area occupied by a window's zoom box.
Drag region kWindowDragRgn The draggable area of the window frame, including the title bar and window outline, but excluding the close box, zoom box, and collapse box.
Size box region kWindowGrowRgn The area occupied by a window's size box.
Collapse box region kWindowCollapseBoxRgn The area occupied by a window's collapse box.
Structure region kWindowStructureRgn The entire area occupied by a window, including the frame and content region. (The window may be partially off-screen but its structure region does not change.)
Content region kWindowContentRgn That part of a window in which the contents of a document, the size box, and the window's controls (including scroll bars) are displayed.

Other Regions

Two other regions of relevance to the Window Manager are:

  • The Update Region. The update region is a dynamic region which accumulates all areas of a window's content region which need updating (that is, re-drawing).

  • The Gray Region. The entire area of the desktop, that is, the screen area that is not occupied by the menu bar, is known as the gray region. The Window Manager maintains a pointer to the gray region in a low-memory global variable named GrayRgn. You can retrieve a handle to the gray region with the function LMGetGrayRgn.

Controls and Control Lists

Windows may contain controls. The most common control in a window is the scroll bar (see Fig 7), which should be included in the window when there is more data than can be shown at one time in the space available. The Control Manager is used to create, display and manipulate scroll bars.

All controls included in a window "belong" to that individual window and are displayed within the colour graphics port which represents that window. For each window your application creates, the Window Manager creates a control list, a series of entries pointing to the descriptions of controls associated with a window.

(Scroll bars)

The Window List

Multiple windows from different applications may appear simultaneously on the desktop. The Window Manager tracks all windows using its own private data structure called the window list. Entries in the window list appear in their order on the desktop, beginning with the frontmost (active) window. When the user changes the ordering of the windows on the desktop, the Window Manager generates events telling your application to activate, deactivate and update its windows as necessary.

The Colour Graphics Port and the Colour Window Structure

The Colour Graphics Port

Each window represents a QuickDraw colour graphics port, which is a drawing environment with its own coordinate system. The Window Manager creates a colour graphics port when it creates the window.

The location of a window on the screen is defined in global coordinates, that is, coordinates which reflect the entire potential drawing space. QuickDraw recognises a coordinate plane whose origin is the upper left corner of the main screen, whose positive x-axis extends rightward and whose positive y-axis extends downward (see Fig 8). In QuickDraw functions, the horizontal offset is ordinarily labelled h, and the vertical offset v. The coordinate plane is bounded by the limits of QuickDraw coordinates, which range from -32768 to 32,767.

(Local and global coordinates)

When QuickDraw creates a new colour graphics port (usually, when you create a new window), it defines a bounding rectangle for the port in global coordinates. Ordinarily, the bounding rectangle represents the entire area of the screen on which the window appears. The bounding rectangle is stored in the colour graphics port data structure, in the bounds field of a structure called a pixel map in Color QuickDraw.

The colour graphics port data structure also includes a field called portRect, which defines the rectangle to be used for drawing. In a colour graphics port representing a window, the portRect rectangle represents the window's content region. Within the port rectangle, the drawing area is described in local coordinates. Fig 8 illustrates the local and global coordinate systems for a window which is 100 pixels high by 200 pixels wide, and which is placed with its content region 70 pixels down and 60 pixels to the right of the upper left corner of the screen.

The colour graphics port is addressed in detail at Chapter 11 - QuickDraw Preliminaries.

When the Window Manager creates a window, it places the origin of the local coordinate system at the upper-left corner of the window's port rectangle. Note, however, that the Event Manager describes mouse events in global coordinates, and that you must do most of your window manipulation in global coordinates.

Colour Window Structure

The Window Manager stores information about a window in a colour window structure. A colour window structure is defined by the data type CWindowRecord:

     struct CWindowRecord
     {
       CGrafPort    port;          // Window's colour graphics port.
       short        windowKind;    // Class of window.
       Boolean      visible;       // true if window is visible.
       Boolean      hilited;       // true if window is highlighted.
       Boolean      goAwayFlag;    // true if window has close box.
       Boolean      spareFlag;     // true if window has zoom box.
       RgnHandle    strucRgn;      // Handle to structure region.
       RgnHandle    contRgn;       // Handle to content region.
       RgnHandle    updateRgn;     // Handle to update region.
       Handle       windowDefProc; // Handle to window definition function.
       Handle       dataHandle;    // Handle to window state data structure.
       StringHandle titleHandle;   // Handle to window's title.
       short        titleWidth;    // Title width in pixels.
       ControlRef   controlList;   // Handle to window's control list.
       CWindowPeek  nextWindow;    // Pointer to next window structure in window list.
       PicHandle    windowPic;     // Handle to an optional picture.
       long         refCon;        // Reference constant.
     };
     typedef struct CWindowRecord CWindowRecord;
     typedef CWindowRecord *CWindowPeek;

Historical Note

There is another window structure called the window structure, which is defined by the data type WindowRecord. The window structure traces its origins back to the era of black-and-white Macintoshes, and had to be used on any Macintosh when Color QuickDraw was not present. Since Color QuickDraw is always available with Mac OS 8 and the Appearance Manager, the window structure is now redundant. The only difference between a window structure and a colour window structure is that the port field is a graphics port (GrafPort) rather than a colour graphics port (CGrafPort).

It is important to note that the colour graphics port is the first field of the colour window structure and that the data type CWindowPtr is defined as a pointer to the colour graphics port, not to the colour window structure. Fields in the colour window structure are accessed using CWindowPeek, which is a pointer to a colour window structure. (CWindowPeek is rarely used, however, since you usually do not need to access or directly modify fields in a colour window structure. The Window Manager automatically updates the colour window structure when you make changes to a window, and supplies functions for changing and reading some fields of the colour window structure.)

The close box region, drag region, zoom box region, collapse box region, and size box region are not included in the colour window structure. The WDEF determines the location of those particular regions.

Compatibility

For compatibility purposes, the WindowPtr data type points to either a colour graphics port or a graphics port and the WindowPeek data type points to either a colour window structure or a window structure.

Events in Windows

As stated at Chapter 2 - Low-Level and Operating System Events, the Window Manager itself generates two types of events central to window management, namely, activate events and update events.

One of the more basic functions of the Window Manager is to report where the cursor is when the application receives a mouse-down event. As was also stated at Chapter 2, the Window Manager function FindWindow tells your application whether the cursor is in a window and, if it is in a window, in exactly which window and which part of that window. FindWindow is thus used as a first filter for mouse-down events, separating events which merely affect the window display from events which manipulate data.

Creating Your Application's Windows

You typically create document and utility windows from resources of type 'WIND', although you can create them programmatically using the function NewCWindow.

'WIND' Resources

When creating resources with Resorcerer, it is advisable that you refer to a diagram and description of the structure of the resource and relate that to the various items in the Resorcerer editing windows. Accordingly, the following describes the structure of the resource associated with the creation of document and utility windows.

Structure of a Compiled 'WIND' Resource

Fig 9 shows the structure of a compiled 'WIND' resource and how it "feeds" the colour window structure.

('WIND' resource)

The following describes the main fields of the 'WIND' resource:

Field Description
INITIAL RECTANGLE The upper-left and lower-right corners, in global coordinates, of a rectangle that defines the initial size and placement of the window's content region. Your application can change this rectangle before displaying the window, either programmatically or through an optional positioning code (see below).
WINDOW DEFINITION ID The window's definition ID, which incorporates the resource ID of the WDEF that will handle the window and an optional variation code.
VISIBILITY STATUS A specification that determines whether the window is visible or invisible. This characteristic controls only whether the Window Manager displays the window, not necessarily whether the window can be seen on the screen. (A visible window entirely covered by other windows, for example, is "visible" even though the user cannot see it.) You typically create a new window in an invisible state, build the content area of the window, and then display the completed window.
PRESENCE OF CLOSE BOX A specification that determines whether or not the window has a close box. The Window Manager draws the close box when it draws the window frame. The window type specified in the second field determines whether a window can support a close box; this field determines whether the close box is present.
REFERENCE CONSTANT A reference constant which your application can use for whatever data it needs to store. When it builds a new colour window structure, the Window Manager stores, in the refCon field, whatever value you specify in this field. You can also set the refCon field of the colour window structure programmatically via a call to SetWRefCon.
WINDOW TITLE A Pascal string that specifies the window's title.
POSITIONING SPECIFICATION An optional positioning specification that overrides the window position established by the rectangle in the first field.

The positioning constants (see below) are convenient when the user is creating new documents or when you are handling your own dialog boxes and alert boxes. When you are creating a new window to display a previously saved document, however, you should display the new window in the same rectangle as that in which it was previously displayed.

Positioning Specification

The constants for the positioning specification field are as follows:

Constant Value Meaning
kWindowDefaultPosition 0x0000 Use initial location.
kWindowCenterMainScreen 0x280A Centre on main screen.
kWindowAlertPositionMainScreen 0x300A Place in alert position on main screen.
kWindowStaggerMainScreen 0x380A Stagger on main screen.
kWindowCenterParentWindow 0xA80A Center on parent window.
kWindowAlertPositionParentWindow 0xB00A Place in alert position on parent window.
kWindowStaggerParentWindow 0xB80A Stagger relative to parent window.
kWindowCenterParentWindowScreen 0x680A Center on parent window screen.
kWindowAlertPositionParentWindowScreen 0x700A Alert position on parent window screen.
kWindowStaggerParentWindowScreen 0x780A Stagger on parent window screen.

Creating a 'WIND' Resource Using Resorcerer

Fig 10 shows a 'WIND' resource being created with Resorcerer.

(Creating a 'WIND' resource)

Creating the Window From the 'WIND' Resource

GetNewCWindow is used to create a window from a 'WIND' resource.

You can allow GetNewCWindow to itself allocate memory for your colour window structure; however, memory fragmentation effects will be minimised by allocating the memory yourself from a non-relocatable block allocated for such purposes during your application's initialisation function, and then passing the pointer to GetNewCWindow.

Historical Note - The 'wctb' Resource

Prior to the introduction of the Appearance-compliant WDEFs, the colours of the various elements of a window were controlled by the window colour table, which contained a series of part codes for different window elements, together with the RGB (red-green-blue) values associated with each part. Applications typically used the default colour table; however, it was possible to explicitly control the colours used in a window by creating a window colour table ('wctb') resource with the same resource ID as the window's 'WIND' resource. The Appearance-compliant WDEFs ignore all information in the window colour table structure except the field that controls the background colour for the window's content region.

Adding Scroll Bars

If a window requires scroll bars, you typically create them from 'CNTL' resources at the time that you create the document window, and then display them when you make the window visible. (See Chapter 7 - Introduction to Controls).

Window Visibility

If the 'WIND' resource specifies that the new window is visible, GetNewCWindow displays the window immediately. If you are creating a document window, however, it is best to create the window in an invisible state and then make it visible when you are ready to display it. The right time to display a window depends on whether the window is associated with a new or saved document:

  • If you are creating a window because the user is creating a new document, you can display the window immediately by calling ShowWindow. (This change in visibility adds to the update region and triggers an update event. Your application should respond to the update event by calling its own function for drawing the content region.)

  • If you are creating a new window to display a saved document, you should retrieve the user's data before displaying the window.

Positioning a New Document Window on the DeskTop

New document windows should be placed just below and to the right of the last document window in which the user was working. On Macintoshes with a single screen, positioning windows is fairly straightforward. The first new document should be positioned on the upper-left corner of the desktop and each additional new document window is opened with its upper-left corner below and to the right of the upper-left corner of its predecessor. If the user closes one or more documents, subsequently opened windows should be located in the vacated positions.

The positioning constants previously described allow you to position new windows automatically. When used, those positioning constants concerned with staggering new window placement will ensure that the Window Manager will use any vacated position for the next new window.

Positioning a Saved Document Window on the DeskTop

When you open a saved document, you should replicate the size and location of the window as it was when the document was last saved. When the user saves a document, you must therefore save the user state rectangle and the current zoom state of the window (that is, whether the window is in the user state or the standard state).

Some explanation of user state and standard state is necessary. The user state is the last size and location the user, through sizing and dragging actions, established for a window. The standard state is the size and location that your application determines is the most convenient size for the window. For windows with full zoom boxes, this typically the gray area of the screen minus three pixels all round.

The user and standard states are stored in the state data structure, whose handle is assigned to the dataHandle field of the colour window structure:

     struct WStateData 
     {
       Rect userState;   // Size and location established by user.
       Rect stdState;    // Size and location established by application.
     };
     typedef struct WStateData WStateData;
     typedef WStateData *WStateDataPtr, **WStateDataHandle;

Returning to the matter of saving the user state and the current state of the window, for windows with full zoom boxes you typically store this data as a custom resource in the resource fork of the document file. The following is an application-defined data type which will support this process by storing the user state rectangle and current zoom state while the document remains open:

     typedef struct 
     {
       Rect    userStateRect; // User state rectangle.
       Boolean zoomState;     // Window state: true = standard, false = user.
     } windowState;
     typedef windowState *windowStatePtr;
     typedef windowStatePtr *windowStateHdl;

This structure can be transformed into an application-defined resource which may then be stored in the resource fork of the document when the user saves the document.

The demonstration program MoreResources.c at Chapter 17 - More on Resources shows how to save the window state to the resource fork of a document file.

Drawing a Window's Contents

Your application is responsible for drawing a window's contents. It typically uses the Control Manager to draw the window's controls and then draws the user data itself.

As stated at Chapter 2 - Low-Level and Operating System Events, if the window contains a static display such as a picture, you can let the Window Manager take care of updating the content region by assigning a handle to the picture in the windowPic field of the colour window structure.

Managing Multiple Windows

Your application is likely to have multiple windows open on the desktop at once (perhaps one or more document windows and one or more dialog boxes) and it will need to keep track of them all.

You can use different strategies for keeping track of windows, including different kinds of windows. As previously stated, the refCon field in the colour window structure is set aside specifically for use by applications and can be used to store different kinds of data, such as a number representing a window type or a handle to a structure containing data relating to window management.

As an example, the refCon field could hold a number representing the type of dialog box or, in the case of document windows, a handle to an application-defined document structure. The document structure might typically hold a handle to the text being edited, handles to the scroll bars, a file reference number and a file system specification for the document's file, plus a flag indicating whether data has changed since the last save, as shown in this example application-defined document structure:

     typedef struct 
     {
       TEHandle       editRec;
       ControlHandle  vScrollBar;
       Controlhandle  hScrollbar;
       short          fileRefNum;
       FSSpec         fileFSSpec;
       boolean        windowDirty;
     } docStructure;
     typedef docStructure *docStructurePtr;
     typedef docStructurePtr *docStructureHdl;

For dialog boxes, a value of, say, 20 in the refCon field might specify a modeless dialog box which accepts input for the Find command, while a value of, say, 21 might specify a modeless dialog box that accepts input for a spelling checker. These reference constants could then control branching to application-defined window management functions specific to the particular dialog concerned.

Handling Events

Handling Mouse Events

When your application is active, it receives notice of all mouse-down events in the menu bar or in one of its windows. When it receives a mouse-down event, your application should call FindWindow to ascertain which window the mouse-down occurred in and to map the cursor location to a window region. The application should then take the appropriate action based on which window, and in which region of that window, the mouse-down occurred.

Mouse-Downs in Inactive Windows

When you receive a mouse-down event in an inactive document window or modeless dialog box, and if the active window is a document window or a modeless dialog box, you should call SelectWindow, passing it the window pointer. SelectWindow re-layers the windows as necessary, removes highlighting from the previously active window, brings the newly-activated window to the front, highlights it and generates the activate and update events necessary to tell all affected applications which windows must be redrawn.

Note that, if the active window is a modal or movable modal alert or dialog box, no action is required by your application. Modal and movable modal alert and dialog boxes are handled by the ModalDialog function, which does not pass the event to your application.

Handling Keyboard Events

Whenever your application is the foreground process, it receives key-down events for all keyboard activity (except, of course, for the standard and user-defined Command-Shift-number key sequences).

When you receive a key-down event, you should first check whether the user is holding down a modifier key and another key at the same time. Your application should respond to key-down events by inserting data into the document, changing the display or taking other appropriate actions. Typically, your application provides feedback for standard keystrokes by drawing the character on the screen.

Handling Update Events

The Window Manager maintains an update region, which represents the parts of your content region that have been affected by changes to the desktop. The Event Manager continually scans the updateRgn fields of the window structures of all the windows on the desktop. If it finds an update region that is not empty, it generates an update event for that window.

When your application receives an update event, it should redraw the content area. When your application redraws the content area, the Window Manager ensures that it does not accidentally draw into other windows by clipping all screen drawing to the visible region of the window's colour graphics port. The visible region is that part of a colour graphics port that is actually visible on screen, that is, the part that is not covered by other windows. The Window Manager stores a handle to the visible region in the visRgn field of the colour graphics port structure.

Before redrawing the content area, your application should call BeginUpdate and, when it has completed the drawing, it should call EndUpdate. As shown at Fig 11, BeginUpdate temporarily adjusts the visible region to equate to the intersection of the visible region and the update region. Because QuickDraw limits its drawing to this temporarily modified visible region, only those parts of the window which actually need updating are drawn. BeginUpdate also clears the update region, thus ensuring that the Event Manager does not continue sending an endless stream of update events.

When the drawing is completed, and as shown at Fig 11, EndUpdate restores the visible region of the colour graphics port to the full visible region.

(Effects of BeginUpdate and EndUpdate)

The reason for these update region/visible region machinations is that the handle to the update region is stored in the window structure's updateRgn field while the handle to the visible region is stored in the colour graphics port structure's visRgn field. QuickDraw knows the colour graphics port structure intimately, but knows nothing about the window structure or its updateRgn field. QuickDraw needs something it can work with, hence the above process whereby the visible region is temporarily made the equivalent of the update region while QuickDraw does its drawing.

Manipulating the Update Region

Your application can force or suppress update events by manipulating the update region. You can call InValRect to add an area to the update region, thus causing an update event to be generated and, as a consequence, that area to be redrawn. You can also remove an area from the update region by calling ValidRect so as to decrease the time spent redrawing. For example, an unaffected text area could be removed from the update region of a window that is being resized.

Type-Dependent Update Functions

An application-defined update function should typically first determine whether the type of window being updated is a document window or some other application-defined window. If the window is a document window, an application-defined document window updating function should be called. If the window is a modeless dialog box, an application-defined updating function for that modeless dialog should be called.

Handling Activate Events

Activate events are generated by the Window Manager to inform your application that a window is becoming active or is about to be made inactive. Each activate event specifies the window to be changed and the direction of that change (that is, whether the window is to be activated or deactivated).

Your application typically triggers activate events itself by calling SelectWindow following a mouse-down event. SelectWindow brings the selected window to the front, removes highlighting from the previously selected window and adds highlighting to the selected window. It then generates two activate events, the first to tell your application to deactivate the previously active window and the second to activate the newly activated window.

When your application receives the event for the window about to be made inactive, it should hide the controls and remove any highlighting of selections. When your application receives the event for the newly activated window, it should draw the controls and restore the content area as necessary, adding the insertion point in its former location or highlighting previously highlighted sections as appropriate.

The application-defined function for handling activate events should typically first determine whether the window being activated/deactivated is a document window or a modeless dialog box. It should then perform the appropriate activation/deactivation actions. The function does not need to check for modal alert or modal dialog boxes because the Dialog Manager's ModalDialog function automatically handles activate events for those windows.

Manipulating Windows

Moving a Window

When a mouse-down event occurs in the title bar, your application should call DragWindow, which tracks the user's actions until the mouse button is released. DragWindow draws a dotted outline of the window on the screen and moves the outline as the user moves the mouse. When the user releases the mouse, the application should call MoveWindow, which redraws the window in its new location.

Zooming a Window

Windows With Full Zoom Boxes

The zoom box allows the user to alternate quickly between two window sizes and positions. These two sizes and positions are the user state and the standard state. To amplify the previous description of user state and standard state:

  • The user state is the window size and location established by the user. If your application does not supply an initial user state, the user state is simply the size and location of the window when it was created, until the user resizes it.

  • The standard state is the window size and location that your application considers most convenient. Typically, this might be the screen gray area minus three pixels all round. In a word-processing program, however, a standard state window might show a full page, if possible, or a page of full width and as much length as will fit on the screen. If the user changes the page size using the print Style dialog box, the application might adjust the standard state to reflect the new page size.

  • If your application does not define a standard state, the Window Manager will automatically set it to the entire gray region of the main screen minus a three-pixel border on all sides. The user cannot change a window's standard state.

  • The user and standard states are stored in a structure whose handle appears in the dataHandle field of the colour window structure. The Window Manager sets the initial values of the userState and stdState fields when it fills in the window structure and it updates the userState whenever the user resizes the window.
When the user presses the mouse button with the cursor in the zoom box, FindWindow "knows" whether the window is in the user state (zoomed-in) or the standard state (zoomed-out). When the window is in the standard state, FindWindow returns inZoomIn, meaning that the window is to be zoomed "in" to the user state. When the window is in the user state, inZoomOut is returned, meaning that the window is to be zoomed "out" to the standard state.

When FindWindow returns either inZoomIn or inZoomOut, your application should call TrackBox to handle highlighting of the zoom box and to determine whether the cursor is inside or outside the zoom box when the button is released. If TrackBox returns true, your application should call ZoomWindow to resize the window, following which it should redraw the content region.

Windows With Vertical or Horizontal Zoom Boxes

For windows with vertical or horizontal zoom boxes, you will typically want to change the size of the window when the zoom box is clicked, but not the location. This means that your application will need to define both the standard state and the user state, setting both states according to the current position of the window. You will thus need to determine the current location of the window, and set the standard and user states, immediately before the call to ZoomWindow.

Your application should ensure that, when a vertical zoom box is clicked, only the vertical size of the associated window changes. Similarly, when a horizontal zoom box is clicked, your application should ensure that only the horizontal size of the associated window changes.

Re-Sizing a Window

When the user presses the mouse button in the size box, your application should call GrowWindow. This function displays a grow image, a dotted outline of the window frame and scroll bar area which expands and contracts as the user drags the size box.

To avoid unmanageably large or small windows, you supply upper and lower size limits when you call GrowWindow. The sizeRect parameter of GrowWindow specifies the upper and lower size limits in a single structure of type Rect. Note that the values in the structure represent window dimensions, not screen coordinates:

  • sizeRect.top represents the minimum vertical measurement.

  • sizeRect.left represents the minimum horizontal measurement.

  • sizeRect.bottom represents the maximum vertical measurement.

  • sizeRect.right represents the maximum horizontal measurement.
Most applications specify a minimum size big enough to include all parts of the structure area and the scroll bars. Because the user cannot move the cursor beyond the edges of the screen, you can safely set the maximum size to the largest possible rectangle.

When the user releases the mouse button, GrowWindow returns a long integer which describes the window's new height (in the high-order word) and width (in the low-order word). A value of zero indicates that the window size did not change. When GrowWindow returns a value other than zero, you call SizeWindow to resize the window.

When the mouse-button is released and GrowWindow returns a non-zero value, the application-defined function for re-sizing windows should call SizeWindow to draw the window in its new size. The scroll bars and window contents should then be adjusted to the new size.

Closing a Window

The user closes a window by either clicking in the close box or by choosing Close from the File menu.

When the user clicks in the close box, TrackGoAway should be called to track the mouse until the user releases the mouse button. If TrackGoAway returns true, meaning that the user did not release the mouse button outside the close box, your application should invoke its function for closing down the window.

The specific steps you take when closing a window depend on what kind of information the window contains and whether the contents need to be saved. The application-defined function should cater for different types of windows, that is, modeless dialog boxes (which may be merely hidden with HideWindow rather than closed completely) and standard document windows. In the latter case, the function should check whether any changes have been made to the document since it was opened and, if so, provide the user with an opportunity to save the document to a file before closing the window. (This whole process is explained in detail at Chapter 16 - Files.)

DisposeWindow and CloseWindow

DisposeWindow removes a window from the screen, removes it from the window list, and discards all of its data storage, including the window structure. DisposeWindow should be used if you allowed the system to allocate storage for the window structure, that is, if you passed NULL as the wStorage parameter in the NewCWindow or GetNewCWindow call.

CloseWindow removes a window from the screen, removes it from the window list, and discards its data storage except for the window structure. CloseWindow should be used when you have allocated storage for the window structure manually, that is, if you created a nonrelocatable block for the window structure and passed the pointer as the wStorage parameter in the NewCWindow or GetNewCWindow call. In this case, the nonrelocatable block containing the window structure must be disposed of separately.

Hiding and Showing a Window

Whenever the user clicks the close box, you ordinarily remove the window from the screen. Sometimes, however, you might find it more convenient to merely hide the window instead of removing its data structures. If your application includes, for example, a Find modeless dialog box which searches for a string, you might want to keep its structures in memory as long as the user is working. In this case, a click on the close box should simply hide the window through a call to HideWindow. Then, when the user next chooses the Find command, the dialog box is already available, in the same location and with the same text as when it was last used.

ShowWindow will make the window visible and SelectWindow will make it the active window.

Providing Help Balloons

Help Balloons -'hrct' and 'hwin' Resources

The system software provides help balloons for the title bar, draggable area, close box, zoom box, and collapse box for windows created with the standard WDEFs. Where applicable, you should provide help balloons for the content area of your windows.

How you choose to provide help balloons for the content area depends mainly on whether your windows are static or dynamic. A static window does not change its title or reposition any of the objects within its content area. A dynamic window can reposition any of it objects within its content area, or its title may change. For example, any window that scrolls past areas of interest to the user is a dynamic window because the object with associated help balloons can change location as the user scrolls. The following addresses the case of static windows only.

Help balloons for static document and utility windows are defined in 'hrct' and 'hwin' resources.

Creating 'hrct' and 'hwin' Resources Using Resorcerer

The 'hrct' (rectangle help) resource is used to define hot rectangles for displaying help balloons in a static window and to specify the help messages for those balloons. All 'hrct' resources must have resource IDs equal to or greater than 128. Fig 12 shows an 'hrct' resource being created using Resorcerer.

(Creating an 'hrct' resource)

The 'hwin' (window help) resource is used to associate the help balloons defined in an 'hrct' resource with a particular window. All 'hrct' resources must have resource IDs equal to or greater than 128. Fig 13 shows an 'hwin' resource being created using Resorcerer.

(Creating an 'hwin' resource)



Main Window Manager Constants, Data Types and Functions

In the following:

  • The constants, data types, and functions introduced with Mac OS 8 and the Appearance Manager are shown in blue.

  • Those older constants, data types and functions affected by the introduction of Mac OS 8 and the Appearance Manager, but which may still be used in certain circumstances, are shown in red.

Constants

Theme-Compliant Window Types

kWindowDocumentProc                = 1024  // Document windows
kWindowGrowDocumentProc            = 1025
kWindowVertZoomDocumentProc        = 1026
kWindowVertZoomGrowDocumentProc    = 1027
kWindowHorizZoomDocumentProc       = 1028
kWindowHorizZoomGrowDocumentProc   = 1029
kWindowFullZoomDocumentProc        = 1030
kWindowFullZoomGrowDocumentProc    = 1031
kWindowPlainDialogProc             = 1040  // Dialogs and Alerts
kWindowShadowDialogProc            = 1041
kWindowModalDialogProc             = 1042
kWindowMovableModalDialogProc      = 1043
kWindowAlertProc                   = 1044
kWindowMovableAlertProc            = 1045
kWindowFloatProc                   = 1057  // Utility (floating) windows
kWindowFloatGrowProc               = 1059
kWindowFloatVertZoomProc           = 1061
kWindowFloatVertZoomGrowProc       = 1063
kWindowFloatHorizZoomProc          = 1065
kWindowFloatHorizZoomGrowProc      = 1067
kWindowFloatFullZoomProc           = 1069
kWindowFloatFullZoomGrowProc       = 1071
kWindowFloatSideProc               = 1073
kWindowFloatSideGrowProc           = 1075
kWindowFloatSideVertZoomProc       = 1077
kWindowFloatSideVertZoomGrowProc   = 1079
kWindowFloatSideHorizZoomProc      = 1081
kWindowFloatSideHorizZoomGrowProc  = 1083
kWindowFloatSideFullZoomProc       = 1085
kWindowFloatSideFullZoomGrowProc   = 1087

Window Kind

kDialogWindowKind       = 2
kApplicationWindowKind  = 8

Part Codes Returned by FindWindow

inDesk        = 0
inNoWindow    = 0
inMenuBar     = 1
inSysWindow   = 2
inContent     = 3
inDrag        = 4
inGrow        = 5
inGoAway      = 6
inZoomIn      = 7
inZoomOut     = 8
inCollapseBox = 11

Window Regions

kWindowTitleBarRgn     = 0
kWindowTitleTextRgn    = 1
kWindowCloseBoxRgn     = 2
kWindowZoomBoxRgn      = 3
kWindowDragRgn         = 5
kWindowGrowRgn         = 6
kWindowCollapseBoxRgn  = 7
kWindowStructureRgn    = 32
kWindowContentRgn      = 33

Data Types

Colour Window Structure

struct CWindowRecord
{
  CGrafPort     port;           // Window's colour graphics port.
  short         windowKind;     // Class of window.
  Boolean       visible;        // true if window is visible.
  Boolean       hilited;        // true if window is highlighted.
  Boolean       goAwayFlag;     // true if window has close box.
  Boolean       spareFlag;      // true if window has zoom box.
  RgnHandle     strucRgn;       // Handle to structure region.
  RgnHandle     contRgn;        // Handle to content region.
  RgnHandle     updateRgn;      // Handle to update region.
  Handle        windowDefProc;  // Handle to window definition function.
  Handle        dataHandle;     // Handle to window state data structure.
  StringHandle  titleHandle;    // Handle to window's title.
  short         titleWidth;     // Title width in pixels.
  ControlRef    controlList;    // Handle to window's control list.
  CWindowPeek   nextWindow;     // Pointer to next window structure in window list.
  PicHandle     windowPic;      // Handle to an optional picture.
  long          refCon;         // Reference constant.
};
typedef struct CWindowRecord CWindowRecord;
typedef CWindowRecord *CWindowPeek;

State Data Structure

struct WStateData
{
  Rect  userState;  // User state.
  Rect  stdState;   // Standard state.
};
typedef struct WStateData WStateData;
typedef WStateData *WStateDataPtr, **WStateDataHandle;

Functions

Initializing the Window Manager

void  InitWindows(void);

Creating Windows

WindowPtr  GetNewCWindow(short windowID,void *wStorage,WindowPtr behind);
WindowPtr  NewCWindow(void *wStorage,const Rect *boundsRect,ConstStr255Param title,
           Boolean visible,short procID,WindowPtr behind,Boolean goAwayFlag,long refCon);

Naming Windows

void  GetWTitle(WindowPtr theWindow,Str255 title);
void  SetWTitle(WindowPtr theWindow,ConstStr255Param title);

Displaying Windows

void  DrawGrowIcon(WindowPtr theWindow);
void  SelectWindow(WindowPtr theWindow);
void  ShowWindow(WindowPtr theWindow);
void  HideWindow(WindowPtr theWindow);
void  ShowHide(WindowPtr theWindow,Boolean showFlag);
void  HiliteWindow(WindowPtr theWindow,Boolean fHilite);
void  BringToFront(WindowPtr theWindow);
void  SendBehind(WindowPtr theWindow,WindowPtr behindWindow);

Retrieving Mouse Information

short      FindWindow(Point thePoint,WindowPtr *theWindow);
WindowPtr  FrontWindow(void);

Moving Windows

void  MoveWindow(WindowPtr theWindow,short hGlobal,short vGlobal,Boolean front);
void  DragWindow(WindowPtr theWindow,Point startPt,const Rect *boundsRect);
long  DragGrayRgn(RgnHandle theRgn,Point startPt,const Rect *boundsRect,
      const Rect *slopRect,short axis,DragGrayRgnProcPtr actionProc);

Resizing Windows

void  SizeWindow(WindowPtr theWindow,short w,short h,Boolean fUpdate);
long  GrowWindow(WindowPtr theWindow,Point startPt,const Rect *bBox);

Zooming Windows

Boolean  TrackBox(WindowPtr theWindow,Point thePt,short partCode);
void     ZoomWindow(WindowPtr theWindow,short partCode,Boolean front);

Closing and Deallocating Windows

Boolean  TrackGoAway(WindowPtr theWindow,Point thePt);
void     CloseWindow(WindowPtr theWindow);
void     DisposeWindow(WindowPtr theWindow);

Maintaining the Update Region

void  BeginUpdate(WindowPtr theWindow);
void  EndUpdate(WindowPtr theWindow);
void  InvalRect(const Rect *badRect);
void  InvalRgn(RgnHandle badRgn);
void  ValidRect(const Rect *goodRect);
void  ValidRgn(RgnHandle goodRgn);

Setting and Retrieving Other Window Characteristics

void       SetWindowPic(WindowPtr theWindow,PicHandle pic);
PicHandle  GetWindowPic(WindowPtr theWindow);
long       GetWRefCon(WindowPtr theWindow);
void       SetWRefCon(WindowPtr theWindow,long data);
short      GetWVariant(WindowPtr theWindow);

Retrieving Window Information

OSStatus  GetWindowRegion(WindowPtr inWindow,WindowRegionCode inRegionCode,
          RgnHandle ioWinRgn)

Collapsing Windows

Boolean   IsWindowCollapsable(WindowPtr inWindow);
Boolean   IsWindowCollapsed(WindowPtr inWindow);
OSStatus  CollapseWindow(WindowPtr inWindow,Boolean inCollapseIt);
OSStatus  CollapseAllWindows(Boolean inCollapseEm); 

Manipulating the Desktop

void       SetDeskCPat(PixPatHandle deskPixPat);
void       GetWMgrPort(GrafPtr *wPort);
void       GetCWMgrPort(CGrafPtr *wMgrCPort);
RgnHandle  LMGetGrayRgn(void);

Go to Demo

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Summon your guild and prepare for war in...
Netmarble is making some pretty big moves with their latest update for Seven Knights Idle Adventure, with a bunch of interesting additions. Two new heroes enter the battle, there are events and bosses abound, and perhaps most interesting, a huge... | Read more »
Make the passage of time your plaything...
While some of us are still waiting for a chance to get our hands on Ash Prime - yes, don’t remind me I could currently buy him this month I’m barely hanging on - Digital Extremes has announced its next anticipated Prime Form for Warframe. Starting... | Read more »
If you can find it and fit through the d...
The holy trinity of amazing company names have come together, to release their equally amazing and adorable mobile game, Hamster Inn. Published by HyperBeard Games, and co-developed by Mum Not Proud and Little Sasquatch Studios, it's time to... | Read more »
Amikin Survival opens for pre-orders on...
Join me on the wonderful trip down the inspiration rabbit hole; much as Palworld seemingly “borrowed” many aspects from the hit Pokemon franchise, it is time for the heavily armed animal survival to also spawn some illegitimate children as Helio... | Read more »
PUBG Mobile teams up with global phenome...
Since launching in 2019, SpyxFamily has exploded to damn near catastrophic popularity, so it was only a matter of time before a mobile game snapped up a collaboration. Enter PUBG Mobile. Until May 12th, players will be able to collect a host of... | Read more »
Embark into the frozen tundra of certain...
Chucklefish, developers of hit action-adventure sandbox game Starbound and owner of one of the cutest logos in gaming, has released their roguelike deck-builder Wildfrost. Created alongside developers Gaziter and Deadpan Games, Wildfrost will... | Read more »
MoreFun Studios has announced Season 4,...
Tension has escalated in the ever-volatile world of Arena Breakout, as your old pal Randall Fisher and bosses Fred and Perrero continue to lob insults and explosives at each other, bringing us to a new phase of warfare. Season 4, Into The Fog of... | Read more »
Top Mobile Game Discounts
Every day, we pick out a curated list of the best mobile discounts on the App Store and post them here. This list won't be comprehensive, but it every game on it is recommended. Feel free to check out the coverage we did on them in the links below... | Read more »
Marvel Future Fight celebrates nine year...
Announced alongside an advertising image I can only assume was aimed squarely at myself with the prominent Deadpool and Odin featured on it, Netmarble has revealed their celebrations for the 9th anniversary of Marvel Future Fight. The Countdown... | Read more »
HoYoFair 2024 prepares to showcase over...
To say Genshin Impact took the world by storm when it was released would be an understatement. However, I think the most surprising part of the launch was just how much further it went than gaming. There have been concerts, art shows, massive... | Read more »

Price Scanner via MacPrices.net

You can save $300-$480 on a 14-inch M3 Pro/Ma...
Apple has 14″ M3 Pro and M3 Max MacBook Pros in stock today and available, Certified Refurbished, starting at $1699 and ranging up to $480 off MSRP. Each model features a new outer case, shipping is... Read more
24-inch M1 iMacs available at Apple starting...
Apple has clearance M1 iMacs available in their Certified Refurbished store starting at $1049 and ranging up to $300 off original MSRP. Each iMac is in like-new condition and comes with Apple’s... Read more
Walmart continues to offer $699 13-inch M1 Ma...
Walmart continues to offer new Apple 13″ M1 MacBook Airs (8GB RAM, 256GB SSD) online for $699, $300 off original MSRP, in Space Gray, Silver, and Gold colors. These are new MacBook for sale by... Read more
B&H has 13-inch M2 MacBook Airs with 16GB...
B&H Photo has 13″ MacBook Airs with M2 CPUs, 16GB of memory, and 256GB of storage in stock and on sale for $1099, $100 off Apple’s MSRP for this configuration. Free 1-2 day delivery is available... Read more
14-inch M3 MacBook Pro with 16GB of RAM avail...
Apple has the 14″ M3 MacBook Pro with 16GB of RAM and 1TB of storage, Certified Refurbished, available for $300 off MSRP. Each MacBook Pro features a new outer case, shipping is free, and an Apple 1-... Read more
Apple M2 Mac minis on sale for up to $150 off...
Amazon has Apple’s M2-powered Mac minis in stock and on sale for $100-$150 off MSRP, each including free delivery: – Mac mini M2/256GB SSD: $499, save $100 – Mac mini M2/512GB SSD: $699, save $100 –... Read more
Amazon is offering a $200 discount on 14-inch...
Amazon has 14-inch M3 MacBook Pros in stock and on sale for $200 off MSRP. Shipping is free. Note that Amazon’s stock tends to come and go: – 14″ M3 MacBook Pro (8GB RAM/512GB SSD): $1399.99, $200... Read more
Sunday Sale: 13-inch M3 MacBook Air for $999,...
Several Apple retailers have the new 13″ MacBook Air with an M3 CPU in stock and on sale today for only $999 in Midnight. These are the lowest prices currently available for new 13″ M3 MacBook Airs... Read more
Multiple Apple retailers are offering 13-inch...
Several Apple retailers have 13″ MacBook Airs with M2 CPUs in stock and on sale this weekend starting at only $849 in Space Gray, Silver, Starlight, and Midnight colors. These are the lowest prices... Read more
Roundup of Verizon’s April Apple iPhone Promo...
Verizon is offering a number of iPhone deals for the month of April. Switch, and open a new of service, and you can qualify for a free iPhone 15 or heavy monthly discounts on other models: – 128GB... Read more

Jobs Board

Relationship Banker - *Apple* Valley Financ...
Relationship Banker - Apple Valley Financial Center APPLE VALLEY, Minnesota **Job Description:** At Bank of America, we are guided by a common purpose to help Read more
IN6728 Optometrist- *Apple* Valley, CA- Tar...
Date: Apr 9, 2024 Brand: Target Optical Location: Apple Valley, CA, US, 92308 **Requisition ID:** 824398 At Target Optical, we help people see and look great - and Read more
Medical Assistant - Orthopedics *Apple* Hil...
Medical Assistant - Orthopedics Apple Hill York Location: WellSpan Medical Group, York, PA Schedule: Full Time Sign-On Bonus Eligible Remote/Hybrid Regular Apply Now Read more
*Apple* Systems Administrator - JAMF - Activ...
…**Public Trust/Other Required:** None **Job Family:** Systems Administration **Skills:** Apple Platforms,Computer Servers,Jamf Pro **Experience:** 3 + years of Read more
Liquor Stock Clerk - S. *Apple* St. - Idaho...
Liquor Stock Clerk - S. Apple St. Boise Posting Begin Date: 2023/10/10 Posting End Date: 2024/10/14 Category: Retail Sub Category: Customer Service Work Type: Part Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.