Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
MenusStuff.c
/* |
File: MenusStuff.c |
Contains: Handles the application's menus |
Written by: Chris White |
Copyright: Copyright © 1995-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
8/5/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#include <Menus.h> |
#include <Windows.h> |
#include <Dialogs.h> |
#include <TextUtils.h> |
#include <Devices.h> |
#include <CodeFragments.h> |
#ifndef __MENUSTUFF__ |
#include "MenuStuff.h" |
#endif |
#include "DialogStuff.h" |
#ifndef __STREAMS__ |
#include "Streams.h" |
#endif |
#ifndef __UTILITIES__ |
#include "Utilities.h" |
#endif |
#ifndef __PROTOTYPES__ |
#include "Prototypes.h" |
#endif |
static Boolean EnableFileCommands ( WindowRef frontWindow ); |
static Boolean EnableEditCommands ( WindowRef frontWindow ); |
static Boolean EnableFragmentCommands ( WindowRef frontWindow ); |
static void SetItemEnable ( MenuHandle theMenu, int16 theItem, Boolean bEnabled ); |
static void DoAppleCmds ( int16 theItem ); |
static void DoFileCmds ( int16 theItem ); |
static void DoFragmentCmds ( int16 theItem ); |
static void DoGetInfo ( WindowRef theWindow ); |
static void DoDisplayExports ( WindowRef theWindow ); |
static void DoMoveFragments ( WindowRef theWindow ); |
static void DoCopyFragments ( WindowRef theWindow ); |
static void DoRemoveFragments ( WindowRef theWindow ); |
static OSErr PackageWindowData ( WindowRef theWindow, Ptr* theData ); |
void MenuDispatch ( int32 menuResult ) |
{ |
int16 theMenu = (menuResult >> 16); // menu selected |
int16 theItem = (menuResult & 0x0000FFFF); // item selected |
switch (theMenu) |
{ |
case kAppleMenu: |
DoAppleCmds ( theItem ); |
break; |
case kFileMenu: |
DoFileCmds ( theItem ); |
break; |
case kEditMenu: |
SystemEdit ( theItem - 1 ); |
break; |
case kFragmentMenu: |
DoFragmentCmds ( theItem ); |
break; |
} |
HiliteMenu ( 0 ); // un-hilite selected menu |
return; |
} // MenuDispatch |
void AdjustMenus ( void ) |
{ |
Boolean bRedraw = false; |
WindowRef frontWindow; |
frontWindow = FrontWindow ( ); |
if ( EnableFileCommands ( frontWindow ) ) |
bRedraw = true; |
if ( EnableEditCommands ( frontWindow ) ) |
bRedraw = true; |
if ( EnableFragmentCommands ( frontWindow ) ) |
bRedraw = true; |
if ( bRedraw ) |
DrawMenuBar ( ); |
return; |
} // AdjustMenus |
static Boolean EnableFileCommands ( WindowRef frontWindow ) |
{ |
static Boolean bIsEnabled = true; |
Boolean bHasDialog = false; |
Boolean bUpdate = false; |
MenuHandle theMenu = GetMenuHandle ( kFileMenu ); |
bHasDialog = frontWindow && GetWindowKind ( frontWindow ) == dialogKind; |
if ( bIsEnabled == bHasDialog ) // Or bIsEnabled != !bHasDialog |
{ |
SetItemEnable ( theMenu, 0, !bHasDialog ); |
bIsEnabled = !bHasDialog; |
bUpdate = true; |
} |
SetItemEnable ( theMenu, cNew, !bHasDialog ); |
SetItemEnable ( theMenu, cOpen, !bHasDialog ); |
SetItemEnable ( theMenu, cClose, frontWindow && GetWindowGoAwayFlag ( frontWindow ) ); |
SetItemEnable ( theMenu, cSave, frontWindow && IsDocumentDirty ( frontWindow ) ); |
SetItemEnable ( theMenu, cSaveAs, frontWindow && GetWindowType ( frontWindow ) == kDocumentWindowType ); |
SetItemEnable ( theMenu, cQuit, !bHasDialog ); |
return bUpdate; |
} // EnableFileCommands |
static Boolean EnableEditCommands ( WindowRef frontWindow ) |
{ |
#pragma unused(frontWindow) |
static Boolean bIsEnabled = true; |
Boolean bEnable = false; |
MenuHandle theMenu = GetMenuHandle ( kEditMenu ); |
bEnable = false; |
if ( bIsEnabled != bEnable ) |
{ |
SetItemEnable ( theMenu, 0, bEnable ); |
bIsEnabled = bEnable; |
return true; |
} |
return false; |
} // EnableEditCommands |
static Boolean EnableFragmentCommands ( WindowRef frontWindow ) |
{ |
static Boolean bIsEnabled = true; |
Boolean bHasSelection = false; |
Boolean bHasMultiSelection = false; |
MenuHandle theMenu = GetMenuHandle ( kFragmentMenu ); |
if ( frontWindow && GetWindowType ( frontWindow ) == kDocumentWindowType ) |
{ |
int16 theIndex = 0; |
tWindowInfoPtr theInfo; |
theInfo = (tWindowInfoPtr) GetWRefCon ( frontWindow ); |
if ( theInfo->listRef ) |
{ |
bHasSelection = GetSelection ( theInfo->listRef, &theIndex ); |
theIndex++; |
bHasMultiSelection = GetSelection ( theInfo->listRef, &theIndex ); |
} |
} |
if ( bIsEnabled != bHasSelection ) |
{ |
if ( bHasSelection ) |
{ |
Boolean bHasMultiWindows; |
// Always better to assign true or false so that if it's checked |
// against the constants, it'll still work. If we simply cast the |
// result of GetNextWindow to a boolean, a true value may not be |
// exactly 1. If we then use Òif ( bHasMultiWindows == true )Ó |
// the evaluation will not be what we wanted. Further, because |
// only 1 byte is assigned to the boolean, we could miss all the |
// important bytes (those non-zero ones) so that bHasMultiWindows |
// turned out to be false. |
bHasMultiWindows = (GetNextWindow ( frontWindow )) ? true : false; |
SetItemEnable ( theMenu, 0, true ); |
SetItemEnable ( theMenu, cGetInfo, !bHasMultiSelection ); |
SetItemEnable ( theMenu, cExports, !bHasMultiSelection ); |
SetItemEnable ( theMenu, cMoveTo, bHasMultiWindows ); |
SetItemEnable ( theMenu, cCopyTo, bHasMultiWindows ); |
SetItemEnable ( theMenu, cRemove, true ); |
} |
else |
SetItemEnable ( theMenu, 0, false ); |
bIsEnabled = bHasSelection; |
return true; |
} |
return false; |
} // EnableFragmentCommands |
static void SetItemEnable ( MenuHandle theMenu, int16 theItem, Boolean bEnabled ) |
{ |
if ( theMenu ) |
{ |
if ( bEnabled ) |
EnableItem ( theMenu, theItem ); |
else |
DisableItem ( theMenu, theItem ); |
} |
return; |
} // SetItemEnable |
static void DoAppleCmds ( int16 theItem ) |
{ |
Str255 name; // string for DA name |
switch ( theItem ) |
{ |
case cAbout: |
Alert ( kAboutDialog, nil ); |
break; |
default: |
GetMenuItemText ( GetMenuHandle ( kAppleMenu ), theItem, (StringPtr) &name ); |
OpenDeskAcc( (StringPtr) &name ); |
break; |
} |
} |
static void DoFileCmds ( int16 theItem ) |
{ |
switch ( theItem ) |
{ |
case cNew: |
DoNewDocument ( ); |
break; |
case cOpen: |
DoOpenDocument ( ); |
break; |
case cClose: |
DoCloseDocument ( FrontWindow ( ) ); |
break; |
case cSave: |
DoSave ( FrontWindow ( ) ); |
break; |
case cSaveAs: |
DoSaveAs ( FrontWindow ( ) ); |
break; |
case cQuit: |
// Tell the application immediatly. It |
gQuit = true; // might need to know. |
if ( DoCloseAllDocuments ( ) ) // Did the user cancel? |
gQuit = false; |
break; |
} |
return; |
} // DoFileCmds |
static void DoFragmentCmds ( int16 theItem ) |
{ |
WindowRef frontWindow = FrontWindow ( ); |
switch ( theItem ) |
{ |
case cGetInfo: |
DoGetInfo ( frontWindow ); |
break; |
case cExports: |
DoDisplayExports ( frontWindow ); |
break; |
case cMoveTo: |
DoMoveFragments ( frontWindow ); |
break; |
case cCopyTo: |
DoCopyFragments ( frontWindow ); |
break; |
case cRemove: |
DoRemoveFragments ( frontWindow ); |
break; |
} |
return; |
} // DoFragmentCmds |
static void DoGetInfo ( WindowRef theWindow ) |
{ |
int16 theIndex = 0; |
ListRef theList; |
theList = GetWListRef ( theWindow ); |
if ( GetSelection ( theList, &theIndex ) ) |
{ |
OSErr theErr; |
DialogRef theDialog; |
tItemPtr theItem; |
Str255 theTitle; |
theItem = GetNthWindowItem ( theWindow, theIndex ); |
GetIndString ( theTitle, 1000, 5 ); |
ConcatPStr ( theTitle, theItem->name, sizeof ( Str255 ) ); |
theErr = CreateInfoDialog ( &theDialog, theTitle, theWindow, theIndex ); |
if ( theErr ) |
AlertUser ( kGenericErrorStr, theErr, nil ); |
} |
return; |
} |
static void DoDisplayExports ( WindowRef theWindow ) |
{ |
int16 theIndex = 0; |
ListRef theList; |
theList = GetWListRef ( theWindow ); |
if ( GetSelection ( theList, &theIndex ) ) |
{ |
OSErr theErr; |
DialogRef theDialog; |
tItemPtr theItem; |
Str255 theTitle; |
tWindowInfoPtr theInfo; |
tAddFragmentExportsRec theRec; |
theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow ); |
theItem = GetNthWindowItem ( theWindow, theIndex ); |
GetIndString ( theTitle, 1000, 1 ); |
ConcatPStr ( theTitle, theItem->name, sizeof ( Str255 ) ); |
theRec.bIn = false; |
theRec.u.out.theSpecPtr = &theInfo->fileSpec; |
theRec.u.out.theItem = theItem; |
theErr = CreateListDialog ( &theDialog, kListDialogOkay, theTitle, |
&AddFragmentExports, (void*) &theRec ); |
if ( theErr ) |
{ |
// If an error occured, the record may contain some useful information |
StringPtr theString = nil; |
if ( theRec.bIn ) |
theString = theRec.u.in.theErrorStr; |
if ( theErr == cfragNoLibraryErr ) |
AlertUser ( kUnresolvedDependenciesStr, 0, theString ); |
else |
AlertUser ( kGenericErrorStr, theErr, nil ); |
} |
} |
return; |
} |
static void DoMoveFragments ( WindowRef theWindow ) |
{ |
OSErr theErr; |
DialogRef theDialog; |
tDialogInfo* theInfo; |
Ptr theData; |
Str255 theTitle, windowTitle; |
GetWTitle ( theWindow, windowTitle ); |
GetIndString ( theTitle, 1000, 2 ); |
ConcatPStr ( theTitle, windowTitle, sizeof ( Str255 ) ); |
theErr = CreateListDialog ( &theDialog, kListDialogOkayCancel, theTitle, |
&AddDocuments, nil ); |
if ( theErr ) |
{ |
AlertUser ( kGenericErrorStr, theErr, nil ); |
return; |
} |
SetWindowSubType ( theDialog, kMoveFragmentWindowSubType ); |
// Packages up the window reference and an array of index |
// values (precceded by an element count). |
theErr = PackageWindowData ( theWindow, &theData ); |
if ( theErr ) |
{ |
AlertUser ( kGenericErrorStr, theErr, nil ); |
return; |
} |
theInfo = (tDialogInfo*) GetWRefCon ( theDialog ); |
theInfo->refCon = (int32) theData; |
return; |
} |
static void DoCopyFragments ( WindowRef theWindow ) |
{ |
OSErr theErr; |
DialogRef theDialog; |
tDialogInfo* theInfo; |
Ptr theData; |
Str255 theTitle, windowTitle; |
GetWTitle ( theWindow, windowTitle ); |
GetIndString ( theTitle, 1000, 3 ); |
ConcatPStr ( theTitle, windowTitle, sizeof ( Str255 ) ); |
theErr = CreateListDialog ( &theDialog, kListDialogOkayCancel, theTitle, |
&AddDocuments, nil ); |
if ( theErr ) |
{ |
AlertUser ( kGenericErrorStr, theErr, nil ); |
return; |
} |
SetWindowSubType ( theDialog, kCopyFragmentWindowSubType ); |
// Packages up the window reference and an array of index |
// values (precceded by an element count). |
theErr = PackageWindowData ( theWindow, &theData ); |
if ( theErr ) |
{ |
AlertUser ( kGenericErrorStr, theErr, nil ); |
return; |
} |
theInfo = (tDialogInfo*) GetWRefCon ( theDialog ); |
theInfo->refCon = (int32) theData; |
return; |
} |
static void DoRemoveFragments ( WindowRef theWindow ) |
{ |
int16 theIndex = 0; |
ListRef theList; |
theList = GetWListRef ( theWindow ); |
while ( GetSelection ( theList, &theIndex ) ) |
{ |
DeleteWindowFragment ( theWindow, theIndex ); |
theIndex++; |
} |
return; |
} |
// |
// Our refCon field is used to encapsulate the information about |
// the fragments being copied. Namely, the window reference and |
// an array of index values (precceded by an element count). This |
// packages up the information using a data stream. |
// |
static OSErr PackageWindowData ( WindowRef theWindow, Ptr* theData ) |
{ |
OSErr theErr; |
int16 theIndex = 0; |
int theCount = 0; |
ListRef theList; |
tStreamRef theStream; |
tStreamCursor countCursor; |
theErr = NewStream ( &theStream, 100 ); |
if ( theErr ) |
return theErr; |
theErr = SetStreamData ( theStream, (Ptr) &theWindow, sizeof ( WindowRef ) ); |
if ( theErr ) |
{ |
DisposeStream ( theStream ); |
return theErr; |
} |
countCursor = GetStreamCursor ( theStream ); |
theErr = SetStreamData ( theStream, nil, sizeof ( int ) ); |
if ( theErr ) |
{ |
DisposeStream ( theStream ); |
return theErr; |
} |
theList = GetWListRef ( theWindow ); |
while ( GetSelection ( theList, &theIndex ) ) |
{ |
SetStreamData ( theStream, (Ptr) &theIndex, sizeof ( int16 ) ); |
theCount++; |
theIndex++; |
} |
theErr = SetStreamCursor ( theStream, countCursor ); |
if ( theErr ) |
{ |
DisposeStream ( theStream ); |
return theErr; |
} |
theErr = SetStreamData ( theStream, (Ptr) &theCount, sizeof ( int ) ); |
if ( theErr ) |
{ |
DisposeStream ( theStream ); |
return theErr; |
} |
theErr = CompactStream ( theStream ); |
if ( theErr ) |
return theErr; |
*theData = (Ptr) theStream; |
return noErr; |
} // PackageWindowData |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-30