TweetFollow Us on Twitter

MACINTOSH C

Demonstration Program

Go to Contents
// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
// Appearance.c
// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
// 
// This program opens two kWindowDocumentProc windows containing:
//
// Ą  In the first window, a theme-compliant list view.
//
// Ą  In the second window, various images drawn with Appearance primitives and window
//    header text drawn in the correct theme colour.
//
// Two of the images in the second window are edit text field frames and one is a list
// box frame.  At any one time, one of these will have a keyboard focus frame drawn
// around it.  Clicking in one of the other frames will move the keyboard focus frame
// to that frame.
//
// The program is terminated by the choosing the Quit item in the File menu. 
//
// The program utilises the following resources:
//
// Ą  An 'MBAR' resource, and 'MENU' resources for Apple, File, Edit, and Demonstration
//     menus, and the pop-up menus (preload, non-purgeable).  
//
// Ą  Two 'WIND' resources (purgeable) (initially not visible).  
//
// Ą  'hrct' and 'hwin' resources (both purgeable), which provide help balloons 
//    describing the contents of the windows.  
//
// Ą  A 'SIZE' resource with the acceptSuspendResumeEvents, doesActivateOnFGSwitch,
//    and is32BitCompatible flags set.    
//
// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

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

#include <Appearance.h>
#include <Devices.h>
#include <Gestalt.h>
#include <LowMem.h>
#include <Sound.h>
#include <ToolUtils.h>

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

#define rMenubar     128
#define rNewWindow1  128
#define rNewWindow2  129
#define mApple       128
#define  iAbout      1
#define mFile        129
#define  iQuit       11

#define MAXLONG      0x7FFFFFFF
#define topLeft(r)   (((Point *) &(r))[0])

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

Boolean    gAppearancePresent     = false;
Boolean    gInCompatibilityMode   = false;
Boolean    gAppearance101present  = false;
Boolean    gAppearance110present  = false;
Boolean    gDone;
Boolean    gInBackground;
WindowPtr  gWindowPtr1, gWindowPtr2;
SInt16     gPixelDepth;  
Boolean    gIsColourDevice        = false;
Rect       gCurrentRect;

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

void  main                       (void);
void  doInitManagers             (void);
void  doEvents                   (EventRecord *);
void  doUpdate                   (EventRecord *);
void  doActivate                 (EventRecord *);
void  doActivateWindow           (WindowPtr,Boolean);
void  doOSEvent                  (EventRecord *);
void  doDrawThemePrimitives      (ThemeDrawState);
void  doDrawThemeCompliantText   (WindowPtr,ThemeDrawState);
void  doDrawListView             (WindowPtr);
void  doChangeKeyBoardFocus      (Point);
void  doGetDepthAndDevice        (void);

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

void  main(void)
{
  OSErr         osError;
  SInt32        response;
  Handle        menubarHdl;
  MenuHandle    menuHdl;
  EventRecord   EventStructure;

  // ......... check for Appearance and functions, compatibility mode, Appearance version

  osError = Gestalt(gestaltAppearanceAttr,&response);

  if(osError == noErr && (BitTst(&response,31 - gestaltAppearanceExists)))
  {
    gAppearancePresent = true;

    if(BitTst(&response,31 - gestaltAppearanceCompatMode))
      gInCompatibilityMode = true;

    Gestalt(gestaltAppearanceVersion,&response);

    if(response == 0x00000101)
      gAppearance101present = true;
    else if(response >= 0x00000110)
      gAppearance110present = true;
  }
  else
  {
    SysBeep(10);
    ExitToShell();
  }

  // ................................................................ 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');

  // ............................ open windows, set font size, show windows, move windows

  if(!(gWindowPtr1 = GetNewCWindow(rNewWindow1,NULL,(WindowPtr)-1)))
    ExitToShell();

  SetPort(gWindowPtr1);
  TextSize(10);
  ShowWindow(gWindowPtr1);
    
  if(!(gWindowPtr2 = GetNewCWindow(rNewWindow2,NULL,(WindowPtr)-1)))
    ExitToShell();

  SetPort(gWindowPtr2);
  TextSize(10);
  ShowWindow(gWindowPtr2);
  
  // ............................... set theme-compliant colour/pattern for second window
  
  SetThemeWindowBackground(gWindowPtr2,kThemeBrushDialogBackgroundActive,true);

  // ......... get pixel depth and whether colour device for certain Appearance functions  
  
  doGetDepthAndDevice();

    // ..... set top edit text field rectangle as target for initial keyboard focus frame
    
  SetRect(&gCurrentRect,20,141,239,162);

  // .................................................................... enter eventLoop

  gDone = false;

  while(!gDone)
  {
    if(WaitNextEvent(everyEvent,&EventStructure,MAXLONG,NULL))
      doEvents(&EventStructure);
  }
}

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

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

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

  InitCursor();  
  FlushEvents(everyEvent,0);

  RegisterAppearanceClient();
}

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

void  doEvents(EventRecord *eventStrucPtr)
{
  SInt8      charCode;
  SInt32     menuChoice;
  SInt16     menuID, menuItem;
  SInt16     partCode;
  WindowPtr  windowPtr;
  Str255     itemName;
  SInt16     daDriverRefNum;

  switch(eventStrucPtr->what)
  {
    case keyDown:
    case autoKey:
      charCode = eventStrucPtr->message & charCodeMask;
      if((eventStrucPtr->modifiers & cmdKey) != 0)
      {
        menuChoice = MenuEvent(eventStrucPtr);
        menuID = HiWord(menuChoice);
        menuItem = LoWord(menuChoice);
        if(menuID == mFile && menuItem  == iQuit)
          gDone = true;
      }
      break;
  
    case mouseDown:
      if(partCode = FindWindow(eventStrucPtr->where,&windowPtr))
      {
        switch(partCode)
        {
          case inMenuBar:
            menuChoice = MenuSelect(eventStrucPtr->where);
            menuID = HiWord(menuChoice);
            menuItem = LoWord(menuChoice);

            if(menuID == 0)
              return;

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

              case mFile:
                if(menuItem == iQuit)
                  gDone = true;
                break;
            }
            HiliteMenu(0);
            break;
        
          case inContent:
            if(windowPtr != FrontWindow())
              SelectWindow(windowPtr);
            else
            {
              if(FrontWindow() == gWindowPtr2)
              {
                SetPort(gWindowPtr2);
                doChangeKeyBoardFocus(eventStrucPtr->where);
              }
            }
            break;
          
          case inDrag:
            DragWindow(windowPtr,eventStrucPtr->where,&qd.screenBits.bounds);
            break;
        }
      }
      break;
      
    case updateEvt:
      doUpdate(eventStrucPtr);
      break;

    case activateEvt:
      doActivate(eventStrucPtr);
      break;

    case osEvt:
      doOSEvent(eventStrucPtr);
      HiliteMenu(0);
      break;
  }
}

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

void  doUpdate(EventRecord *eventStrucPtr)
{
  WindowPtr  windowPtr;
  
  windowPtr = (WindowPtr) eventStrucPtr->message;

  BeginUpdate(windowPtr);

  SetPort(windowPtr);
  
  if(windowPtr == gWindowPtr2)
  {
    if(gWindowPtr2 == FrontWindow() && !gInBackground)
    {
      doDrawThemePrimitives(kThemeStateActive);
      doDrawThemeCompliantText(windowPtr,kThemeStateActive);
      DrawThemeFocusRect(&gCurrentRect,true);
    }
    else
    {
      doDrawThemePrimitives(kThemeStateDisabled);
      doDrawThemeCompliantText(windowPtr,kThemeStateDisabled);
    }  
  }    
    
  if(windowPtr == gWindowPtr1)
    doDrawListView(windowPtr);

  EndUpdate(windowPtr);
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doActivate

void  doActivate(EventRecord *eventStrucPtr)
{
  WindowPtr  windowPtr;
  Boolean    becomingActive;

  windowPtr = (WindowPtr) eventStrucPtr->message;
  becomingActive = ((eventStrucPtr->modifiers & activeFlag) == activeFlag);
  doActivateWindow(windowPtr,becomingActive);
}

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

void  doActivateWindow(WindowPtr windowPtr,Boolean becomingActive)
{  
  if(windowPtr == gWindowPtr2)
  {
    SetPort(gWindowPtr2);

    doDrawThemePrimitives(becomingActive);
    doDrawThemeCompliantText(windowPtr,becomingActive);
    DrawThemeFocusRect(&gCurrentRect,becomingActive);
  }
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doOSEvent

void  doOSEvent(EventRecord *eventStrucPtr)
{
  switch((eventStrucPtr->message >> 24) & 0x000000FF)
  {
    case suspendResumeMessage:
      gInBackground = (eventStrucPtr->message & resumeFlag) == 0;
      doActivateWindow(FrontWindow(),!gInBackground);
      break;
  }
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doDrawThemePrimitives

void  doDrawThemePrimitives(ThemeDrawState inState)
{
  Rect  theRect;
      
  SetRect(&theRect,-1,-1,261,26);
  DrawThemeWindowHeader(&theRect,inState);

  SetRect(&theRect,20,46,119,115);
  DrawThemePrimaryGroup(&theRect,inState);

  SetRect(&theRect,140,46,239,115);
  DrawThemeSecondaryGroup(&theRect,inState);

  SetRect(&theRect,20,127,240,128);
  DrawThemeSeparator(&theRect,inState);

  SetRect(&theRect,20,141,239,162);
  DrawThemeEditTextFrame(&theRect,inState);

  SetRect(&theRect,20,169,239,190);
  DrawThemeEditTextFrame(&theRect,inState);

  if(gAppearance101present || gAppearance110present)
  {
    SetRect(&theRect,20,203,62,245);
    DrawThemeGenericWell(&theRect,inState,false);
  }

  SetRect(&theRect,20,258,62,300);
  DrawThemeGenericWell(&theRect,inState,true);

  SetRect(&theRect,75,202,76,302);
  DrawThemeSeparator(&theRect,inState);

  SetRect(&theRect,90,203,239,300);
  DrawThemeListBoxFrame(&theRect,inState);
  
  SetRect(&theRect,-1,321,261,337);
  DrawThemePlacard(&theRect,inState);
}  

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doDrawThemeCompliantText

void  doDrawThemeCompliantText(WindowPtr windowPtr,ThemeDrawState inState)
{
  SInt16  windowWidth, stringWidth;
  Str255  message = "\pBalloon help is available";

  if(inState == kThemeStateActive)
    SetThemeTextColor(kThemeTextColorWindowHeaderActive,gPixelDepth,gIsColourDevice);
  else
    SetThemeTextColor(kThemeTextColorWindowHeaderInactive,gPixelDepth,gIsColourDevice);

  windowWidth = (windowPtr)->portRect.right - (windowPtr)->portRect.left;
  stringWidth = StringWidth(message);
  MoveTo((windowWidth / 2) - (stringWidth / 2), 17);
  DrawString("\pBalloon help is available");  
}

// ××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doDrawListView

void  doDrawListView(WindowPtr windowPtr)
{
  Rect    theRect;
  SInt16  a;
  
  theRect = windowPtr->portRect;

  SetThemeBackground(kThemeBrushListViewBackground,gPixelDepth,gIsColourDevice);
  EraseRect(&theRect);

  theRect.left += 130;
  
  SetThemeBackground(kThemeBrushListViewSortColumnBackground,gPixelDepth,gIsColourDevice);
  EraseRect(&theRect);
  
  SetThemePen(kThemeBrushListViewSeparator,gPixelDepth,gIsColourDevice);

  theRect = windowPtr->portRect;
  for(a=theRect.top;a<=theRect.bottom;a+=18)
  {
    MoveTo(theRect.left,a);
    LineTo(theRect.right - 1,a);
  }

  SetThemeTextColor(kThemeTextColorListView,gPixelDepth,gIsColourDevice);
  
  for(a=theRect.top;a<=theRect.bottom +18;a+=18)
  {
    MoveTo(theRect.left,a - 5);
    DrawString("\p   List View Background        List View Sort Column");
  }
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doChangeKeyBoardFocus

void  doChangeKeyBoardFocus(Point mouseXY)
{
  Rect  edit1Rect, edit2Rect, listRec;
  
  DrawThemeFocusRect(&gCurrentRect,false);
  DrawThemeEditTextFrame(&gCurrentRect,kThemeStateActive);

  SetRect(&edit1Rect,20,141,239,162);
  SetRect(&edit2Rect,20,169,239,190);
  SetRect(&listRec,90,203,239,300);

  SetPort(gWindowPtr2);
  GlobalToLocal(&mouseXY);

  if(PtInRect(mouseXY,&edit1Rect))
    SetRect(&gCurrentRect,20,141,239,162);
  else if(PtInRect(mouseXY,&edit2Rect))
    SetRect(&gCurrentRect,20,169,239,190);
  else if(PtInRect(mouseXY,&listRec))
    SetRect(&gCurrentRect,90,203,239,300);
  
  DrawThemeFocusRect(&gCurrentRect,true);
}

// ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× doGetDepthAndDevice

void doGetDepthAndDevice(void)
{
  GDHandle  deviceHdl;

  deviceHdl = LMGetMainDevice();
  gPixelDepth = (*(*deviceHdl)->gdPMap)->pixelSize;
  if(BitTst(&(*deviceHdl)->gdFlags,gdDevType))
    gIsColourDevice = true;
}

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

Demonstration Program Comments

When this program is run, the user should:

*   First drag the top window to a position where the content of the bottom window is
    visible.

*   Choose Show Balloons from the Help menu and move the cursor over the frames in the
    window titled "Drawing With Primitives" window (when active), and the left and right
    sides of the window titled "Theme-Compliant List View" (when active), noting the 
    descriptions in the balloons.

*   With the "Drawing With Primitives" window frontmost, click in the edit text field
    frame not currently outlined with the keyboard focus frame, or in the list box frame,
    so as to move the keyboard focus frame to that rectangle.

*   Click on the desktop to send the application to the background and note the changed
    appearance of the frames and text in the "Drawing With Primitives" window.  Note also
    that there is no change to the appearance of the content region of the 
    "Theme-Compliant List View" window.  Click on the "Drawing With Primitives" 
    window to bring the application to the foreground with that window active, noting the 
    changed appearance of the frames and text.

In the following, reference is made to graphics devices and pixel depth.  Graphics devices
and pixel depth are explained at Chapter 11 - QuickDraw Preliminaries.

#define

The first block establishes constants representing menu IDs, resources, and menu items,
and window and menu bar resources.

MAXLONG is defined as the maximum possible long value, and is used in the WaitNextEvent
function.  The last line defines a common macro which converts the top and left fields of
a Rect structure to a Point.

Global Variables

gAppearancePresent will be assigned true if at least Version 1.0 of the Appearance Manager
is present.  gInCompatibilityMode will be assigned true if the machine on which the 
demonstration is running is in compatibility mode (applicable only to Versions 1.0 through
1.0.3 only). gAppearance101present will be assigned true if Versions 1.0.1, 1.0.2, or 
1.0.3 are present. gAppearance110present will be assigned true if Version 1.1 is present.

gDone, when set to true, causes the main event loop to be exited and the program to
terminate.  gInBackground relates to foreground/background switching.  gWindowPtr1 and
gWindowPtr2 will be assigned window pointers.

gPixelDepth will be assigned the pixel depth of the main device. gIsColourDevice will be
assigned true if the graphics device is a colour device and false if it is a monochrome
device.  The values in these two variables are required by certain Appearance functions. 
gCurrentRect will be assigned the rectangle which is to be the current target for the
keyboard focus frame.

main

Gestalt is called to determine whether some version of the Appearance Manager is present.
If so, bit 1 in response is tested to determine whether the machine on which the program 
is running is currently in compatibility mode (relevant only where Appearance Manager 
Versions 1.0 through 1.0.3 are present), and Gestalt is called again to determine whether 
Version 1.0.1 through 1.0.3, or Version 1.1 or later, is present.  If the Appearance 
Manager is not present, the system alert sound is played and the program simply 
terminates.

Note that the assignment to the global variable gInCompatibilityMode is for demonstration 
purposes only; the program does not use this variables for any purpose.

After the menus are set up, each window is created.  After each window is created, its 
graphics port is set as the current port and the text size for that port is set to 10pt, 
the window is shown.

SetThemeWindowBackground sets a theme-compliant colour/pattern for the "Drawing With
Primitives" window's content area.  This means that the content area will be automatically
repainted with that colour/pattern when required with no further assistance from the
application.  When true is passed in the third parameter, the content region of the window
is invalidated and the content region is repainted immediately.

The call to the application-defined function doGetDepthAndDevice determines the current
pixel depth of the graphics port, and whether the current graphics device is a colour
device, and assigns the results to the global variables gPixelDepth and gIsColourDevice.

The call to SetRect establishes the initial target for the keyboard focus frame.  This is
the rectangle used by the first edit text field frame.

doInitManagers

DoInitManagers is called from main immediately after it has been determined that the 
Appearance Manager is present.  In this demonstration program, and in all subsequent 
demonstration programs, a call to RegisterAppearanceClient has been added to this 
function.

If this program is run under Appearance Manager Versions 1.0 through 1.0.3, one effect of 
the call to RegisterAppearanceClient is that the new theme-compliant menu bar 
definition function (resource ID 63) will be used regardless of whether system-wide 
Appearance is selected on or off in the Appearance control panel.

doEvents

At the mouseDown case, the inContent case within the partCode switch is of relevance to
the demonstration.

If the mouse-down was within the content region of a window, and if that window is not the
front window, SelectWindow is called to bring that window to the front and activate it.

However, if the window is the front window, and if that window is the "Drawing With
Primitives" window, that window's graphics port is set as the current graphics port for
drawing, and the application-defined function doChangeKeyBoardFocus is called.  That
function determines whether the mouse-down was within one of the edit text field frames or
the list box frame, and moves the keyboard focus if necessary.

doUpdate

Within the doUpdate function, if the window to which the update event relates is the
"Drawing With Primitives" window, and if that window is currently the front window:

*   Application-defined functions are called to draw the primitives and the window header
    text in the active mode.

*   DrawThemeFocusRect is called to draw the keyboard focus frame using the rectangle
    currently assigned to the global variable gCurrentRect.

If, however, the "Drawing With Primitives" window is not the front window, the same calls
are made but with the primitives and text being drawn in the inactive mode.  Note that no
call is required to erase the keyboard focus frame because this will already have been
erased when the window was deactivated (see below).

If the window to which update event relates is the "Theme-Compliant List View" 
window, an application-defined function for drawing the window's content area is called.
Note that, for this window, there is no differentiation between active and inactive modes.
This is because, for list views, the same brush type constants are used regardless of 
whether the window is active or inactive.


doActivateWindow

When an activate event is received for the "Drawing With Primitives" window, the
application-defined functions for drawing the primitives and the window header text,
together with the Appearance function which draws and erases the keyboard focus rectangle,
are called.  To eliminate the necessity for if/else coding, the becomingActive value is
used to ensure that, firstly, the primitives and text are drawn in the appropriate mode
and, secondly, that the keyboard focus frame is either drawn or erased, depending on
whether the window is coming to the front or being sent to the back.

Once again, the "Theme-Compliant List View" window is treated differently because the
list view brush constants to be used are the same regardless of whether the window is 
activated and deactivated.

doDrawAppearancePrimitives

doDrawAppearancePrimitives uses Appearance Manager functions for drawing Appearance
primitives, and is called to draw the various frames in the "Drawing With Primitives" window.
The mode in which the primitives are drawn (active or inactive) is determined by the
Boolean value passed in the inState parameter.

Note that DrawThemeGenericWell, which was introduced with Version 1.0.1 of the Appearance
Manager, is called only if Versions 1.0.1 through 1.0.3, or Version 1.1, are present.

doDrawAppearanceCompliantText

doDrawAppearanceCompliantText is called to draw some advisory text in the window header
of the "Drawing With Primitives" window.  The QuickDraw drawing function DrawString does
the drawing; however, before the drawing begins, the Appearance function SetThemeTextColor
is used to set the foreground colour for drawing text, in either the active or inactive
modes, so as to comply with the current appearance.

At the first two lines, if "Drawing With Primitives" is the active window,
SetThemeTextColor is called with the kThemeActiveWindowHeaderTextColor text colour
constant passed in the first parameter.  At the next two lines, if the window is inactive,
SetThemeTextColor is called with kThemeInctiveWindowHeaderTextColor passed in the first
parameter.  Note that SetThemeTextColor requires the pixel depth of the graphics port, and
whether the graphics device is a colour device or a monochrome device, passed in the
second and third parameters.

The next three lines simply adjust QuickDraw's pen location so that the text is drawn
centered laterally in the window header frame.  The call to DrawString draws the specified
text.

doDrawListView

doDrawListView draws a theme-compliant list view background in the specified window.

The first line copies the window's port rectangle to a local variable of type Rect.

The call to SetThemeBackground sets the background colour/pattern to the colour/pattern
represented by the theme-compliant brush type constant kThemeListViewBackgroundBrush. 
The QuickDraw function EraseRect fills the whole of the port rectangle with this
colour/pattern.

The next line adjusts the Rect variable's left field so that the rectangle now represents
the right half of the port rectangle.  The same drawing process is then repeated, but this
time with kThemeListViewSortColumnBackgroundBrush passed in the first parameter of the
SetThemeBackground call.

SetThemePen is then called with the colour/pattern represented by the constant
kThemeListViewSeparatorBrush passed in the first parameter.  The rectangle for drawing is
then expanded to equate with the port rectangle before the following five lines draw
one-pixel-wide horizontal lines, at 18-pixel intervals, from the top to the bottom of the
port rectangle.

Finally, some text is drawn in the list view in the theme-compliant colour for list
views.  SetThemeTextColour is called with the kThemeListViewTextColor passed in, following
which a for loop draws some text, at 18-pixel intervals, from the top to the bottom of the
port rectangle.

doChangeKeyBoardFocus

doChangeKeyBoardFocus is called when a mouse-down occurs in the content region of the
"Drawing With Primitives" window.

At the first two lines, Appearance functions are used to, firstly, erase the keyboard
focus frame from the rectangle around which it is currently drawn and, secondly, redraw an
edit text field frame around that rectangle.

The next three lines make three local variables of type Rect equal to the rectangles for
the two edit text field frames and the list box frame.

The call to GlobalToLocal converts the coordinates of the mouse-down to the local
coordinates required by the following calls to PtInRect.  PtInRect returns true if the
mouse-down is within the rectangle passed in the second parameter.  If one of the calls to
PtInRect returns true, that rectangle is made the current rectangle for keyboard focus by
assigning it to the global variable gCurrentRect.

Whatever rectangle is assigned to gCurrentRect, the call to DrawThemeFocusRect draws a
theme-compliant keyboard focus frame around that rectangle.

doGetDepthAndDevice

doGetDepthAndDevice determines the pixel depth of the graphics port, and whether the
graphics device is a colour device or a monochrome device, and assigns the results to two
global variables.  This information is required by certain Appearance functions.
 

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

Apple Watch Ultra 2 now available at Apple fo...
Apple has, for the first time, begun offering Certified Refurbished Apple Watch Ultra 2 models in their online store for $679, or $120 off MSRP. Each Watch includes Apple’s standard one-year warranty... Read more
AT&T has the iPhone 14 on sale for only $...
AT&T has the 128GB Apple iPhone 14 available for only $5.99 per month for new and existing customers when you activate unlimited service and use AT&T’s 36 month installment plan. The fine... Read more
Amazon is offering a $100 discount on every M...
Amazon is offering a $100 instant discount on each configuration of Apple’s new 13″ M3 MacBook Air, in Midnight, this weekend. These are the lowest prices currently available for new 13″ M3 MacBook... Read more
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

Jobs Board

*Apple* Systems Administrator - JAMF - Syste...
Title: Apple Systems Administrator - JAMF ALTA is supporting a direct hire opportunity. This position is 100% Onsite for initial 3-6 months and then remote 1-2 Read more
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
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.