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
$524.94
Apple Inc.
+5.93
MSFT
$40.01
Microsoft Corpora
-0.39
GOOG
$536.10
Google Inc.
-20.44

MacTech Search:
Community Search:

Software Updates via MacUpdate

VMware Fusion 6.0.3 - Run Windows apps a...
VMware Fusion allows you to create a Virtual Machine on your Mac and run Windows (including Windows 8.1) and Windows software on your Mac. Run your favorite Windows applications alongside Mac... Read more
Tweetbot 1.5.1 - Popular iOS twitter cli...
Tweetbot is a full-featured OS X Twitter client with a lot of personality. Whether it's the meticulously-crafted interface, sounds and animation, or features like multiple timelines and column views... Read more
Mac DVDRipper Pro 4.1.7 - Copy, backup,...
Mac DVDRipper Pro is the DVD backup solution that lets you protect your DVDs from scratches, save your batteries by reading your movies from your hard disk, manage your collection with just a few... Read more
PDFpenPro 6.2 - Advanced PDF toolkit for...
PDFpenPro allows users to edit PDF's easily. Add text, images and signatures. Fill out PDF forms. Merge or split PDF documents. Reorder and delete pages. Even correct text and edit graphics! Create... Read more
PDFpen 6.2 - Edit and annotate PDFs with...
PDFpen allows users to easily edit PDF's. Add text, images and signatures. Fill out PDF forms. Merge or split PDF documents. Reorder and delete pages. Even correct text and edit graphics! Features... Read more
Monolingual 1.5.9 - Remove unwanted OS X...
Monolingual is a program for removing unnecesary language resources from OS X, in order to reclaim several hundred megabytes of disk space. It requires a 64-bit capable Intel-based Mac and at least... Read more
Maya 2015 - Professional 3D modeling and...
Maya is an award-winning software and powerful, integrated 3D modeling, animation, visual effects, and rendering solution. Because Maya is based on an open architecture, all your work can be scripted... Read more
Starcraft II: Wings of Liberty 1.1.1.180...
Download the patch by launching the Starcraft II game and downloading it through the Battle.net connection within the app. Starcraft II: Wings of Liberty is a strategy game played in real-time. You... Read more
Sibelius 7.5.0 - Music notation solution...
Sibelius is the world's best-selling music notation software for Mac. It is as intuitive to use as a pen, yet so powerful that it does most things in less than the blink of an eye. The demo includes... Read more
Typinator 5.9 - Speedy and reliable text...
Typinator turbo-charges your typing productivity. Type a little. Typinator does the rest. We've all faced projects that require repetitive typing tasks. With Typinator, you can store commonly used... Read more

Latest Forum Discussions

See All

Have a Special Dead Trigger 2 Easter Bas...
Have a Special Dead Trigger 2 Easter Basket Full of Goodies, Courtesy of Madfinger Games Posted by Rob Rich on April 18th, 2014 [ permalink ] Dead Trigger 2 | Read more »
Almost All of Playdek’s Library is on Sa...
Almost All of Playdek’s Library is on Sale Right Now, and You Should Check it Out Posted by Rob Rich on April 18th, 2014 [ permalink ] Playdek has released quite a few great iOS ports of board and card games over the years, and now most of them... | Read more »
Zynga Launches Brand New Farmville Exper...
Zynga Launches Brand New Farmville Experience with Farmville 2: Country Escape Posted by Tre Lawrence on April 18th, 2014 [ permalink ] | Read more »
David. Review
David. Review By Cata Modorcea on April 18th, 2014 Our Rating: :: MINIMALISTIC IN A DIFFERENT WAYUniversal App - Designed for iPhone and iPad David is a minimalistic game wrapped inside of a soothing atmosphere in which the hero... | Read more »
Eyefi Unveils New Eyefi Cloud Service Th...
Eyefi Unveils New Eyefi Cloud Service That Allows Users to Share Media Across Personal Devices Posted by Tre Lawrence on April 18th, 2014 [ permalink ] | Read more »
Tales from the Dragon Mountain: The Lair...
Tales from the Dragon Mountain: The Lair Review By Jennifer Allen on April 18th, 2014 Our Rating: :: STEADY ADVENTURINGiPad Only App - Designed for the iPad Treading a safe path, Tales from the Dragon Mountain: The Lair is a... | Read more »
Yahoo Updates Flickr App with Advanced E...
Yahoo Updates Flickr App with Advanced Editing Features and More Posted by Tre Lawrence on April 18th, 2014 [ permalink ] | Read more »
My Incredible Body - A Kid's App to...
My Incredible Body - A Kid's App to Learn about the Human Body 1.1.00 Device: iOS Universal Category: Education Price: $2.99, Version: 1.1.00 (iTunes) Description: Wouldn’t it be cool to look inside yourself and see what was going on... | Read more »
Trials Frontier Review
Trials Frontier Review By Carter Dotson on April 18th, 2014 Our Rating: :: A ROUGH LANDINGUniversal App - Designed for iPhone and iPad Trials Frontier finally brings the famed stunt racing franchise to mobile, but how much does its... | Read more »
Evernote Business Notebook by Moleskin I...
Evernote Business Notebook by Moleskin Introduced – Support Available in Evernote for iOS Posted by Tre Lawrence on April 18th, 2014 [ permalink ] | Read more »

Price Scanner via MacPrices.net

Free HopTo 2.2 Helps Enhance Your Productivit...
The HopTo app helps you do more on your iPad by providing more and easier adaccess to files and documents. Version 2.2 adds Egnyte and HopTo’s Mac OSX File Connector. If you already have the hopTo... Read more
National Distracted Driving Awareness Month:...
As the country recognizes National Distracted Driving Awareness Month, Sprint is reminding wireless consumers to focus on driving while behind the wheel, to not text or email while driving, and to... Read more
13-inch 2.4GHz Retina MacBook Pro available f...
Abt has the 13″ 2.4GHz 128GB Retina MacBook Pro available for $1229 including free shipping. Their price is $70 off MSRP. Read more
iMacs on sale for up to $160 off MSRP this we...
Best Buy has iMacs on sale for up to $160 off MSRP for a limited time. Choose free home shipping or free instant local store pickup (if available). Prices are valid for online orders only, in-store... Read more
iPad Airs on sale this weekend for up to $100...
Best Buy has WiFi iPad Airs on sale for $50 off MSRP and WiFi + Cellular iPad Airs on sale for $100 off MSRP on their online store for a limited time, with prices now starting at $449. Choose free... Read more
Apple restocks refurbished Mac minis starting...
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
Hyundai Brings Apple CarPlay To The 2015 Sona...
Hyundai Motor America has announced it will bring Apple CarPlay functionality to the 2015 Sonata. CarPlay is pitched as a smarter, safer and easier way to use iPhone in the car and gives iPhone users... Read more
Updated iPads Coming Sooner Than We Had Thoug...
MacRumors, cites KGI securities analyst Ming Chi Kuo, well-respected as an Apple product prognisticator, saying that Apple will introduce an upgraded iPad Air and iPad mini in 2014/Q3, meaning the... Read more
Toshiba Unveils New High And Low End Laptop M...
Toshiba has announced new laptop models covering both the high-end and low-end of the notebook computer spectrum. Toshiba 4K Ultra HD Laptop Toshiba’s new Satellite P55t features one of the world’s... Read more
Save up to $270 with Apple refurbished 13-inc...
The Apple Store has Apple Certified Refurbished October 2013 13″ Retina MacBook Pros available starting at $1099, with models up to $270 off MSRP. Apple’s one-year warranty is standard, and shipping... Read more

Jobs Board

*Apple* Automotive Parts Department position...
Apple Automotive is one of the fastest growing dealer…and it shows. Consider making the switch to the Apple Automotive Group today! At Apple Automotive, we Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Retail - Manager - Holyoke - Apple I...
Job Summary Keeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, you’re a master of them all. In the store’s fast-paced, Read more
*Apple* Retail - Manager - Apple (United Sta...
Job SummaryKeeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, you're a master of them all. In the store's fast-paced, dynamic Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.