TweetFollow Us on Twitter

MACINTOSH C CARBON

Demonstration Program CarbonEvents1

Goto Contents

// *******************************************************************************************
// CarbonEvents1.c                                                          CARBON EVENT MODEL
// *******************************************************************************************
// 
// This program opens a kWindowFullZoomGrowDocumentProc window, creates a root control for
// the window (on Mac OS 8/9), and adds a pop-up menu button control to the window.
//
// The standard application event handler handles all application events.  The standard
// window event handler is installed on the window.  In addition, the program installs its own
// handler on the window for the purpose of determining which item the user chooses in the 
// pop-up menu button's menu.  (Although installed on the window, this handler could just as
// easily be installed on the control.)
//
// The program utilises the following resources:
//
// o  A 'plst' resource.
//
// o  An 'MBAR' resource, and 'MENU' resources for OS9Apple/Application, File, and Edit menus
//    and the pop-up menu (preload, non-purgeable).  
//
// o  A 'WIND' resource (purgeable) (initially not visible).  
//
// o  A 'SIZE' resource with the acceptSuspendResumeEvents, canBackground, 
//    doesActivateOnFGSwitch, and isHighLevelEventAware flags set.
//
// *******************************************************************************************

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

#include <Carbon.h>

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

#define rMenubar   128
#define rWindow    128
#define mFile      129
#define  iQuit     12
#define mPopupMenu 131
// .......................................................................... global variables

Boolean gRunningOnX = false;

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

void      main               (void);
void      doPreliminaries    (void);
OSStatus  windowEventHandler (EventHandlerCallRef,EventRef,void *);
void      doNewWindow        (void);
void      doGetControls      (WindowRef);

// ************************************************************************************** main

void  main(void)
{
  MenuBarHandle menubarHdl;
  SInt32        response;
  MenuRef       menuRef;

  // ........................................................................ do preliminaries

  doPreliminaries();

  // ............................................................... set up menu bar and menus

  menubarHdl = GetNewMBar(rMenubar);
  if(menubarHdl == NULL)
    ExitToShell();
  SetMenuBar(menubarHdl);
  DrawMenuBar();

  Gestalt(gestaltMenuMgrAttr,&response);
  if(response & gestaltMenuMgrAquaLayoutMask)
  {
    menuRef = GetMenuRef(mFile);
    if(menuRef != NULL)
    {
      DeleteMenuItem(menuRef,iQuit);
      DeleteMenuItem(menuRef,iQuit - 1);
    }

    gRunningOnX = true;
  }
  else
  {
    menuRef = GetMenuRef(mFile);
    if(menuRef != NULL)
      SetMenuItemCommandID(menuRef,iQuit,kHICommandQuit);
  }

  // ............................................................................. open window

  doNewWindow();

  // .............................................................. run application event loop

  RunApplicationEventLoop();
}

// *************************************************************************** doPreliminaries

void  doPreliminaries(void)
{
  MoreMasterPointers(32);
  InitCursor();
}

// ******************************************************************************* doNewWindow

void  doNewWindow(void)
{
  WindowRef     windowRef;
  OSStatus      osError;
  Rect          controlRect = { 42,39,62,235 };
  ControlRef    controlRef;
  EventTypeSpec windowEvents[] = { { kEventClassControl, kEventControlHit } };

  // .......................................................... open window and set attributes

  if(!(windowRef = GetNewCWindow(rWindow,NULL,(WindowRef) -1)))
    ExitToShell();
  SetPortWindowPort(windowRef);

  ChangeWindowAttributes(windowRef,kWindowStandardHandlerAttribute ,0);
 
  // ............................................................ install window event handler

  InstallWindowEventHandler(windowRef,
                            NewEventHandlerUPP((EventHandlerProcPtr) windowEventHandler),
                            GetEventTypeCount(windowEvents),windowEvents,0,NULL);

  // ............................. create root control for window and get popup button control

  if(!gRunningOnX)
    CreateRootControl(windowRef,&controlRef);

  if((osError = CreatePopupButtonControl(windowRef,&controlRect,CFSTR("Time Zone:"),
                                         mPopupMenu,false,-1,0,0,&controlRef)) != noErr)
    ExitToShell();

  // ............................................................................. show window

  ShowWindow(windowRef);
}

// ************************************************************************ windowEventHandler

OSStatus  windowEventHandler(EventHandlerCallRef eventHandlerCallRef,EventRef eventRef,
                             void* userData)
{
  OSStatus    result = eventNotHandledErr;
  UInt32      eventKind;
  ControlRef  controlRef;
  MenuRef     menuRef;
  Size        actualSize;
  SInt16      controlValue;
  Str255      menuItemString;
  Rect        theRect = { 0,0,40,293 };
  CFStringRef stringRef;
  Rect        textBoxRect;

  eventKind  = GetEventKind(eventRef);

  if(eventKind == kEventControlHit)
  {
    GetEventParameter(eventRef,kEventParamDirectObject,typeControlRef,NULL,
                      sizeof(controlRef),NULL,&controlRef);

    GetControlData(controlRef,kControlEntireControl,kControlPopupButtonMenuHandleTag,
                   sizeof(menuRef),&menuRef,&actualSize);
    controlValue = GetControlValue(controlRef);
    GetMenuItemText(menuRef,controlValue,menuItemString);

    EraseRect(&theRect);
    stringRef = CFStringCreateWithPascalString(NULL,menuItemString,
                                               kCFStringEncodingMacRoman);
    SetRect(&textBoxRect,theRect.left,7,theRect.right,22);
    DrawThemeTextBox(stringRef,kThemeSmallSystemFont,true,true,&textBoxRect,teJustCenter,
                     NULL);
    if(stringRef != NULL)
      CFRelease(stringRef);

    result = noErr;
  }

  return result;
}

// *******************************************************************************************

Demonstration Program CarbonEvents1 Comments

When this program is run, the user should:

o Drag, resize, zoom and, when done, close the window.

o Send the application to the background and bring it to the foreground, noting the activation
  and deactivation of the pop-up menu button control.

o Choose items in the pop-up menu button's menu.

o Quit the application by choosing the Quit item in the Mac OS 9 File/Mac OS X Application menu
  and using its Command-key equivalent.

main

If the program is running on OS 8/9, SetMenuItemCommandID is called to assign the command ID
'quit' to the Quit item in the File menu.  (This command is assigned to the Mac OS X Quit item
by default.)  Thus, when the Quit item is chosen on Mac OS 8/9 and Mac OS X, the standard
application event handler will call the default Quit Application Apple event handler
(automatically installed when RunApplicationEventLoop is called) to close down the program.

The standard application event handler is installed when RunApplicationEventLoop is called. The
standard application event handler handles all application events, including, in Classic event
model parlance, suspend and resume events (that is, application-deactivated and
application-activated events.

doNewWindow

After the window is created, ChangeWindowAttributes is called to set the standard handler
attribute, causing the standard window event handler to be installed on the window.  The
standard window event handles all window dragging, sizing, zooming, collapsing/minimising, and
closing operations, attends to control updating, and (provided a root control is created for
the window), control deactivation and activation when the program is sent to the back and
brought to the.  It also calls TrackControl when a mouse-down occurs in the pop-up menu button,
thus handling all user interaction with the control.

The call to InstallWindowEventHandler installs the application's window event handler on the
window.  A single event type (kEventControlHit) is registered.  Note that this handler could
have been installed on the control itself, but is installed on the window in this program for
the purpose of emphasizing the propagation order of events.  (No handler is installed on the
control, so the event will "fall through" to the window event handler.)

If the program is running on Mac OS 8/9, CreateRootControl is called to create a root control
for the window.  (This call is not necessary on Mac OS X because, on Mac OS X, a root control
is automatically created on windows which have at least one control.)

windowEventHandler

windowEventHandler is a callback function.  It is the window event handler installed on the
window by the call to InstallWindowEventHandler in main.  Its purpose is to determine the
control value of the pop-up menu button control, and thus the menu item the user chose.

As previously stated, the standard window event handler calls TrackControl when a mouse-down
occurs in the pop-up menu button.  The Carbon Event Manager sends the kEventControlHit event
type when TrackControl returns (regardless, incidentally, of whether the cursor is still within
the control when the mouse button is released).

GetEventType is called to get the event type.  If the event type is kEventControlHit, the if
block executes and the handler returns noErr, indicating to the Carbon Event Manager that the
event has been fully handled and that it should not be propagated further.  If the event type
is not kEventControlHit, the handler returns eventNotHandledErr, indicating that the event
should be propagated further.

Within the if block, GetEventParameter is called to extract certain data from the event,
specifically, a reference to the control.  This reference is passed in the call to
GetControlData, which gets a reference to the control's menu.  The call to GetControlValue then
gets the control's value, and the call to GetMenuItemText gets the text of the menu item.  This
text is then drawn at the top of the window to prove that the handler has done its job.

Demonstration Program CarbonEvents2

// *******************************************************************************************
// CarbonEvents2.h                                                          CARBON EVENT MODEL
// *******************************************************************************************
// 
// This program allows the user to:
//
// o  Open, close, and interact with kWindowFullZoomGrowDocumentProc windows containing
//    various controls.
//
// o  Open, close and interact with a movable modal dialog and, on Mac OS X only,
//    window-modal (sheet) alerts and window-modal (sheet) dialogs.
//
// The program demonstrates the main aspects of the Carbon Event model, specifically:
//
// o  Events relating to menus, windows and controls, including the detection of mouse-downs
//    in controls in document windows and movable modal dialogs.
//
// o  Keyboard events.
//
// o  Events relating to application activation and deactivation (resume and suspend in 
//    Classic event model parlance).
//
// o  The use of mouse-moved events in support of cursor adjustment functions.
//
// o  The installation of event loop timers (used, in this program, to trigger an "idle" 
//    function.
//
// The program also demonstrates the implementation of live window resizing. 
//
// The window contains a window header frame in which is displayed the menu items chosen from 
// pop-up menu buttons, the identity of a push button when that push button is clicked, and
// scroll bar control values when the scroll arrows or gray areas/track of the scroll bars are
// clicked and when the scroll box/scroller is dragged.  (The vertical scroll bar is the 
// non-live feedback variant.  The horizontal scroll bar is the live-feedback variant.)  Text
// extracted from the edit text item in the window-modal (sheet) dialog and the identity of 
// the button clicked in the window-modal (sheet) alert are also displayed in the window 
// header frame.
//
// The movable modal dialog serves the secondary purpose of proving window correct window 
// updating even though an event filter function is not used by the dialog.  
//
// The program utilises the following resources:
//
// o  A 'plst' resource.
//
// o  An 'MBAR' resource, and 'MENU' resources for OS9Apple/Application, File, Edit, and 
//    Typing Target, and Dialogs menus, and the pop-up menus (preload, non-purgeable).  
//
// o  A 'WIND' resource (purgeable) (initially not visible).
//
// o  A 'DLOG' resource ((purgeable) (initially not visible), with associated 'DITL', 'dlgx' 
//    and 'dfnt' resources, for the window-modal (sheet) dialog.
//
// o  A 'CNTL' resource (purgeable) for an image well control in the window-modal (sheet)
//    dialog.
//
// o  A 'STR#' resource (purgeable) containing text for the window-modal (sheet) alert. 
//
// o  A 'SIZE' resource with the acceptSuspendResumeEvents, canBackground, 
//    doesActivateOnFGSwitch, and isHighLevelEventAware flags set.
//
// *******************************************************************************************

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

#include <Carbon.h>

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

#define rMenubar                128
#define rWindow                 128
#define rAboutDialog            128
#define mAppleApplication       128
#define  iAbout                 1
#define mFile                   129
#define  iQuit                  12
#define  iNew                   1
#define  iClose                 4
#define mTyping                 131
#define  iDocument              1
#define  iEditTextControl       2
#define  iAllOfTheAbove         3
#define mDialogs                132
#define  iMovableModal          1
#define  iSheetAlert            2
#define  iSheetDialog           3
#define mWindow                 135
#define rSheetDialog            128
#define rSheetStrings           128
#define  sAlertSheetMessage     1
#define  sAlertSheetInformative 2
#define kPopupCountryID         'ctry'
#define kScrollBarWidth         15
#define MIN(a,b)                ((a) < (b) ? (a) : (b))
#define topLeft(r)              (((Point *) &(r))[0])
#define botRight(r)             (((Point *) &(r))[1])

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

typedef struct
{
  ControlRef popupTimeZoneRef;
  ControlRef popupCountryRef;
  ControlRef radiobuttonRedRef;
  ControlRef radiobuttonWhiteRef;
  ControlRef radiobuttonBlueRef;
  ControlRef groupboxColourRef;
  ControlRef groupboxTypingRef;
  ControlRef buttonRef;
  ControlRef buttonDefaultRef;
  ControlRef editTextRef;
  ControlRef scrollbarVertRef;
  ControlRef scrollbarHorizRef;
} docStruc, **docStrucHandle;

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

void            main                  (void);
void            doPreliminaries       (void);
OSStatus        appEventHandler       (EventHandlerCallRef,EventRef,void *);
OSStatus        windowEventHandler    (EventHandlerCallRef,EventRef,void *);
void            doNewWindow           (void);
EventHandlerUPP doGetHandlerUPP       (void);
void            doCloseWindow         (WindowRef);
void            doGetControls         (WindowRef);
void            doIdle                (void);
void            doAdjustMenus         (void);
void            doMenuChoice          (MenuID,MenuItemIndex);
void            doDrawContent         (WindowRef);
void            doActivateDeactivate  (WindowRef,Boolean);
void            doControlHit1         (WindowRef,ControlRef,Point,ControlPartCode);
void            doControlHit2         (void);
void            doPopupMenuChoice     (WindowRef,ControlRef,SInt16);
void            doVertScrollbar       (ControlPartCode,WindowRef,ControlRef,Point);
void            actionFunctionVert    (ControlRef,ControlPartCode);
void            actionFunctionHoriz   (ControlRef,ControlPartCode);
void            doMoveScrollBox       (ControlRef,SInt16);
void            doRadioButtons        (ControlRef,WindowRef);
void            doCheckboxes          (ControlRef);
void            doPushButtons         (ControlRef,WindowRef);
void            doAdjustScrollBars    (WindowRef);
void            doAdjustCursor        (WindowRef);
void            doDrawDocumentTyping  (SInt8,UInt32);
void            doDrawMessage         (WindowRef,Boolean);
void            doConcatPStrings      (Str255,Str255);
void            doCopyPString         (Str255,Str255);

OSStatus        doSheetAlert          (void);
OSStatus        doSheetDialog         (void);
EventHandlerUPP doGetSheetHandlerUPP  (void);
OSStatus        sheetEventHandler     (EventHandlerCallRef,EventRef,void *);
OSStatus        doMovableModalDialog  (void);
EventHandlerUPP doGetDialogHandlerUPP (void);
OSStatus        dialogEventHandler    (EventHandlerCallRef,EventRef,void *);

// *******************************************************************************************
// CarbonEvents2.c
// *******************************************************************************************

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

#include "CarbonEvents2.h"

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

ControlActionUPP gActionFunctionVertUPP;
ControlActionUPP gActionFunctionHorizUPP;
Boolean          gRunningOnX = false;
SInt16           gNumberOfWindows = 0;
Str255           gCurrentString;
SInt16           gTypingTarget = 3;

// ************************************************************************************** main

void  main(void)
{
  MenuBarHandle     menubarHdl;
  SInt32            response;
  MenuRef           menuRef;
  EventLoopTimerUPP eventLoopTimerUPP;
  EventTypeSpec   applicationEvents[] = { { kEventClassApplication, kEventAppActivated    },
                                          { kEventClassCommand,     kEventProcessCommand  },
                                          { kEventClassMenu,        kEventMenuEnableItems },
                                          { kEventClassMouse,       kEventMouseMoved      } };

  // ........................................................................ do preliminaries

  doPreliminaries();

  // ..................................................... create universal procedure pointers

  gActionFunctionVertUPP  = NewControlActionUPP((ControlActionProcPtr) actionFunctionVert);
  gActionFunctionHorizUPP = NewControlActionUPP((ControlActionProcPtr) actionFunctionHoriz);

  // ............................................................... set up menu bar and menus

  menubarHdl = GetNewMBar(rMenubar);
  if(menubarHdl == NULL)
    ExitToShell();
  SetMenuBar(menubarHdl);

  CreateStandardWindowMenu(0,&menuRef);
  SetMenuID(menuRef,mWindow);
  InsertMenu(menuRef,0);

  DrawMenuBar();

  Gestalt(gestaltMenuMgrAttr,&response);
  if(response & gestaltMenuMgrAquaLayoutMask)
  {
    menuRef = GetMenuRef(mFile);
    if(menuRef != NULL)
    {
      DeleteMenuItem(menuRef,iQuit);
      DeleteMenuItem(menuRef,iQuit - 1);
    }

    gRunningOnX = true;
  }
  else
  {
    menuRef = GetMenuRef(mFile);
    if(menuRef != NULL)
      SetMenuItemCommandID(menuRef,iQuit,kHICommandQuit);

    menuRef = GetMenuRef(mDialogs);
    if(menuRef != NULL)
    {
      DisableMenuItem(menuRef,iSheetAlert);
      DisableMenuItem(menuRef,iSheetDialog);
    }
  }

  // ................................................. initial advisory text for window header

  doCopyPString("\pManipulate the window and controls.  Do typing.",gCurrentString);

  // ....................................................... install application event handler
  
  InstallApplicationEventHandler(NewEventHandlerUPP((EventHandlerProcPtr) appEventHandler),
                                 GetEventTypeCount(applicationEvents),applicationEvents,
                                 0,NULL);

  // ........................................................................... install timer

  eventLoopTimerUPP = NewEventLoopTimerUPP((EventLoopTimerProcPtr) doIdle);

  InstallEventLoopTimer(GetCurrentEventLoop(),0,TicksToEventTime(GetCaretTime()),
                        eventLoopTimerUPP,NULL,NULL);

  // ............................................................................. open window

  doNewWindow();

  // .............................................................. run application event loop

  RunApplicationEventLoop();
}

// *************************************************************************** doPreliminaries

void  doPreliminaries(void)
{
  MoreMasterPointers(128);
  InitCursor();
}

// *************************************************************************** appEventHandler

OSStatus  appEventHandler(EventHandlerCallRef eventHandlerCallRef,EventRef eventRef,
                          void * userData)
{
  OSStatus      result = eventNotHandledErr;
  UInt32        eventClass;
  UInt32        eventKind;
  HICommand     hiCommand;
  MenuID        menuID;
  MenuItemIndex menuItem;
  WindowClass   windowClass;

  eventClass = GetEventClass(eventRef);
  eventKind  = GetEventKind(eventRef);

  switch(eventClass)
  {
    case kEventClassApplication:
      if(eventKind == kEventAppActivated)
        SetThemeCursor(kThemeArrowCursor);
      break;

    case kEventClassCommand:
      if(eventKind == kEventProcessCommand)
      {
        GetEventParameter(eventRef,kEventParamDirectObject,typeHICommand,NULL,
                          sizeof(HICommand),NULL,&hiCommand);
        if(hiCommand.commandID == kHICommandQuit)
          result = eventNotHandledErr;
        menuID = GetMenuID(hiCommand.menu.menuRef);
        menuItem = hiCommand.menu.menuItemIndex;
        if((hiCommand.commandID != kHICommandQuit) && 
           (menuID >= mAppleApplication && menuID <= mDialogs))
        {
          doMenuChoice(menuID,menuItem);
          result = noErr;
        }
        if(hiCommand.commandID == kPopupCountryID)
        {
          doControlHit2();
          result = noErr;
        }
      }
      break;

    case kEventClassMenu:
      if(eventKind == kEventMenuEnableItems)
      {
        GetWindowClass(FrontWindow(),&windowClass);
        if(windowClass == kDocumentWindowClass)
          doAdjustMenus();
        result = noErr;
      }
      break;

    case kEventClassMouse:
      if(eventKind == kEventMouseMoved)
      {
        GetWindowClass(FrontWindow(),&windowClass);
        if(windowClass == kDocumentWindowClass)
          doAdjustCursor(FrontWindow());
        result = noErr;
      }
      break;
  }

  return result;
}

// ************************************************************************ windowEventHandler

OSStatus  windowEventHandler(EventHandlerCallRef eventHandlerCallRef,EventRef eventRef,
                             void* userData)
{
  OSStatus        result = eventNotHandledErr;
  UInt32          eventClass;
  UInt32          eventKind;
  WindowRef       windowRef;
  Rect            mainScreenRect, portRect;
  BitMap          screenBits;
  Point           idealHeightAndWidth, minimumHeightAndWidth, mouseLocation;
  ControlRef      controlRef;
  ControlPartCode controlPartCode;
  SInt8           charCode;
  UInt32          modifiers; 
  HICommand       hiCommand;

  eventClass = GetEventClass(eventRef);
  eventKind  = GetEventKind(eventRef);

  switch(eventClass)
  {
    case kEventClassWindow:                                              // event class window

      GetEventParameter(eventRef,kEventParamDirectObject,typeWindowRef,NULL,sizeof(windowRef),
                        NULL,&windowRef);

      switch(eventKind)
      {
        case kEventWindowDrawContent:
          doDrawContent(windowRef);
          break;

        case kEventWindowActivated:
          doActivateDeactivate(windowRef,true);
          break;

        case kEventWindowDeactivated:
          doActivateDeactivate(windowRef,false);
          break;

        case kEventWindowGetIdealSize:
          mainScreenRect = GetQDGlobalsScreenBits(&screenBits)->bounds;
          idealHeightAndWidth.v = mainScreenRect.bottom - 75;
          idealHeightAndWidth.h = 600;
          SetEventParameter(eventRef,kEventParamDimensions,typeQDPoint,
                            sizeof(idealHeightAndWidth),&idealHeightAndWidth);
           result = noErr;
          break;

        case kEventWindowGetMinimumSize:
          minimumHeightAndWidth.v = 308; 
          minimumHeightAndWidth.h = 290;
          SetEventParameter(eventRef,kEventParamDimensions,typeQDPoint,
                            sizeof(minimumHeightAndWidth),&minimumHeightAndWidth);
          result = noErr;
          break;

        case kEventWindowZoomed:
          GetWindowPortBounds(windowRef,&portRect);
          EraseRect(&portRect);
          doAdjustScrollBars(windowRef);
          result = noErr;
          break;

        case kEventWindowBoundsChanged:
          doAdjustScrollBars(windowRef);
          doDrawMessage(windowRef,true);
          result = noErr;
          break;

        case kEventWindowClose:
          doCloseWindow(windowRef);
          break;
      }
      break;

    case kEventClassControl:                                            // event class control
      switch(eventKind)
      {
        case kEventControlClick:
          GetEventParameter(eventRef,kEventParamMouseLocation,typeQDPoint,NULL,
                            sizeof(mouseLocation),NULL,&mouseLocation);
          SetPortWindowPort(FrontWindow());
          GlobalToLocal(&mouseLocation);
          controlRef = FindControlUnderMouse(mouseLocation,FrontWindow(),&controlPartCode);
          if(controlRef)
          {
            doControlHit1(FrontWindow(),controlRef,mouseLocation,controlPartCode);
            result = noErr;
          }
          break;
      }
      break;

    case kEventClassKeyboard:                                          // event class keyboard
      switch(eventKind)
      {
        case kEventRawKeyDown:
          if(gTypingTarget == 1 || gTypingTarget == 3)
          {
            GetEventParameter(eventRef,kEventParamKeyMacCharCodes,typeChar,NULL,
                              sizeof(charCode),NULL,&charCode);
            GetEventParameter(eventRef,kEventParamKeyModifiers,typeUInt32,NULL,
                              sizeof(modifiers),NULL,&modifiers);
            doDrawDocumentTyping(charCode,modifiers);
          }
          if(gTypingTarget == 1)
            result = noErr;
          break;
      }
      break;

    case kEventClassCommand:                                            // event class command
      if(eventKind == kEventProcessCommand)
      {
        GetEventParameter(eventRef,kEventParamDirectObject,typeHICommand,NULL,
                          sizeof(HICommand),NULL,&hiCommand);
        if(hiCommand.commandID == kHICommandOK)
          doCopyPString("\pOK button hit",gCurrentString);
        if(hiCommand.commandID == kHICommandCancel)
          doCopyPString("\pCancel button hit",gCurrentString);
        if(hiCommand.commandID == kHICommandOther)
          doCopyPString("\pOther button hit",gCurrentString);
        GetWindowPortBounds(FrontWindow(),&portRect);
        InvalWindowRect(FrontWindow(),&portRect);
      }
      break;
  }

  return result;
}

// ******************************************************************************* doNewWindow

void  doNewWindow(void)
{
  WindowRef      windowRef;
  Str255         windowTitleString = "\pCarbonEvents2 - ";
  Str255         theString;
  docStrucHandle docStrucHdl;
  SInt16         a;
  MenuRef        menuRef;
  EventTypeSpec  windowEvents[] = { { kEventClassWindow,   kEventWindowDrawContent    },
                                    { kEventClassWindow,   kEventWindowActivated      },
                                    { kEventClassWindow,   kEventWindowDeactivated    },
                                    { kEventClassWindow,   kEventWindowGetIdealSize   },
                                    { kEventClassWindow,   kEventWindowGetMinimumSize },
                                    { kEventClassWindow,   kEventWindowZoomed         },
                                    { kEventClassWindow,   kEventWindowBoundsChanged  },
                                    { kEventClassWindow,   kEventWindowClose          },
                                    { kEventClassControl,  kEventControlClick         },
                                    { kEventClassKeyboard, kEventRawKeyDown           },
                                    { kEventClassCommand,  kEventProcessCommand       } };

  // .......................................................... open window and set attributes

  if(!(windowRef = GetNewCWindow(rWindow,NULL,(WindowRef) -1)))
    ExitToShell();

  ChangeWindowAttributes(windowRef,kWindowStandardHandlerAttribute,0);
  if(gRunningOnX)
    ChangeWindowAttributes(windowRef,kWindowLiveResizeAttribute,0);

  // .............................................. alternative open window and set attributes

  // Rect              contentRect = { 100,100,405,393 };
  // WindowAttributes  attributes  = kWindowStandardHandlerAttribute |
  //                                 kWindowStandardDocumentAttributes |
  //                                 kWindowLiveResizeAttribute;
  //
  // CreateNewWindow(kDocumentWindowClass,attributes,&contentRect,&windowRef);
  // RepositionWindow(windowRef,NULL,kWindowAlertPositionOnMainScreen);
  
  // ........... get block for document structure, assign handle to window record refCon field

  if(!(docStrucHdl = (docStrucHandle) NewHandle(sizeof(docStruc))))
    ExitToShell();

  // ........................................................................ set window title

  SetWRefCon(windowRef,(SInt32) docStrucHdl);
  gNumberOfWindows ++;
  NumToString(gNumberOfWindows,theString);
  doConcatPStrings(windowTitleString,theString);
  SetWTitle(windowRef,windowTitleString);

  SetPortWindowPort(windowRef);
  TextSize(46);

  // ............................ if running on Mac OS 8/9, set theme-compliant colour/pattern

  SetThemeWindowBackground(windowRef,kThemeBrushDialogBackgroundActive,false);

  // ............................................................ install window event handler

  InstallWindowEventHandler(windowRef,doGetHandlerUPP(),GetEventTypeCount(windowEvents),
                            windowEvents,0,NULL);

  // ....................................... get controls, adjust scroll bars, and show window

  doGetControls(windowRef);
  doAdjustScrollBars(windowRef);
  ShowWindow(windowRef);

  // ..................... enable Typing and Window menu, fix typing target and keyboard focus

  menuRef = GetMenuRef(mTyping);
  EnableMenuItem(menuRef,0);

  for(a = iDocument;a <= iAllOfTheAbove;a ++)
    CheckMenuItem(menuRef,a,false);
  CheckMenuItem(menuRef,iAllOfTheAbove,true);
  SetKeyboardFocus(windowRef,(*docStrucHdl)->editTextRef,kControlFocusNextPart);
  gTypingTarget = 3;
  
  EnableMenuItem(GetMenuRef(mWindow),0);
}

// *************************************************************************** doGetHandlerUPP

EventHandlerUPP  doGetHandlerUPP(void)
{
  static EventHandlerUPP windowEventHandlerUPP;

  if(windowEventHandlerUPP == NULL)
    windowEventHandlerUPP = NewEventHandlerUPP((EventHandlerProcPtr) windowEventHandler);

  return windowEventHandlerUPP;
}

// ***************************************************************************** doCloseWindow

void  doCloseWindow(WindowRef windowRef)
{
  docStrucHandle docStrucHdl;

  KillControls(windowRef);

  docStrucHdl = (docStrucHandle) (GetWRefCon(windowRef));
  DisposeHandle((Handle) docStrucHdl);

  gNumberOfWindows --;

  if(gNumberOfWindows == 0)
  {
    DisableMenuItem(GetMenuRef(mTyping),0);
    DisableMenuItem(GetMenuRef(mWindow),0);
  }
}

// ***************************************************************************** doGetControls

void  doGetControls(WindowRef windowRef)
{
  ControlRef     controlRef;
  docStrucHandle docStrucHdl;
  OSStatus       osError;
  Rect           controlRect;
  Boolean        booleanData = true;

  CreateRootControl(windowRef,&controlRef);

  docStrucHdl = (docStrucHandle) (GetWRefCon(windowRef));

  SetRect(&controlRect,40,40,235,60);
  if((osError = CreatePopupButtonControl(windowRef,&controlRect,CFSTR("Time Zone:"),133,false,
                                         -1,0,0,&(*docStrucHdl)->popupTimeZoneRef)) != noErr)
    ExitToShell();

  SetRect(&controlRect,55,73,235,93);
  if((osError = CreatePopupButtonControl(windowRef,&controlRect,CFSTR("Country:"),134,false,
                                         -1,0,0,&(*docStrucHdl)->popupCountryRef)) != noErr)
    ExitToShell();

  SetRect(&controlRect,35,126,91,144);
  if((osError = CreateRadioButtonControl(windowRef,&controlRect,CFSTR("Red"),1,false,
                                         &(*docStrucHdl)->radiobuttonRedRef)) != noErr)
    ExitToShell();

  SetRect(&controlRect,35,148,91,166);
  if((osError = CreateRadioButtonControl(windowRef,&controlRect,CFSTR("White"),0,false,
                                         &(*docStrucHdl)->radiobuttonWhiteRef)) != noErr)
    ExitToShell();

  SetRect(&controlRect,35,170,91,188);
  if((osError = CreateRadioButtonControl(windowRef,&controlRect,CFSTR("Blue"),0,false,
                                         &(*docStrucHdl)->radiobuttonBlueRef)) != noErr)
    ExitToShell();

  SetRect(&controlRect,20,102,107,201);
  if((osError = CreateGroupBoxControl(windowRef,&controlRect,CFSTR("Colour"),true,
                                      &(*docStrucHdl)->groupboxColourRef)) != noErr)
    ExitToShell();

  SetRect(&controlRect,123,102,255,201);
  if((osError = CreateGroupBoxControl(windowRef,&controlRect,CFSTR("Typing"),true,
                                      &(*docStrucHdl)->groupboxTypingRef)) != noErr)
    ExitToShell();

  SetRect(&controlRect,63,213,132,233);
  if((osError = CreatePushButtonControl(windowRef,&controlRect,CFSTR("Cancel"),
                                        &(*docStrucHdl)->buttonRef)) != noErr)
    ExitToShell();

  SetRect(&controlRect,144,213,213,233);
  if((osError = CreatePushButtonControl(windowRef,&controlRect,CFSTR("OK"),
                                        &(*docStrucHdl)->buttonDefaultRef)) != noErr)
    ExitToShell();

  SetRect(&controlRect,26,251,249,267);
  if((osError = CreateEditTextControl(windowRef,&controlRect,NULL,false,true,NULL,
                                      &(*docStrucHdl)->editTextRef)) != noErr)
    ExitToShell();

  SetRect(&controlRect,0,0,16,262);
  if((osError = CreateScrollBarControl(windowRef,&controlRect,0,0,125,0,false,NULL,
                                       &(*docStrucHdl)->scrollbarVertRef)) != noErr)
    ExitToShell();

  SetRect(&controlRect,0,0,245,16);
  if((osError = CreateScrollBarControl(windowRef,&controlRect,0,0,125,0,true,NULL,
                                       &(*docStrucHdl)->scrollbarHorizRef)) != noErr)
    ExitToShell();

  AutoEmbedControl((*docStrucHdl)->radiobuttonRedRef,windowRef);
  AutoEmbedControl((*docStrucHdl)->radiobuttonWhiteRef,windowRef);
  AutoEmbedControl((*docStrucHdl)->radiobuttonBlueRef,windowRef);

  SetControlCommandID((*docStrucHdl)->popupCountryRef,kPopupCountryID);

  SetControlData((*docStrucHdl)->buttonDefaultRef,kControlEntireControl,
                 kControlPushButtonDefaultTag,sizeof(booleanData),&booleanData);
}

// ************************************************************************************ doIdle

void  doIdle(void)
{
  if(!gRunningOnX)
    IdleControls(FrontWindow());
}

// ***************************************************************************** doAdjustMenus

void  doAdjustMenus(void)
{
  MenuRef   menuRef;
  OSStatus  osError;
  WindowRef windowRef;

  if(FrontWindow())
  {
    menuRef = GetMenuRef(mFile);
    EnableMenuItem(menuRef,iClose);
    menuRef = GetMenuRef(mTyping);
    EnableMenuItem(menuRef,0);
  }
  else
  {
    menuRef = GetMenuRef(mFile);
    DisableMenuItem(menuRef,iClose);
    menuRef = GetMenuRef(mTyping);
    DisableMenuItem(menuRef,0);
  }

  if(gRunningOnX)
  {
    if((osError = GetSheetWindowParent(FrontWindow(),&windowRef)) == noErr)
    {
      menuRef = GetMenuRef(mFile);
      DisableMenuItem(menuRef,iClose);
      menuRef = GetMenuRef(mTyping);
      DisableMenuItem(menuRef,0);
    }
    else
    {
      if(FrontWindow())
      {
        menuRef = GetMenuRef(mTyping);
        EnableMenuItem(menuRef,0);
      }
    }

    menuRef = GetMenuRef(mDialogs);
    if(((osError = GetSheetWindowParent(FrontWindow(),&windowRef)) == noErr) || 
       (FrontWindow() == NULL) || IsWindowCollapsed(FrontWindow()))
    {
      DisableMenuItem(menuRef,iSheetAlert);
      DisableMenuItem(menuRef,iSheetDialog);
    }
    else
    {
      EnableMenuItem(menuRef,iSheetAlert);
      EnableMenuItem(menuRef,iSheetDialog);
    }
  }
}

// ****************************************************************************** doMenuChoice

void  doMenuChoice(MenuID menuID,MenuItemIndex menuItem)
{
  WindowRef      windowRef;
  SInt16         a;
  MenuRef        menuRef;
  docStrucHandle docStrucHdl;

  if(menuID == 0)
    return;

  windowRef = FrontWindow();

  switch(menuID)
  {
    case mAppleApplication:
      if(menuItem == iAbout)
        SysBeep(10);
      break;

    case mFile:
      if(menuItem == iNew)
        doNewWindow();
      else if(menuItem == iClose)
      {
        doCloseWindow(windowRef);
        DisposeWindow(windowRef);
      }
      break;

    case mTyping:
      menuRef = GetMenuRef(mTyping);
      for(a = iDocument;a <= iAllOfTheAbove;a ++)
        CheckMenuItem(menuRef,a,false);
      CheckMenuItem(menuRef,menuItem,true);
      gTypingTarget = menuItem;
      docStrucHdl = (docStrucHandle) (GetWRefCon(windowRef));
      if(menuItem == iDocument)
        SetKeyboardFocus(windowRef,(*docStrucHdl)->editTextRef,kControlFocusNoPart);
      else
        SetKeyboardFocus(windowRef,(*docStrucHdl)->editTextRef,kControlFocusNextPart);
      break;

    case mDialogs:
      if(menuItem == iMovableModal)
        if(doMovableModalDialog() != noErr)
          ExitToShell();
      if(menuItem == iSheetAlert)
        if(doSheetAlert() != noErr)
          ExitToShell();
      if(menuItem == iSheetDialog)
        if(doSheetDialog() != noErr)
          ExitToShell();
      break;
  }
}

// ***************************************************************************** doDrawContent

void  doDrawContent(WindowRef windowRef)
{
  SetPortWindowPort(windowRef);
  doDrawMessage(windowRef,windowRef == FrontWindow());
}

// ************************************************************************** doActivateWindow

void  doActivateDeactivate(WindowRef windowRef,Boolean becomingActive)
{
  if(becomingActive)
    doDrawMessage(windowRef,becomingActive);
  else
    doDrawMessage(windowRef,becomingActive);
}

// ***************************************************************************** doControlHit1

void  doControlHit1(WindowRef windowRef,ControlRef controlRef,Point mouseLocation,
                   ControlPartCode controlPartCode)
{
  docStrucHandle docStrucHdl;
  SInt16         controlValue;

  docStrucHdl = (docStrucHandle) (GetWRefCon(windowRef));

  if(controlRef == (*docStrucHdl)->popupTimeZoneRef) 
  {
    TrackControl(controlRef,mouseLocation,(ControlActionUPP) -1);
    controlValue = GetControlValue(controlRef);
    doPopupMenuChoice(windowRef,controlRef,controlValue);
  }
  else if(controlRef == (*docStrucHdl)->scrollbarVertRef) 
  {
    doVertScrollbar(controlPartCode,windowRef,controlRef,mouseLocation);
  }
  else if(controlRef == (*docStrucHdl)->scrollbarHorizRef)
  {
    TrackControl(controlRef,mouseLocation,gActionFunctionHorizUPP);
  }
  else
  {
    if(TrackControl(controlRef,mouseLocation,NULL))
    {
      if(controlRef == (*docStrucHdl)->radiobuttonRedRef ||
         controlRef == (*docStrucHdl)->radiobuttonWhiteRef ||
         controlRef == (*docStrucHdl)->radiobuttonBlueRef)
      {
        doRadioButtons(controlRef,windowRef);
      }
      if(controlRef == (*docStrucHdl)->buttonRef ||
         controlRef == (*docStrucHdl)->buttonDefaultRef)
      {
        doPushButtons(controlRef,windowRef);
      }
    }
  }
}

// ***************************************************************************** doControlHit2

void  doControlHit2(void)
{
  docStrucHandle docStrucHdl;
  ControlRef     controlRef;
  SInt16         controlValue;
  
  docStrucHdl = (docStrucHandle) GetWRefCon(FrontWindow());
  controlRef = (*docStrucHdl)->popupCountryRef;

  controlValue = GetControlValue(controlRef);
  doPopupMenuChoice(FrontWindow(),controlRef,controlValue);
}

// ************************************************************************* doPopupMenuChoice

void  doPopupMenuChoice(WindowRef windowRef,ControlRef controlRef,SInt16 controlValue)
{
  MenuRef menuRef;
  Size    actualSize;

  GetControlData(controlRef,kControlEntireControl,kControlPopupButtonMenuHandleTag,
                 sizeof(menuRef),&menuRef,&actualSize);
  GetMenuItemText(menuRef,controlValue,gCurrentString);    
  doDrawMessage(windowRef,true);
}

// *************************************************************************** doVertScrollbar

void  doVertScrollbar(ControlPartCode controlPartCode,WindowRef windowRef,
                      ControlRef controlRef,Point mouseXY)
{
  Str255 valueString;

  doCopyPString("\pScroll Bar Control Value: ",gCurrentString);

  switch(controlPartCode)
  {
    case kControlIndicatorPart:
      if(TrackControl(controlRef,mouseXY,NULL))
      {
        NumToString((SInt32) GetControlValue(controlRef),valueString);
        doConcatPStrings(gCurrentString,valueString);
        doDrawMessage(windowRef,true);
      }
      break;

    case kControlUpButtonPart:
    case kControlDownButtonPart:
    case kControlPageUpPart:
    case kControlPageDownPart:
      TrackControl(controlRef,mouseXY,gActionFunctionVertUPP);
      break;
  }
}

// ************************************************************************ actionFunctionVert

void  actionFunctionVert(ControlRef controlRef,ControlPartCode controlPartCode)
{
  SInt16    scrollDistance, controlValue;
  Str255    valueString;
  WindowRef windowRef;

  doCopyPString("\pScroll Bar Control Value: ",gCurrentString);

  if(controlPartCode)
  {
    switch(controlPartCode)
    {
      case kControlUpButtonPart:
      case kControlDownButtonPart:
        scrollDistance = 2;
        break;

      case kControlPageUpPart:
      case kControlPageDownPart:
        scrollDistance = 55;
        break;
    }

    if((controlPartCode == kControlDownButtonPart) || 
       (controlPartCode == kControlPageDownPart))
      scrollDistance = -scrollDistance;

    controlValue = GetControlValue(controlRef);
    if(((controlValue == GetControlMaximum(controlRef)) && scrollDistance < 0) || 
       ((controlValue == GetControlMinimum(controlRef)) && scrollDistance > 0))
      return;

    doMoveScrollBox(controlRef,scrollDistance);

    NumToString((SInt32) GetControlValue(controlRef),valueString);
    doConcatPStrings(gCurrentString,valueString);
    windowRef = GetControlOwner(controlRef);
    doDrawMessage(windowRef,true);
  }
}

// *********************************************************************** actionFunctionHoriz

void  actionFunctionHoriz(ControlRef controlRef,ControlPartCode controlPartCode)
{
  SInt16    scrollDistance, controlValue;
  Str255    valueString;
  WindowRef windowRef;

  doCopyPString("\pScroll Bar Control Value: ",gCurrentString);

  if(partCode != kControlNoPart)
  {
    if(controlPartCode != kControlIndicatorPart)
    {
      switch(controlPartCode)
      {
        case kControlUpButtonPart:
        case kControlDownButtonPart:
          scrollDistance = 2;
          break;

        case kControlPageUpPart:
        case kControlPageDownPart:
          scrollDistance = 55;
          break;
      }

      if((controlPartCode == kControlDownButtonPart) || 
         (controlPartCode == kControlPageDownPart))
        scrollDistance = -scrollDistance;

      controlValue = GetControlValue(controlRef);
      if(((controlValue == GetControlMaximum(controlRef)) && scrollDistance < 0) || 
         ((controlValue == GetControlMinimum(controlRef)) && scrollDistance > 0))
        return;

      doMoveScrollBox(controlRef,scrollDistance);
    }

    NumToString((SInt32) GetControlValue(controlRef),valueString);
    doConcatPStrings(gCurrentString,valueString);
    windowRef = GetControlOwner(controlRef);
    doDrawMessage(windowRef,true);
  }
}

// *************************************************************************** doMoveScrollBox

void doMoveScrollBox(ControlRef controlRef,SInt16 scrollDistance)
{
  SInt16 oldControlValue, controlValue, controlMax;

  oldControlValue = GetControlValue(controlRef);
  controlMax = GetControlMaximum(controlRef);

  controlValue = oldControlValue - scrollDistance;

  if(controlValue < 0)
    controlValue = 0;
  else if(controlValue > controlMax)
    controlValue = controlMax;

  SetControlValue(controlRef,controlValue);
}

// **************************************************************************** doRadioButtons

void  doRadioButtons(ControlRef controlRef,WindowRef windowRef)
{  
  docStrucHandle docStrucHdl;

  docStrucHdl = (docStrucHandle) (GetWRefCon(windowRef));

  SetControlValue((*docStrucHdl)->radiobuttonRedRef,kControlRadioButtonUncheckedValue);
  SetControlValue((*docStrucHdl)->radiobuttonWhiteRef,kControlRadioButtonUncheckedValue);
  SetControlValue((*docStrucHdl)->radiobuttonBlueRef,kControlRadioButtonUncheckedValue);
  SetControlValue(controlRef,kControlRadioButtonCheckedValue);
}

// ****************************************************************************** doCheckboxes

void  doCheckboxes(ControlRef controlRef)
{
  SetControlValue(controlRef,!GetControlValue(controlRef));
}

// ***************************************************************************** doPushButtons

void  doPushButtons(ControlRef controlRef,WindowRef windowRef)
{
  docStrucHandle docStrucHdl;

  docStrucHdl = (docStrucHandle) (GetWRefCon(windowRef));

  if(controlRef == (*docStrucHdl)->buttonRef)
  {
    doCopyPString("\pCancel button",gCurrentString);
    doDrawMessage(windowRef,true);
  }
  else if(controlRef == (*docStrucHdl)->buttonDefaultRef)
  {
    doCopyPString("\pDefault button",gCurrentString);
    doDrawMessage(windowRef,true);
  }
}

// ************************************************************************ doAdjustScrollBars

void  doAdjustScrollBars(WindowRef windowRef)
{
  Rect           portRect;
  docStrucHandle docStrucHdl;

  docStrucHdl = (docStrucHandle) (GetWRefCon(windowRef));

  GetWindowPortBounds(windowRef,&portRect);

  HideControl((*docStrucHdl)->scrollbarVertRef);
  HideControl((*docStrucHdl)->scrollbarHorizRef);

  MoveControl((*docStrucHdl)->scrollbarVertRef,portRect.right - kScrollBarWidth,
              portRect.top + 25);
  MoveControl((*docStrucHdl)->scrollbarHorizRef,portRect.left -1,
              portRect.bottom - kScrollBarWidth);

  SizeControl((*docStrucHdl)->scrollbarVertRef,16, portRect.bottom - 39);
  SizeControl((*docStrucHdl)->scrollbarHorizRef, portRect.right - 13,16);

  ShowControl((*docStrucHdl)->scrollbarVertRef);
  ShowControl((*docStrucHdl)->scrollbarHorizRef);
  
  SetControlMaximum((*docStrucHdl)->scrollbarVertRef,portRect.bottom - portRect.top - 25
                    - kScrollBarWidth);
  SetControlMaximum((*docStrucHdl)->scrollbarHorizRef,portRect.right - portRect.left 
                    - kScrollBarWidth);
}

// **************************************************************************** doAdjustCursor

void  doAdjustCursor(WindowRef windowRef)
{
  RgnHandle  myArrowRegion;
  RgnHandle  myIBeamRegion;
  Rect       cursorRect;
  Point      mousePt;
  ControlRef controlRef;
  Cursor     arrow;

  myArrowRegion = NewRgn();
  myIBeamRegion = NewRgn();  
  SetRectRgn(myArrowRegion,-32768,-32768,32767,32767);

  SetRect(&cursorRect,24,250,254,269);

  SetPortWindowPort(windowRef);
  LocalToGlobal(&topLeft(cursorRect));
  LocalToGlobal(&botRight(cursorRect));  

  RectRgn(myIBeamRegion,&cursorRect);
  DiffRgn(myArrowRegion,myIBeamRegion,myArrowRegion);

  GetGlobalMouse(&mousePt);
  GetKeyboardFocus(FrontWindow(),&controlRef);

  if(PtInRgn(mousePt,myIBeamRegion) && controlRef)
    SetCursor(*(GetCursor(iBeamCursor)));
  else
    SetCursor(GetQDGlobalsArrow(&arrow));

  DisposeRgn(myArrowRegion);
  DisposeRgn(myIBeamRegion);
}

// ********************************************************************** doDrawDocumentTyping

void  doDrawDocumentTyping(SInt8 charCode,UInt32 modifiers)
{
  Rect        typingRect  = { 118,128,194,253 };
  Rect        shiftRect   = { 131,181,139,189 };
  Rect        controlRect = { 144,181,152,189 };
  Rect        optionRect  = { 157,181,165,189 };
  Rect        cmdRect     = { 170,181,178,189 };
  Rect        textBoxRect;
  CFStringRef stringRef;

  EraseRect(&typingRect);

  stringRef = CFStringCreateWithPascalString(NULL,"\pShift",kCFStringEncodingMacRoman);
  SetRect(&textBoxRect,142,132,242,147);
  if((modifiers & shiftKey) != 0)  TextMode(srcOr); else TextMode(grayishTextOr);
  DrawThemeTextBox(stringRef,kThemeSmallSystemFont,0,false,&textBoxRect,teJustLeft,NULL);

  stringRef = CFStringCreateWithPascalString(NULL,"\pControl",kCFStringEncodingMacRoman);
  SetRect(&textBoxRect,142,145,242,160);
  if((modifiers & controlKey) != 0)  TextMode(srcOr); else TextMode(grayishTextOr);
  DrawThemeTextBox(stringRef,kThemeSmallSystemFont,0,false,&textBoxRect,teJustLeft,NULL);

  stringRef = CFStringCreateWithPascalString(NULL,"\pOption",kCFStringEncodingMacRoman);
  SetRect(&textBoxRect,142,158,242,173);
  if((modifiers & optionKey) != 0)  TextMode(srcOr); else TextMode(grayishTextOr);
  DrawThemeTextBox(stringRef,kThemeSmallSystemFont,0,false,&textBoxRect,teJustLeft,NULL);

  stringRef = CFStringCreateWithPascalString(NULL,"\pCmd",kCFStringEncodingMacRoman);
  SetRect(&textBoxRect,142,171,242,186);
  if((modifiers & cmdKey) != 0)  TextMode(srcOr); else TextMode(grayishTextOr);
  DrawThemeTextBox(stringRef,kThemeSmallSystemFont,0,false,&textBoxRect,teJustLeft,NULL);

  if(stringRef != NULL)    
    CFRelease(stringRef);

  TextMode(srcOr);
  MoveTo(205,171);
  DrawChar(charCode);    
}

// ***************************************************************************** doDrawMessage

void  doDrawMessage(WindowRef windowRef,Boolean inState)
{
  Rect        portRect, headerRect, textBoxRect;
  CFStringRef stringRef;

  SetPortWindowPort(windowRef);

  GetWindowPortBounds(windowRef,&portRect);

  SetRect(&headerRect,portRect.left - 1,portRect.top - 1,portRect.right + 1,
          portRect.top + 26);
  DrawThemeWindowHeader(&headerRect,inState);

  stringRef = CFStringCreateWithPascalString(NULL,gCurrentString,
                                                 kCFStringEncodingMacRoman);
  SetRect(&textBoxRect,portRect.left,5,portRect.right,25);

  if(inState == kThemeStateActive)
    TextMode(srcOr);
  else
    TextMode(grayishTextOr);

  DrawThemeTextBox(stringRef,kThemeSmallSystemFont,inState,false,&textBoxRect,teJustCenter,
                     NULL);
  if(stringRef != NULL)    
    CFRelease(stringRef);
}

// ************************************************************************** doConcatPStrings

void  doConcatPStrings(Str255 targetString,Str255 appendString)
{
  SInt16 appendLength;

  appendLength = MIN(appendString[0],255 - targetString[0]);

  if(appendLength > 0)
  {
    BlockMoveData(appendString+1,targetString+targetString[0]+1,(SInt32) appendLength);
    targetString[0] += appendLength;
  }
}

// ***************************************************************************** doCopyPString

void  doCopyPString(Str255 sourceString,Str255 destinationString)
{
  SInt16 stringLength;

  stringLength = sourceString[0];
  BlockMove(sourceString + 1,destinationString + 1,stringLength);
  destinationString[0] = stringLength;
}

// *******************************************************************************************
// Dialogs.c
// *******************************************************************************************

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

#include "CarbonEvents2.h"

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

Boolean gSound   = 0;
Boolean gVideo   = 0;
Boolean gEffects = 0;

extern Str255 gCurrentString;

// ****************************************************************************** doSheetAlert

OSStatus  doSheetAlert(void)
{
  AlertStdCFStringAlertParamRec paramRec;
  Str255                        messageText, informativeText;
  CFStringRef                   messageTextCF, informativeTextCF;
  OSStatus                      osError = noErr;
  DialogRef                     dialogRef;

  GetStandardAlertDefaultParams(¶mRec,kStdCFStringAlertVersionOne);
  paramRec.cancelText  = CFSTR("Cancel");
  paramRec.otherText  = CFSTR("Other");

  GetIndString(messageText,rSheetStrings,sAlertSheetMessage);
  GetIndString(informativeText,rSheetStrings,sAlertSheetInformative);
  messageTextCF = CFStringCreateWithPascalString(NULL,messageText,
                                                 CFStringGetSystemEncoding());
  informativeTextCF = CFStringCreateWithPascalString(NULL,informativeText,
                                                     CFStringGetSystemEncoding());

  osError = CreateStandardSheet(kAlertCautionAlert,messageTextCF,informativeTextCF,¶mRec,
                                GetWindowEventTarget(FrontWindow()),&dialogRef);
  if(osError == noErr)
    osError = ShowSheetWindow(GetDialogWindow(dialogRef),FrontWindow());

  if(messageTextCF != NULL)
    CFRelease(messageTextCF);
  if(informativeTextCF != NULL)
    CFRelease(informativeTextCF);

  doAdjustMenus();

  return osError;
}

// ***************************************************************************** doSheetDialog

OSStatus  doSheetDialog(void)
{
  DialogRef     dialogRef;
  WindowRef     windowRef;
  EventTypeSpec sheetEvents[] = { kEventClassMouse, kEventMouseDown };
  ControlRef    controlRef;
  Str255        stringData = "\pBradman";
  OSStatus      osError = noErr;
   
  dialogRef = GetNewDialog(rSheetDialog,NULL,(WindowRef) -1);
  windowRef = GetDialogWindow(dialogRef);
  ChangeWindowAttributes(windowRef,kWindowStandardHandlerAttribute,0);    

  InstallWindowEventHandler(windowRef,doGetSheetHandlerUPP(),GetEventTypeCount(sheetEvents),
                            sheetEvents,0,NULL);
    
  SetDialogDefaultItem(dialogRef,kStdOkItemIndex);

  GetDialogItemAsControl(dialogRef,2,&controlRef);
  SetDialogItemText((Handle) controlRef,stringData);
  SelectDialogItemText(dialogRef,2,0,32767);

  osError = ShowSheetWindow(GetDialogWindow(dialogRef),FrontWindow());

  doAdjustMenus();

  return osError;
}

// ********************************************************************** doGetSheetHandlerUPP

EventHandlerUPP  doGetSheetHandlerUPP(void)
{
  static EventHandlerUPP sheetEventHandlerUPP;

  if(sheetEventHandlerUPP == NULL)
    sheetEventHandlerUPP = NewEventHandlerUPP((EventHandlerProcPtr) sheetEventHandler);

  return sheetEventHandlerUPP;
}

// ************************************************************************* sheetEventHandler

OSStatus  sheetEventHandler(EventHandlerCallRef eventHandlerCallRef,EventRef eventRef,
                             void* userData)
{
  OSStatus        result = eventNotHandledErr;
  UInt32          eventClass;
  UInt32          eventKind;
  Point           mouseLocation;
  ControlRef      controlRef, controlRefOKButton;
  ControlPartCode controlPartCode;
  DialogRef       dialogRef;
  Rect            portRect;

  eventClass = GetEventClass(eventRef);
  eventKind  = GetEventKind(eventRef);

  if(eventClass == kEventClassMouse)
  {
    if(eventKind == kEventMouseDown)
    {
      GetEventParameter(eventRef,kEventParamMouseLocation,typeQDPoint,NULL,
                        sizeof(mouseLocation),NULL,&mouseLocation);

      SetPortWindowPort(FrontWindow());
      GlobalToLocal(&mouseLocation);
      controlRef = FindControlUnderMouse(mouseLocation,FrontWindow(),&controlPartCode);
      if(controlRef)
      {
        dialogRef = GetDialogFromWindow(FrontWindow());
        GetDialogItemAsControl(dialogRef,1,&controlRefOKButton);

        if(controlRef == controlRefOKButton)
        {
          GetDialogItemAsControl(dialogRef,2,&controlRef);
          GetDialogItemText((Handle) controlRef,gCurrentString);

          HideSheetWindow(FrontWindow());
          DisposeDialog(dialogRef);

          GetWindowPortBounds(FrontWindow(),&portRect);
          InvalWindowRect(FrontWindow(),&portRect);

          return noErr;
        }
      }
    }
  }

  return result;
}

// ********************************************************************** doMovableModalDialog

OSStatus  doMovableModalDialog(void)
{
  OSStatus      osError = noErr;
  Rect          rect = { 0,0,167,148 };
  WindowRef     windowRef;
  Rect          pushButtonRect = { 127,63,147,132 };
  ControlRef    controlRef;
  ControlRef    soundControlRef, videoControlRef, effectsControlRef, boxControlRef;
  Rect          checkboxRect = { 37,32,55,124 };
  ControlID     controlID;
  Rect          groupboxRect = { 10,16,113,132 };
  EventTypeSpec dialogEvents[] = { kEventClassControl, kEventControlHit };

  osError = CreateNewWindow(kMovableModalWindowClass,kWindowStandardHandlerAttribute,&rect,
                            &windowRef);
  if(osError == noErr)
  {
    RepositionWindow(windowRef,FrontWindow(),kWindowAlertPositionOnMainScreen);
    SetThemeWindowBackground(windowRef,kThemeBrushDialogBackgroundActive,false);

    CreateRootControl(windowRef,&controlRef);

    CreatePushButtonControl(windowRef,&pushButtonRect,CFSTR("OK"),&controlRef);
    SetWindowDefaultButton(windowRef,controlRef);
    controlID.id = 'okbt';
    SetControlID(controlRef,&controlID);

    CreateCheckBoxControl(windowRef,&checkboxRect,CFSTR("Sound On"),1,false,&soundControlRef);
    controlID.id = 'chb1';
    SetControlID(soundControlRef,&controlID);
    SetControlValue(soundControlRef,gSound);
    
    OffsetRect(&checkboxRect,0,22);
    CreateCheckBoxControl(windowRef,&checkboxRect,CFSTR("Video On"),1,false,&videoControlRef);
    controlID.id = 'chb2';
    SetControlID(videoControlRef,&controlID);
    SetControlValue(videoControlRef,gVideo);
    OffsetRect(&checkboxRect,0,22);
    CreateCheckBoxControl(windowRef,&checkboxRect,CFSTR("Effects On"),1,false,
                          &effectsControlRef);
    controlID.id = 'chb3';
    SetControlID(effectsControlRef,&controlID);
    SetControlValue(effectsControlRef,gEffects);

    CreateGroupBoxControl(windowRef,&groupboxRect,CFSTR("Preferences"),true,&boxControlRef);

    AutoEmbedControl(soundControlRef,windowRef);
    AutoEmbedControl(videoControlRef,windowRef);
    AutoEmbedControl(effectsControlRef,windowRef);

    InstallWindowEventHandler(windowRef,doGetDialogHandlerUPP(),
                              GetEventTypeCount(dialogEvents),dialogEvents,windowRef,NULL);
    ShowWindow(windowRef);
    osError = RunAppModalLoopForWindow(windowRef);
  }
  
  return osError;
}

// ********************************************************************* doGetDialogHandlerUPP

EventHandlerUPP  doGetDialogHandlerUPP(void)
{
  static EventHandlerUPP dialogEventHandlerUPP;

  if(dialogEventHandlerUPP == NULL)
    dialogEventHandlerUPP = NewEventHandlerUPP((EventHandlerProcPtr) dialogEventHandler);

  return dialogEventHandlerUPP;
}

// ************************************************************************ dialogEventHandler

OSStatus  dialogEventHandler(EventHandlerCallRef eventHandlerCallRef,EventRef eventRef,
                             void *userData)
{
  OSStatus   result = eventNotHandledErr;
  UInt32     eventClass;
  UInt32     eventKind;
  ControlRef controlRef;
  ControlID  controlID;

  eventClass = GetEventClass(eventRef);
  eventKind  = GetEventKind(eventRef);

  if(eventClass == kEventClassControl)
  {
    if(eventKind == kEventControlHit)
    {
      GetEventParameter(eventRef,kEventParamDirectObject,typeControlRef,NULL,
                        sizeof(ControlRef),NULL,&controlRef);

      GetControlID(controlRef,&controlID);
      if(controlID.id == 'okbt')
      {
        QuitAppModalLoopForWindow(userData);
        DisposeWindow(userData);
        result = noErr;
      }
      else
      {
        SetControlValue(controlRef,!GetControlValue(controlRef));
        if(controlID.id == 'chb1')
          gSound = GetControlValue(controlRef);
        else if(controlID.id == 'chb2')
          gVideo = GetControlValue(controlRef);
        else if(controlID.id == 'chb3')
          gEffects = GetControlValue(controlRef);
        result = noErr;
      }
    }
  }
  return result;
}

// *******************************************************************************************

Demonstration Program CarbonEvents2 Comments

When this program is run, the user should:

o Open and close windows, and drag, resize, and zoom open windows, noting particularly the size
to which the window zooms in an out.

o Interact with the pop-up menu button, push button and scrollbar controls in open windows.

o Send the application to the background and bring it to the foreground, noting the activation
  and deactivation of the window controls.

o Type into the edit text control, with and without the Shift, Control, Option, and/or Command
  keys held down.  Then choose Document or Edit Text Control to change the target for keyboard
  input.

o Choose the items in the Dialogs menu to open, close, and interact with the movable modal
  dialog and, on Mac OS X only, window-modal (sheet) alerts and window-modal (sheet) dialogs.

o Quit the application by choosing the Quit item in the Mac OS 8/9 File/Mac OS X Application
  menu and using its Command-key equivalent.

The functions relating to controls in this program, including the action functions for the
scroll bars, are similar to those in the demonstration programs Controls1 and Controls2
(Chapter 7).

CarbonEvents2.c

main

If the program is running on OS 8/9, SetMenuItemCommandID is called to assign the command ID
'quit' to the Quit item in the File menu.  (This command is assigned to the Mac OS X Quit item
by default.)  Thus, when the Quit item is chosen on Mac OS 8/9 and Mac OS X, the standard
application event handler will call the default Quit Application Apple event handler
(automatically installed when RunApplicationEventLoop is called) to close down the program.

The call to InstallApplicationEventHandler installs the program's application event handler.

The call to InstallEventLoopTimer installs a timer set to fire at the interval returned by the
call to GetCaretTime, which is converted to event time (seconds) by the macro TicksToEventTime. 
The timer will be used to trigger a call to the function doIdle, within which IdleControls is
called to blink the insertion point caret in the windows' edit text control.  A universal
procedure pointer to doIdle is passed in the inTimerProc parameter.

When RunApplicationEventLoop is called, registered events will be dispatched to the
application.

appEventHandler

appEventHandler is the application's application event handler.  It is a callback function.

Firstly, the calls to GetEventClass and GetEventKind get the event class and type.  The
function then switches on the event class.

If the event class is kEventClassApplication and the event type is kEventAppActivated, the
cursor is set to the arrow cursor.  eventNotHandledErr is returned by the handler, ensuring
that the event will be propagated to the standard application event handler.

If the event class is kEventClassCommand and the event type is kEventProcessCommand,
GetEventParameter is called to extract the specified data from the event.  This data is
returned in a variable of type HICommand.

If an examination of the commandID field of the HICommand structure reveals that the command ID
is 'quit', the handler returns eventNotHandledErr, ensuring that the event will be propagated
to the standard application event handler.  This ensures that the standard handler calls the
default Quit Application Apple event handler.

The menu ID and item number are then extracted from the HICommand structure.  If the command ID
is not 'quit' and the menu ID is that for one of the program's pull-down menus, doMenuChoice is
called to further handle the event.  Because the event is fully handled by the program, noErr
is returned by the handler to ensure that the event is not further propagated.

In this program, each pop-up menu button control is handled in a different manner.  As will be
seen, the second (Country) pop-up menu button control is assigned the command ID 'ctry'
(kPopupCountryID) on creation.  Thus, if a mouse-down occurs in this pop-up menu button, the
standard window event handler calls TrackControl to handle user action, following which the
kEventProcessCommand is dispatched to the application.  Within the application's application
event handler, if the command ID in the HICommand structure's commandID field is 'ctry', the
function doControlHit2 is called, following which noErr is returned by the handler.

If the event class is kEventClassMenu and the event type is kEventMenuEnableItems, the function
doAdjustMenus is called.  The kEventMenuEnableItems event type is dispatched when a mouse-down
occurs in a pull-down menu or a menu-related Command-key equivalent is pressed.

If the event class is kEventClassMouse and the event type is kEventMouseMoved, and if the front
window is of the document kind, the function doAdjustCursor is called to adjust the cursor to
the I-beam shape if it is over an edit text control with keyboard focus, or to the arrow shape
if it is not.

windowEventHandler

windowEventHandler is the application's window event handler.  It is a callback function.

Firstly, the calls to GetEventClass and GetEventKind get the event class and type.  The
function then switches on the event class.

If the event class is kEventClassWindow, GetEventParameter is called to extract the window
reference from the event before a switch on the event type is entered.

If the event type is kEventWindowDrawContent, the function doDrawContent (the window update
function) is called.  (Note that doDrawContent does not call BeginUpdate and EndUpdate because
there is no need to call those functions when responding to kEventWindowDrawContent events.) 
The handler returns eventNotHandledErr, allowing the event to be passed to the standard window
event handler which, in turn, attends to its part of the update process, including drawing the
controls.  

Note that registering the kEventWindowDrawContent event type and responding in this way
obviates the necessity for an event filter (callback) function (which calls the window update
function) for the movable modal dialog.

If the event type is kEventWindowActivated or kEventWindowDeactivated, the function
doActivateDeactivate is called to draw the text in the window header in the appropriate
(activated or deactivated) state.  The handler returns eventNotHandledErr, allowing the event
to be passed to the standard window event handler which, in turn, attends to its part of the
activation/deactivation process, including activating/deactivating the controls.

If the event type is kEventWindowGetIdealSize, the handler responds by calling
SetEventParameter, which sets the height and width to which the window will be zoomed when it
is zoomed out.  The handler returns noErr to defeat further propagation of the event.

If the event type is kEventWindowGetMinimumSize, the handler responds by calling
SetEventParameter, which sets the minimum height and width to which the window can be resized. 
The handler returns noErr to defeat further propagation of the event. 

If the event type is kEventWindowZoomed, the window's port rectangle is erased, the function
doAdjustScrollBars is called to resize and reposition the scroll bars, and the handler returns
noErr.

Since the kWindowLiveResizeAttribute attribute is set on the window, the
kEventWindowBoundsChanged event type will be received continually as the window is being
resized (as opposed to only one kEventWindowBoundsChanged event type being received, when the
mouse button is released, when the kWindowLiveResizeAttribute attribute is not set).  The
function doAdjustScrollBars is continally called to resize and reposition the scroll bars, the
function doDrawMessage is continually called to redraw the window header and associated text,
and the handler returns noErr.

If the event type is kEventWindowClose, the function doCloseWindow is called to dispose of the
window's controls and document structure handle, decrement the global variable holding the
current number of open windows, and disable the Typing Target and Window menus if no windows
will be open when this window is closed.  EventNotHandledErr is returned by the handler to
cause the standard window event handler to dispose of the window.

If the event class is kEventClassControl and the event type is kEventControlClick,
GetEventParameter is called to extract the mouse location, which will be in global coordinates,
from the event.  The mouse coordinates are then converted to local coordinates preparatory to a
call to FindControlUnderMouse.  If there is a control under the mouse cursor, the function
doControlHit1 is called to further handle the event.  When doControlHit1 returns, the handler
returns noErr to defeat further propagation of the event.  (Note that, so far as the first
(Time Zone) pop-up menu button is concerned, this approach to pop-up menu button control
handling differs from that in the demonstration program CarbonEvents1.)

If the event class is kEventClassKeyboard and the event type is kEventRawKeyDown, and if the
current typing target (as chosen in the Typing Target menu) is either the "document" or the
"document" and edit text control combined, GetEventParameter is called twice to get the
character code and the modifier keys that were down (if any), and both of these parameters are
passed to the function doDrawDocumentTyping to draw the character and highlight the modifier
key (if any) indicator in the ("document") Typing group box in the window.  If the current
typing target is the "document" only, the handler returns noErr to prevent the edit text
control receiving the event, otherwise eventNotHandledErr is returned to allow the event to
propagate to the edit text control.

The last block pertains to the window-modal (sheet) alert created by the function doSheetAlert
in Dialogs.c.  When the user clicks in one of the sheet's buttons, the parent window receives
the relevant command ID (kHICommandOK, kHICommandCancel, or kHICommandOther).  The identity of
the button is drawn in the parent window's window header frame.

doNewWindow

After GetNewCWindow creates the window, ChangeWindowAttributes is called to cause the standard
window event handler to be installed on the window.

The next block shows alternative window creation code for windows created programmatically
using CreateNewWindow.  Note that the standard window event handler will be installed because
the kWindowStandardHandlerAttribute is included in the attributes passed in the second
parameter of the CreateNewWindow call.

The call to InstallWindowEventHandler installs the application's window event handler on the
window.  Since more than one window can be opened, the call to InstallWindowEventHandler will
be called whenever a new window is opened.  Accordingly, to prevent a possible memory leak, the
call to doGetHandlerUPP (to get a UPP to the application's window event handler) ensures that
only one routine descriptor will be created regardless of how many windows are opened.  (Recall
from Chapter 5 that universal procedure pointer creation functions always allocate routine
descriptors in memory on Mac OS 8/9, and sometimes allocate routine descriptors in memory on
Mac OS X (depending on whether the application is compiled as a CFM binary or Mach-O binary.)

Note that registering the kEventProcessCommand event (class kEventClassCommand) is required in
order to determine which button is clicked in a window-modal (sheet) alert. 

doCloseWindow

Note that doCloseWindow does not dispose of the window.  As previously stated, the
application's window event handler allows kEventWindowClose events to be passed to the standard
window event handler after doCloseWindow is called.  The standard window handler disposes of
the window.

doGetControls

After the controls have been created, SetControlCommandID is called to assign the command ID
'ctry' (kPopupCountryID) to the second (Country) pop-up menu button control.  As previously
stated, this will cause a kEventProcessCommand event to be dispatched to the application when a
a mouse-down occurs in this pop-up menu button, allowing the application's application event
handler to handle the event.

doIdle

doIdle is called when the event timer fires.  IdleControls is called to cause the insertion
point caret to blink in the edit text control.  (This call is not necessary on Mac OS X because
Mac OS X controls have built-in timers.)

doDrawContent

doDrawContent is the window update function, which is called when the kEventWindowDrawContent
event type is received.  As previously stated, there is no need to call BeginUpdate or
EndUpdate in this function (though there would be, for Mac OS 8/9 only, if the
kEventWindowUpdate event type had been registered rather than the kEventWindowDrawContent event
type).

doControlHit1

doControlHit1 is called from the application's window event handler when the kEventMouseDown
event type is received and a call to FindControlUnderMouse determines that there is a control
under the mouse.  Further processing of mouse-downs in the controls in this program is
identical to that used in in the demonstration program Controls1 (Chapter 7).

Note the differences in this program's approach to detecting and handling mouse-downs in a
pop-up menu button control, as compared with the approach used in the demonstration program
CarbonEvents1.

doControlHit2

DoControlHit2 is called from the application's application event handler when the
kEventProcessCommand event type is received and the commandID field of the HICommand structure
contains the second (Country) pop-up menu button control's command ID.  The control's value is
determined, allowing the chosen menu item's text to be extracted and drawn in the window
header.

Dialogs.c

doSheetAlert

The call to GetStandardAlertDefaultParams initialises a standard CFString alert parameter
structure with default values.  (The defaults are: no Help button; no Cancel button; no Other
button.)  The next two lines cause a Cancel and Other button to be included.

The next block get the message and informative strings to be passed in the call to
CreateStandardSheet, which creates the sheet.  The call to ShowSheetWindow displays the sheet.

Clicks in the sheet's buttons are handled in the parent window's handler (windowEventHandler).

doSheetDialog

The call to GetNewDialog creates the dialog, whose window definition ID is kWindowSheetProc
(1088).  GetDialogWindow gets a reference to the dialog's window object, allowing
ChangeWindowAttributes to be called to cause the standard window event handler to be installed
on the window.

The call to InstallWindowEventHandler installs the handler sheetEventHandler on the dialog. 
Note that the function doGetSheetHandlerUPP is called to get the universal procedure pointer to
the handler passed in the second parameter of the InstallWindowEventHandler call.

SetDialogDefaultItem establishes the single push button item in the dialog as the default
button.  The next block sets some initial text in the dialog's edit text item and selects that
text.

The call to ShowSheetWindow displays the sheet.

doGetSheetHandlerUPP

doGetSheetHandler serves the same purpose for window-modal (sheet) dialogs as does
doGetHandlerUPP (see above) for document windows.

sheetEventHandler

sheetEventHandler is the event handler for window-modal (sheet) dialogs.  It is a callback
function.

If the kEventMouseDown event type is received, GetEventParameter is called to get the mouse
location, which is then converted to the local coordinates required by FindControlUnderMouse. 
If the call to FindControlUnderMouse reveals that there is a control under the mouse,
GetDialogFromWindow is called to get a reference to the dialog, allowing GetDialogItemAsControl
to get a reference to the first item in the dialog's item list (the OK push button).

If the control clicked is the OK push button, the current text in the edit text item is
extracted for display in the parent window's window header frame, HideSheetWindow is called to
hide the sheet and DisposeDialog disposes of the sheet and releases all related memory.

if the mouse click was in the edit text item, eventNotHandledErr is returned so the event can
be handled by the standard handler.

doMovableModalDialog

doMovableModalDialog creates a movable modal dialog containing three checkbox controls, a group
box control and an OK push button control.

CreateNewWindow creates an initially invisible window of class kMovableModalWindowClass with
the standard window handler installed.  The RepositionWindow call ensures that the dialog will
appear in the alert position on the main screen.  SetThemeWindowBackground sets the dialog's
background colour/pattern to the correct colour pattern for dialogs.

CreateRootControl creates a root control for the window, ensuring that activation/deactivation
of the controls will be automatic.

The next three blocks create the dialog's controls.  In the case of the OK push button and
checkbox controls, a control ID is assigned to each control.  The initial value of the checkbox
controls is set to 0.

InstallWindowEventHandler installs the event handler dialogEventHandler on the window.  With
the dialog fully prepared, ShowWindow displays the dialog.

RunAppModalLoopForWindow is the Carbon event model equivalent of the Classic event model's
ModalDialog.  It will exit when QuitAppModalLoopForWindow is called in the dialog's event
handler.  Although it will block until the modal loop ends, your application's other handlers
will still be called.

RunAppModalLoopForWindow attends to the menu deactivation usually associated with the display
of a movable modal dialog.

dialogEventHandler

dialogEventHandler is the event handler for the movable modal dialog.  It is a callback
function.

If the kEventControlHit event type is received, GetEventParameter is called to get a reference
to the control, allowing the call to GetControlID to get the control's ID.

If the control is the OK push button, the QuitAppModalLoopForWindow call terminates the modal
loop and restores menu activation/deactivation status to that which obtained prior to the call
to RunAppModalLoopForWindow.

If the control is one of the checkbox controls, the current value of the control is flipped and
the new value is assigned to the relevant global variable which keeps track of the control
values between successive invocations of the dialog.
 
AAPL
$97.19
Apple Inc.
+2.47
MSFT
$44.87
Microsoft Corpora
+0.04
GOOG
$595.98
Google Inc.
+1.24

MacTech Search:
Community Search:

Software Updates via MacUpdate

Firefox 31.0 - Fast, safe Web browser. (...
Firefox for Mac offers a fast, safe Web browsing experience. Browse quickly, securely, and effortlessly. With its industry-leading features, Firefox is the choice of Web development professionals... Read more
Little Snitch 3.3.3 - Alerts you to outg...
Little Snitch gives you control over your private outgoing data. Track background activityAs soon as your computer connects to the Internet, applications often have permission to send any... Read more
Thunderbird 31.0 - Email client from Moz...
As of July 2012, Thunderbird has transitioned to a new governance model, with new features being developed by the broader free software and open source community, and security fixes and improvements... Read more
Together 3.2 - Store and organize all of...
Together helps you organize your Mac, giving you the ability to store, edit and preview your files in a single clean, uncluttered interface. Smart storage. With simple drag-and-drop functionality,... Read more
Cyberduck 4.5 - FTP and SFTP browser. (F...
Cyberduck is a robust FTP/FTP-TLS/SFTP browser for the Mac whose lack of visual clutter and cleverly intuitive features make it easy to use. Support for external editors and system technologies such... Read more
iExplorer 3.4 - View and transfer all th...
iExplorer is an iPhone browser for Mac lets you view the files on your iOS device. By using a drag and drop interface, you can quickly copy files and folders between your Mac and your iPhone or... Read more
Airmail 1.4 - Powerful, minimal email cl...
Airmail is a powerful, minimal mail client.It was designed to retain the same experience with a single or multiple accounts and provide a quick, modern and easy-to-use user experience. Airmail... Read more
Macs Fan Control 1.1.12 - Monitor and co...
Macs Fan Control allows you to monitor and control almost any aspect of your computer's fans, with support for controlling fan speed, temperature sensors pane, menu-bar icon, and autostart with... Read more
A Better Finder Rename 9.37 - File, phot...
A Better Finder Rename is the most complete renaming solution available on the market today. That's why, since 1996, tens of thousands of hobbyists, professionals and businesses depend on A Better... Read more
MacBook Air EFI Firmware Update 2.9 - Fo...
MacBook Air EFI Firmware Update is recommended for MacBook Air (Mid 2011) models. This update addresses an issue where systems may take longer to wake from sleep than expected and fixes a rare issue... Read more

Latest Forum Discussions

See All

Together for iOS (Productivity)
Together for iOS 1.0 Device: iOS Universal Category: Productivity Price: $9.99, Version: 1.0 (iTunes) Description: Together is an app for keeping things in one place. Notes, documents, images, movies, sounds, web pages and bookmarks... | Read more »
The Phantom PI Mission Apparition (Game...
The Phantom PI Mission Apparition 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: ** Release sale! 50% off for a limited time! ** The Phantom PI Mission Apparition is a spooky, puzzly, rock’... | Read more »
The Great Prank War (Games)
The Great Prank War 1.0.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0.0 (iTunes) Description: Help Mordecai, Rigby, Muscle Man and Skips take the park back from Gene and his goons with a plethora of prank-related... | Read more »
Teenage Mutant Ninja Turtles (Games)
Teenage Mutant Ninja Turtles 1.0.0 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0.0 (iTunes) Description: Download the all new Teenage Mutant Ninja Turtles Official Movie Game! | Read more »
Dream Revenant (Games)
Dream Revenant 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: EXCLUSIVE LAUNCH PRICE ! Dream Revenant is at $1.99 for a limited time ! | Read more »
Traps n' Gemstones (Games)
Traps n' Gemstones 1.00 Device: iOS Universal Category: Games Price: $2.99, Version: 1.00 (iTunes) Description: LAUNCH SALE! 40% off, JULY ONLY! TRAPS N' GEMSTONES is an adventurous platform game, among gamers typically known as the... | Read more »
Soccer Physics (Games)
Soccer Physics 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: One-button soccer game! So dumb it's fun. "Soccer Physics is probably the funniest football game you'll play on iOS" —... | Read more »
Ex-Angry Birds Developers Release Monsu...
Ex-Angry Birds Developers Release Monsu Teaser Trailer Posted by Jennifer Allen on July 23rd, 2014 [ permalink ] Finnish developer Boomlagoon has released a teaser trailer of their forthcoming side-scrolling action platformer, | Read more »
Dragons: Rise of Berk – Tips, Tricks, an...
Things have changed in Berk, the fantasy Viking village of DreamWorks’ How to Train Your Dragon series. Dragons and Vikings, once mortal enemies, now must learn to live together in peace. Dragons: Rise of Berk lets players manage dragon-Viking... | Read more »
Cowabunga! Teenage Mutant Ninja Turtles:...
Cowabunga! Teenage Mutant Ninja Turtles: Rooftop Run Is Currently Free Posted by Jennifer Allen on July 23rd, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »

Price Scanner via MacPrices.net

What Should Apple’s Next MacBook Priority Be;...
Stabley Times’ Phil Moore says that after expanding its iMac lineup with a new low end model, Apple’s next Mac hardware decision will be how it wants to approach expanding its MacBook lineup as well... Read more
ArtRage For iPhone Painting App Free During C...
ArtRage for iPhone is currently being offered for free (regularly $1.99) during Comic-Con San Diego #SDCC, July 24-27, in celebration of the upcoming ArtRage 4.5 and other 64-bit versions of the... Read more
With The Apple/IBM Alliance, Is The iPad Now...
Almost since the iPad was rolled out in 2010, and especially after Apple made a 128 GB storage configuration available in 2012, there’s been debate over whether the iPad is a serious tool for... Read more
MacBook Airs on sale starting at $799, free s...
B&H Photo has the new 2014 MacBook Airs on sale for up to $100 off MSRP for a limited time. Shipping is free, and B&H charges NY sales tax only. They also include free copies of Parallels... Read more
Apple 27″ Thunderbolt Display (refurbished) a...
The Apple Store has Apple Certified Refurbished 27″ Thunderbolt Displays available for $799 including free shipping. That’s $200 off the cost of new models. Read more
WaterField Designs Unveils Cycling Ride Pouch...
High end computer case and bag maker WaterField Designs of San Francisco now enters the cycling market with the introduction of the Cycling Ride Pouch – an upscale toolkit with a scratch-free iPhone... Read more
Kingston Digital Ships Large Capacity Near 1T...
Kingston Digital, Inc., the Flash memory affiliate of Kingston Technology Company, Inc.,has announced its latest addition to the SSDNow V300 series, the V310. The Kingston SSDNow V310 solid-state... Read more
Apple’s Fiscal Third Quarter Results; Record...
Apple has announced financial results for its fiscal 2014 third quarter ended June 28, 2014, racking up quarterly revenue of $37.4 billion and quarterly net profit of $7.7 billion, or $1.28 per... Read more
15-inch 2.0GHz MacBook Pro Retina on sale for...
B&H Photo has the 15″ 2.0GHz Retina MacBook Pro on sale for $1829 including free shipping plus NY sales tax only. Their price is $170 off MSRP. B&H will also include free copies of Parallels... Read more
Apple restocks refurbished Mac minis for up t...
The Apple Store has restocked Apple Certified Refurbished Mac minis for up to $150 off the cost of new models. Apple’s one-year warranty is included with each mini, and shipping is free: - 2.5GHz Mac... Read more

Jobs Board

Sr Software Lead Engineer, *Apple* Online S...
Sr Software Lead Engineer, Apple Online Store Publishing Systems Keywords: Company: Apple Job Code: E3PCAK8MgYYkw Location (City or ZIP): Santa Clara Status: Full Read more
Senior Interaction Designer, *Apple* Online...
**Job Summary** Apple is looking for a hands on Senior…will be a key player in designing for the Apple Online Store. The ideal designer will have a Read more
*Apple* Sales Chat Rep - Apple (United State...
…is looking for motivated, outgoing, and tech savvy individuals who want to offer Apple Customers an unparalleled customer experience over chat. At Apple , we believe Read more
Mac Expert - *Apple* Online Store Mexico -...
…MUST be fluent in English and Spanish to be considered for this position At Apple , we believe that hard work, a fun environment, creativity and innovation fuel the Read more
*Apple* Industrial Design CAD Sculptor - App...
**Job Summary** The Apple Industrial Design team is looking for a CAD sculptor/Digital 3D modeler to create high quality CAD models used in the industrial design process Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.