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

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 »
Explore some of BBCs' most iconic s...
Despite your personal opinion on the BBC at a managerial level, it is undeniable that it has overseen some fantastic British shows in the past, and now thanks to a partnership with Roblox, players will be able to interact with some of these... | Read more »
Play Together teams up with Sanrio to br...
I was quite surprised to learn that the massive social network game Play Together had never collaborated with the globally popular Sanrio IP, it seems like the perfect team. Well, this glaring omission has now been rectified, as that instantly... | Read more »
Dark and Darker Mobile gets a new teaser...
Bluehole Studio and KRAFTON have released a new teaser trailer for their upcoming loot extravaganza Dark and Darker Mobile. Alongside this look into the underside of treasure hunting, we have received a few pieces of information about gameplay... | Read more »
DOFUS Touch relaunches on the global sta...
After being a big part of a lot of gamers - or at the very least my - school years with Dofus and Wakfu, Ankama sort of shied away from the global stage a bit before staging a big comeback with Waven last year. Now, the France-based developers are... | Read more »

Price Scanner via MacPrices.net

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
B&H has 16-inch MacBook Pros on sale for...
Apple 16″ MacBook Pros with M3 Pro and M3 Max CPUs are in stock and on sale today for $200-$300 off MSRP at B&H Photo. Their prices are among the lowest currently available for these models. B... Read more
Updated Mac Desktop Price Trackers
Our Apple award-winning Mac desktop price trackers are the best place to look for the lowest prices and latest sales on all the latest computers. Scan our price trackers for the latest information on... Read more
9th-generation iPads on sale for $80 off MSRP...
Best Buy has Apple’s 9th generation 10.2″ WiFi iPads on sale for $80 off MSRP on their online store for a limited time. Prices start at only $249. Sale prices for online orders only, in-store prices... Read more
15-inch M3 MacBook Airs on sale for $100 off...
Best Buy has Apple 15″ MacBook Airs with M3 CPUs on sale for $100 off MSRP on their online store. Prices valid for online orders only, in-store prices may vary. Order online and choose free shipping... Read more
24-inch M3 iMacs now on sale for $150 off MSR...
Amazon is now offering a $150 discount on Apple’s new M3-powered 24″ iMacs. Prices start at $1149 for models with 8GB of RAM and 256GB of storage: – 24″ M3 iMac/8-core GPU/8GB/256GB: $1149.99, $150... Read more
15-inch M3 MacBook Airs now on sale for $150...
Amazon is now offering a $150 discount on Apple’s new M3-powered 15″ MacBook Airs. Prices start at $1149 for models with 8GB of RAM and 256GB of storage: – 15″ M3 MacBook Air/8GB/256GB: $1149.99, $... Read more
The latest Apple Education discounts on MacBo...
If you’re a student, teacher, or staff member at any educational institution, you can use your .edu email address when ordering at Apple Education to take up to $300 off the purchase of a new MacBook... Read more

Jobs Board

Early Preschool Teacher - Glenda Drive/ *Appl...
Early Preschool Teacher - Glenda Drive/ Apple ValleyTeacher Share by Email Share on LinkedIn Share on Twitter Read more
Retail Assistant Manager- *Apple* Blossom Ma...
Retail Assistant Manager- APPLE BLOSSOM MALL Brand: Bath & Body Works Location: Winchester, VA, US Location Type: On-site Job ID: 04225 Job Area: Store: Management Read more
Housekeeper, *Apple* Valley Village - Cassi...
Apple Valley Village Health Care Center, a senior care campus, is hiring a Part-Time Housekeeper to join our team! We will train you for this position! In this role, Read more
Sonographer - *Apple* Hill Imaging Center -...
Sonographer - Apple Hill Imaging Center - Evenings Location: York Hospital, York, PA Schedule: Full Time Sign-On Bonus Eligible Remote/Hybrid Regular Apply Now See Read more
Senior Software Engineer - *Apple* Fundamen...
…center of Microsoft's efforts to empower our users to do more. The Apple Fundamentals team focused on defining and improving the end-to-end developer experience in Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.