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.
AddNibToNav.cp
/* |
File: AddNibToNav.cp |
Contains: How to add a .nib file to a Navigation Services window. |
Version: 1.0 |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Copyright © 2003 Apple Computer, Inc., All Rights Reserved |
*/ |
#include <Carbon/Carbon.h> |
// Common stuff to all samples |
void InitToolbox(void); |
void InitMenuBar(void); |
pascal OSErr HandlePref(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon); |
pascal OSErr HandleOapp(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon); |
pascal OSErr HandleOdoc(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon); |
pascal OSErr HandlePdoc(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon); |
void InstallAppleEventHandlers(void); |
pascal OSStatus CommandProcess(EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); |
void InstallApplicationCarbonEventHandlers(void); |
void DoCloseWindow(WindowRef theWind); |
void RecursiveCloseWindow(WindowRef theWind); |
void CloseAllWindows(); |
void InitApplication(void); |
void TermApplication(void); |
// End of common stuff |
void DoAboutBox(void); |
void DoPreferences(void); |
void DoNewWindow(void); |
int main(void) |
{ |
InitToolbox(); |
InitApplication(); |
RunApplicationEventLoop(); |
TermApplication(); |
return 0; |
} |
//------------------------------- Initializations ------------------------------ |
void InitToolbox(void) |
{ |
InitCursor(); |
} |
void InitApplication(void) |
{ |
long response; |
OSErr err; |
// Can we run this particular demo application? |
err = Gestalt(gestaltSystemVersion, &response); |
Boolean ok = ((err == noErr) && (response >= 0x00001020)); |
if (!ok) |
{ |
StandardAlert(kAlertStopAlert, "\pMac OS X 10.2 (minimum) is required for this application", "\p", NULL, NULL); |
ExitToShell(); |
} |
InstallAppleEventHandlers(); |
InstallApplicationCarbonEventHandlers(); |
InitMenuBar(); |
DoNewWindow(); |
} |
void InitMenuBar(void) |
{ |
// Getting our menu bar |
Handle aHand = GetNewMBar(128); |
SetMenuBar(aHand); |
// Enabling Preferences menu item |
EnableMenuCommand(NULL, kHICommandPreferences); |
// Adding some menu item commands |
MenuHandle menu = GetMenuHandle(128); |
SetMenuItemCommandID(menu, 1, kHICommandNew); |
SetMenuItemCommandID(menu, 2, kHICommandClose); |
SetMenuItemCommandID(GetMenuHandle(1), 1, kHICommandAbout); |
// Adding a standard Window menu |
CreateStandardWindowMenu(0, &menu); |
InsertMenu(menu, 0); |
DrawMenuBar(); |
DisposeHandle(aHand); |
} |
//------------------------------- Apple Events --------------------------------- |
void InstallAppleEventHandlers(void) |
{ |
OSErr err; |
err = AEInstallEventHandler(kCoreEventClass, kAEShowPreferences, NewAEEventHandlerUPP(HandlePref), 0, false); |
if (err) DebugStr("\pAEInstallEventHandler failed for kAEOpenApplication"); |
err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, NewAEEventHandlerUPP(HandleOapp), 0, false); |
if (err) DebugStr("\pAEInstallEventHandler failed for kAEOpenApplication"); |
err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerUPP(HandleOdoc), 0, false); |
if (err) DebugStr("\pAEInstallEventHandler failed for kAEOpenDocuments"); |
err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, NewAEEventHandlerUPP(HandlePdoc), 0, false); |
if (err) DebugStr("\pAEInstallEventHandler failed for kAEPrintDocuments"); |
// Note: Since RunApplicationEventLoop installs a Quit AE Handler, we no longer have to do it here. |
} |
pascal OSErr HandlePref(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon) |
{ |
#pragma unused (theAppleEvent, reply, handlerRefcon) |
return errAEEventNotHandled; |
} |
pascal OSErr HandleOapp(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon) |
{ |
#pragma unused (theAppleEvent, reply, handlerRefcon) |
return noErr; |
} |
pascal OSErr HandleOdoc(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon) |
{ |
#pragma unused (theAppleEvent, reply, handlerRefcon) |
return errAEEventNotHandled; |
} |
pascal OSErr HandlePdoc(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon) |
{ |
#pragma unused (theAppleEvent, reply, handlerRefcon) |
return errAEEventNotHandled; |
} |
//------------------------------- Carbon Events -------------------------------- |
void InstallApplicationCarbonEventHandlers(void) |
{ |
EventTypeSpec eventType = {kEventClassCommand, kEventCommandProcess}; |
InstallEventHandler(GetApplicationEventTarget(), NewEventHandlerUPP(CommandProcess), 1, &eventType, NULL, NULL); |
} |
pascal OSStatus CommandProcess(EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) |
{ |
#pragma unused (nextHandler, userData) |
HICommand aCommand; |
OSStatus status = noErr; |
GetEventParameter(theEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &aCommand); |
switch (aCommand.commandID) |
{ |
case kHICommandAbout: |
DoAboutBox(); |
break; |
case kHICommandPreferences: |
DoPreferences(); |
break; |
case kHICommandNew: |
DoNewWindow(); |
break; |
case kHICommandClose: |
DoCloseWindow(FrontNonFloatingWindow()); |
break; |
default: |
status = eventNotHandledErr; |
break; |
} |
return status; |
} |
//------------------------------- Terminating ---------------------------------- |
void TermApplication(void) |
{ |
CloseAllWindows(); |
} |
void CloseAllWindows() |
{ |
WindowRef theWind = FrontWindow(); |
if (theWind) |
{ |
RecursiveCloseWindow(theWind); |
} |
} |
void RecursiveCloseWindow(WindowRef theWind) |
{ |
WindowRef nextWind = GetNextWindow(theWind); |
if (nextWind) RecursiveCloseWindow(nextWind); |
DoCloseWindow(theWind); |
} |
void DoCloseWindow(WindowRef theWind) |
{ |
EventRef theEvent; |
CreateEvent(NULL, kEventClassWindow, kEventWindowClose, 0, 0, &theEvent); |
SetEventParameter(theEvent, kEventParamDirectObject, typeWindowRef, sizeof(WindowRef), &theWind); |
SendEventToEventTarget(theEvent, GetWindowEventTarget(theWind)); |
} |
//------------------------------- End of common stuff -------------------------- |
void DoAboutBox(void) |
{ |
StandardAlert(kAlertNoteAlert, "\pAddNibToNav 1.0 by DTS, Apple © 2003", "\p", NULL, NULL); |
} |
void DoPreferences(void) |
{ |
StandardAlert(kAlertNoteAlert, "\pNo Preferences yet!", "\p", NULL, NULL); |
} |
UInt32 GetHIToolboxVersion() |
{ |
CFBundleRef bundle; |
CFStringRef versionStr = NULL; |
static UInt32 version = 0; |
if (version != 0) return version; |
bundle = CFBundleGetBundleWithIdentifier( CFSTR("com.apple.HIToolbox") ); |
if ( bundle != NULL ) |
versionStr = (CFStringRef) CFBundleGetValueForInfoDictionaryKey( bundle, CFSTR("CFBundleShortVersionString") ); |
if ( versionStr != NULL && CFGetTypeID( versionStr ) == CFStringGetTypeID() ) |
{ |
int major = 0, minor = 0, bugfix = 0; |
char sz[20]; |
CFStringGetCString( versionStr, sz, sizeof( sz ), kCFStringEncodingUTF8 ); |
sscanf( sz, "%d.%d.%d", &major, &minor, &bugfix ); |
version = ( major << 8 ) + ( minor << 4 ) + bugfix; |
} |
return version; |
} |
typedef struct |
{ |
IBNibRef nibRef; |
WindowRef windowFromNib; |
} CustomData; |
void HandleCarbonCustomizeEvent(NavCBRecPtr callBackParms, CustomData * data) |
{ |
OSStatus status = noErr; |
SInt16 neededHeight, neededWidth; |
static SInt16 gCarbonEventLastTryHeight; |
static SInt16 gCarbonEventLastTryWidth; |
// If it's the first time we get in this function, we need to create our nib reference and |
// instantiate the window from the nib. This function might/will be called many times. |
if (data->nibRef == NULL) |
{ |
// Create a Nib reference passing the name of the nib file (without the .nib extension). |
// CreateNibReference only searches into the application bundle. |
status = CreateNibReference(CFSTR("AddNibToNav"), &data->nibRef); |
if (status != noErr) { printf("CreateNibReference returned %ld\n", status); return;} |
// Then instantiate the window "Custom Area". |
// This name is set in InterfaceBuilder when the nib is created. |
status = CreateWindowFromNib(data->nibRef, CFSTR("Custom Area"), &data->windowFromNib); |
if (status != noErr) { printf("CreateWindowFromNib returned %ld\n", status); return;} |
} |
Rect windowBounds; |
GetWindowPortBounds(data->windowFromNib, &windowBounds); |
neededHeight = callBackParms->customRect.top + (windowBounds.bottom - windowBounds.top); |
neededWidth = callBackParms->customRect.left + (windowBounds.right - windowBounds.left); |
// check to see if this is the first round of negotiations: |
if ((callBackParms->customRect.right == 0) && (callBackParms->customRect.bottom == 0)) |
{ |
// it is, so tell NavServices what dimensions we want: |
callBackParms->customRect.right = neededWidth; |
callBackParms->customRect.bottom = neededHeight; |
} |
else |
{ |
// we are in the middle of negotiating: |
if (gCarbonEventLastTryWidth != callBackParms->customRect.right) |
if (callBackParms->customRect.right < neededWidth) // is NavServices width too small for us? |
callBackParms->customRect.right = neededWidth; |
if (gCarbonEventLastTryHeight != callBackParms->customRect.bottom) |
if (callBackParms->customRect.bottom < neededHeight) // is NavServices height too small for us? |
callBackParms->customRect.bottom = neededHeight; |
} |
// remember our last size so the next time we can re-negotiate: |
gCarbonEventLastTryWidth = callBackParms->customRect.right; |
gCarbonEventLastTryHeight = callBackParms->customRect.bottom; |
} |
void HandleCarbonStartEvent(NavCBRecPtr callBackParms, CustomData * data) |
{ |
OSStatus status = noErr; |
ControlID userPaneID = { 'usrp', 100 }; |
HIViewRef userPane; |
status = HIViewFindByID(HIViewGetRoot(data->windowFromNib), userPaneID, &userPane); |
if (status != noErr) { printf("HIViewFindByID returned %ld\n", status); return;} |
// We need to move the User Pane (along with its sub-controls) from the nib window |
// to the Navigation Services window in Jaguar. |
// In Panther, the NavCustomControl/kNavCtlAddControl will move the User Pane from the nib window |
// to the Navigation Services window so we don't need to explicitly move it before. |
if (GetHIToolboxVersion() < 0x130) |
{ |
ControlRef rootControl; |
status = GetRootControl(callBackParms->window, &rootControl); |
if (status != noErr) { printf("GetRootControl returned %ld\n", status); return;} |
status = EmbedControl(userPane, rootControl); |
if (status != noErr) { printf("EmbedControl returned %ld\n", status); return;} |
} |
status = NavCustomControl(callBackParms->context, kNavCtlAddControl, userPane); |
if (status != noErr) { printf("NavCustomControl returned %ld\n", status); return;} |
// We're done with the instantiations from the nib so let's dispose them. |
DisposeWindow(data->windowFromNib); |
DisposeNibReference(data->nibRef); |
data->nibRef = NULL; |
} |
void HandleCustomMouseDown(NavCBRecPtr callBackParms) |
{ |
EventRecord *evt = callBackParms->eventData.eventDataParms.event; |
Point where = evt->where; |
GlobalToLocal(&where); |
ControlRef whichControl = FindControlUnderMouse(where, callBackParms->window, NULL); |
if (whichControl != NULL) |
{ |
ControlKind theKind; |
GetControlKind(whichControl, &theKind); |
// Moving the focus if we clicked in an editable text control |
// In this sample, we only have a Clock and an Unicode Edit controls |
if ((theKind.kind == kControlKindEditUnicodeText) || (theKind.kind == kControlKindClock)) |
{ |
ControlRef currentlyFocusedControl; |
GetKeyboardFocus(callBackParms->window, ¤tlyFocusedControl); |
if (currentlyFocusedControl != whichControl) |
SetKeyboardFocus(callBackParms->window, whichControl, kControlFocusNextPart); |
} |
HandleControlClick(whichControl, where, evt->modifiers, NULL); |
} |
} |
void HandleNormalEvents(NavCBRecPtr callBackParms) |
{ |
switch (callBackParms->eventData.eventDataParms.event->what) |
{ |
case mouseDown: |
{ |
HandleCustomMouseDown(callBackParms); |
break; |
} |
} |
} |
pascal void EventProc(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void *callBackUD) |
{ |
OSStatus status = noErr; |
CustomData * data = (CustomData *)callBackUD; |
switch (callBackSelector) |
{ |
case kNavCBCustomize: |
{ |
HandleCarbonCustomizeEvent(callBackParms, data); |
break; |
} |
case kNavCBStart: |
{ |
HandleCarbonStartEvent(callBackParms, data); |
break; |
} |
case kNavCBEvent: |
{ |
HandleNormalEvents(callBackParms); |
break; |
} |
case kNavCBAdjustRect: |
{ |
ControlID userPaneID = { 'usrp', 100 }; |
HIViewRef userPane; |
status = HIViewFindByID(HIViewGetRoot(callBackParms->window), userPaneID, &userPane); |
if (status != noErr) |
break; // we didn't reach kNavCBStart yet so our user pane is not there. |
MoveControl(userPane, callBackParms->customRect.left, callBackParms->customRect.top); |
break; |
} |
case kNavCBAccept: |
{ |
// Getting the current settings of some controls... |
ControlID checkBoxID = { 'chck', 100 }; |
HIViewRef checkBox; |
status = HIViewFindByID(HIViewGetRoot(callBackParms->window), checkBoxID, &checkBox); |
Boolean isChecked = (GetControlValue(checkBox) == 1); |
// if (isChecked) printf("is Checked\n"); else printf("is not Checked\n"); |
ControlID unicodeEditID = { 'ucde', 100 }; |
HIViewRef unicodeEdit; |
status = HIViewFindByID(HIViewGetRoot(callBackParms->window), unicodeEditID, &unicodeEdit); |
CFStringRef theCFString; |
GetControlData(unicodeEdit, kControlEntireControl, kControlEditTextCFStringTag, sizeof(theCFString), &theCFString, NULL); |
/*{ |
char buffer[300]; |
CFStringGetCString(theCFString, buffer, 300, kCFStringEncodingMacRoman); |
printf("string is '%s'\n", buffer); |
}*/ |
CFRelease(theCFString); |
break; |
} |
} |
} |
void DoNewWindow(void) |
{ |
OSStatus status = noErr; |
NavDialogCreationOptions options; |
status = NavGetDefaultDialogCreationOptions(&options); |
if (status != noErr) { printf("NavGetDefaultDialogCreationOptions returned %ld\n", status); return;} |
CustomData * data = (CustomData *)malloc(sizeof(CustomData)); |
data->nibRef = NULL; |
data->windowFromNib = NULL; |
NavDialogRef navDialog; |
status = NavCreatePutFileDialog(&options, kUnknownType, kUnknownType, EventProc, data, &navDialog); |
if (status != noErr) { printf("NavCreatePutFileDialog returned %ld\n", status); return;} |
status = NavDialogRun(navDialog); |
if (status != noErr) { printf("NavDialogRun returned %ld\n", status); return;} |
NavDialogDispose(navDialog); |
free(data); |
} |
Copyright © 2004 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2004-01-22