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.
 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

The Legend of Heroes: Trails of Cold Ste...
I adore game series that have connecting lore and stories, which of course means the Legend of Heroes is very dear to me, Trails lore has been building for two decades. Excitedly, the next stage is upon us as Userjoy has announced the upcoming... | Read more »
Go from lowly lizard to wicked Wyvern in...
Do you like questing, and do you like dragons? If not then boy is this not the announcement for you, as Loongcheer Game has unveiled Quest Dragon: Idle Mobile Game. Yes, it is amazing Square Enix hasn’t sued them for copyright infringement, but... | Read more »
Aether Gazer unveils Chapter 16 of its m...
After a bit of maintenance, Aether Gazer has released Chapter 16 of its main storyline, titled Night Parade of the Beasts. This big update brings a new character, a special outfit, some special limited-time events, and, of course, an engaging... | Read more »
Challenge those pesky wyverns to a dance...
After recently having you do battle against your foes by wildly flailing Hello Kitty and friends at them, GungHo Online has whipped out another surprising collaboration for Puzzle & Dragons. It is now time to beat your opponents by cha-cha... | Read more »
Pack a magnifying glass and practice you...
Somehow it has already been a year since Torchlight: Infinite launched, and XD Games is celebrating by blending in what sounds like a truly fantastic new update. Fans of Cthulhu rejoice, as Whispering Mist brings some horror elements, and tests... | Read more »
Summon your guild and prepare for war in...
Netmarble is making some pretty big moves with their latest update for Seven Knights Idle Adventure, with a bunch of interesting additions. Two new heroes enter the battle, there are events and bosses abound, and perhaps most interesting, a huge... | Read more »
Make the passage of time your plaything...
While some of us are still waiting for a chance to get our hands on Ash Prime - yes, don’t remind me I could currently buy him this month I’m barely hanging on - Digital Extremes has announced its next anticipated Prime Form for Warframe. Starting... | Read more »
If you can find it and fit through the d...
The holy trinity of amazing company names have come together, to release their equally amazing and adorable mobile game, Hamster Inn. Published by HyperBeard Games, and co-developed by Mum Not Proud and Little Sasquatch Studios, it's time to... | Read more »
Amikin Survival opens for pre-orders on...
Join me on the wonderful trip down the inspiration rabbit hole; much as Palworld seemingly “borrowed” many aspects from the hit Pokemon franchise, it is time for the heavily armed animal survival to also spawn some illegitimate children as Helio... | Read more »
PUBG Mobile teams up with global phenome...
Since launching in 2019, SpyxFamily has exploded to damn near catastrophic popularity, so it was only a matter of time before a mobile game snapped up a collaboration. Enter PUBG Mobile. Until May 12th, players will be able to collect a host of... | Read more »

Price Scanner via MacPrices.net

Limited-time sale: 13-inch M3 MacBook Airs fo...
Amazon has the base 13″ M3 MacBook Air (8GB/256GB) in stock and on sale for a limited time for $989 shipped. That’s $110 off MSRP, and it’s the lowest price we’ve seen so far for an M3-powered... Read more
13-inch M2 MacBook Airs in stock today at App...
Apple has 13″ M2 MacBook Airs available for only $849 today in their Certified Refurbished store. These are the cheapest M2-powered MacBooks for sale at Apple. Apple’s one-year warranty is included,... Read more
New today at Apple: Series 9 Watches availabl...
Apple is now offering Certified Refurbished Apple Watch Series 9 models on their online store for up to $80 off MSRP, starting at $339. Each Watch includes Apple’s standard one-year warranty, a new... Read more
The latest Apple iPhone deals from wireless c...
We’ve updated our iPhone Price Tracker with the latest carrier deals on Apple’s iPhone 15 family of smartphones as well as previous models including the iPhone 14, 13, 12, 11, and SE. Use our price... Read more
Boost Mobile will sell you an iPhone 11 for $...
Boost Mobile, an MVNO using AT&T and T-Mobile’s networks, is offering an iPhone 11 for $149.99 when purchased with their $40 Unlimited service plan (12GB of premium data). No trade-in is required... Read more
Free iPhone 15 plus Unlimited service for $60...
Boost Infinite, part of MVNO Boost Mobile using AT&T and T-Mobile’s networks, is offering a free 128GB iPhone 15 for $60 per month including their Unlimited service plan (30GB of premium data).... Read more
$300 off any new iPhone with service at Red P...
Red Pocket Mobile has new Apple iPhones on sale for $300 off MSRP when you switch and open up a new line of service. Red Pocket Mobile is a nationwide MVNO using all the major wireless carrier... Read more
Clearance 13-inch M1 MacBook Airs available a...
Apple has clearance 13″ M1 MacBook Airs, Certified Refurbished, available for $759 for 8-Core CPU/7-Core GPU/256GB models and $929 for 8-Core CPU/8-Core GPU/512GB models. Apple’s one-year warranty is... Read more
Updated Apple MacBook Price Trackers
Our Apple award-winning MacBook Price Trackers are continually updated with the latest information on prices, bundles, and availability for 16″ and 14″ MacBook Pros along with 13″ and 15″ MacBook... Read more
Every model of Apple’s 13-inch M3 MacBook Air...
Best Buy has Apple 13″ MacBook Airs with M3 CPUs in stock and on sale today for $100 off MSRP. Prices start at $999. Their prices are the lowest currently available for new 13″ M3 MacBook Airs among... Read more

Jobs Board

Solutions Engineer - *Apple* - SHI (United...
**Job Summary** An Apple Solution Engineer's primary role is tosupport SHI customers in their efforts to select, deploy, and manage Apple operating systems and Read more
DMR Technician - *Apple* /iOS Systems - Haml...
…relevant point-of-need technology self-help aids are available as appropriate. ** Apple Systems Administration** **:** Develops solutions for supporting, deploying, Read more
Omnichannel Associate - *Apple* Blossom Mal...
Omnichannel Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Operations Associate - *Apple* Blossom Mall...
Operations Associate - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Read more
Cashier - *Apple* Blossom Mall - JCPenney (...
Cashier - Apple Blossom Mall Location:Winchester, VA, United States (https://jobs.jcp.com/jobs/location/191170/winchester-va-united-states) - Apple Blossom Mall Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.