Retired Document
Important: This document may not represent best practices for current development. Links to downloads and other resources may no longer be valid.
Utility Functions
In your custom code, you might need to embed a control in a dialog pane, get a ticket reference, or implement a help event handler.
This appendix explains how to perform these tasks. You should be able to use this sample code in a real-world project with little or no modification.
Embedding a Nib-Based Control
Listing A-1 implements a function that embeds a nib-based control inside the dialog pane provided by the printing system.
This function takes three parameters—a nib-based window, a Carbon container control (called a user pane), and the ID of the nib-based control being embedded.
During execution, this function
gets a reference to the nib-based control
positions the control with respect to the dialog window
embeds the control inside the dialog user pane
returns a reference to the control being embedded
Listing A-1 Embedding a nib-based control inside a dialog pane
extern OSStatus MyEmbedControl ( |
WindowRef nibWindow, |
ControlRef userPane, |
const ControlID *controlID, |
ControlRef* outControl |
) |
{ |
ControlRef control = NULL; |
OSStatus result = noErr; |
*outControl = NULL; |
result = GetControlByID (nibWindow, controlID, &control);// 1 |
if (result == noErr) |
{ |
SInt16 dh, dv; |
Rect nibFrame, controlFrame, paneFrame; |
(void) GetWindowBounds (nibWindow, kWindowContentRgn, &nibFrame); |
(void) GetControlBounds (userPane, &paneFrame); |
(void) GetControlBounds (control, &controlFrame); |
dh = ((paneFrame.right - paneFrame.left) - |
(nibFrame.right - nibFrame.left))/2;// 2 |
if (dh < 0) dh = 0; |
dv = ((paneFrame.bottom - paneFrame.top) - |
(nibFrame.bottom - nibFrame.top))/2;// 3 |
if (dv < 0) dv = 0; |
OffsetRect (// 4 |
&controlFrame, |
paneFrame.left + dh, |
paneFrame.top + dv |
); |
(void) SetControlBounds (control, &controlFrame); |
result = SetControlVisibility (control, TRUE, FALSE);// 5 |
if (result == noErr) |
{ |
result = EmbedControl (control, userPane);// 6 |
if (result == noErr) |
{ |
*outControl = control;// 7 |
} |
} |
} |
return result; |
} |
Here’s what the code in Listing A-1 does:
Gets a reference to the desired control. This control already exists in the nib window that contains your custom interface.
Finds the delta needed to position the control such that the nib-based interface is horizontally center-aligned inside the dialog pane.Finds the delta needed to position the control such that the nib-based interface is vertically center-aligned inside the dialog pane.
Adjusts the coordinates of the top-left corner of the control, so that the control is positioned correctly with respect to the dialog pane.
Makes sure the control is visible if the dialog pane is displayed.
Embeds the control inside the dialog pane. As a side effect, the printing system now owns the control reference—your printing dialog extension should not release it.
Passes the embedded control back to the caller.
Getting a Ticket Reference
To get a ticket reference, you need to implement a function that calls PMSessionGetData
for the session object associated with the current print job.
Table A-1 lists the four standard ticket identifiers defined for use by printing dialog extensions.
Identifier (CFStringRef) | Ticket | Comments |
---|---|---|
| Print settings | Used by application and printer module printing dialog extensions. |
| Page format | Used by application and printer module printing dialog extensions. |
| Job template | Available only during some printer module printing dialog extension routines. |
| Printer info | Available only during some printer module printing dialog extension routines. |
Listing A-2 illustrates how to write a function that constructs and passes back a ticket reference.
Listing A-2 A utility function that gets a ticket reference
extern OSStatus MyGetTicket |
( |
PMPrintSession session, |
CFStringRef ticketID, |
PMTicketRef* ticketPtr |
) |
{ |
OSStatus result = noErr; |
CFTypeRef type = NULL; |
PMTicketRef ticket = NULL; |
*ticketPtr = NULL; |
result = PMSessionGetDataFromSession (session, ticketID, &type);// 1 |
if (result == noErr) |
{ |
if (CFNumberGetValue (// 2 |
(CFNumberRef) type, kCFNumberSInt32Type, (void*) &ticket)) |
{ |
*ticketPtr = ticket;// 3 |
} |
else { |
result = kPMInvalidValue; |
} |
} |
return result; |
} |
Here’s what the code in Listing A-2 does:
Searches the printing session object for a specialized job ticket. The value passed back is a generic object reference. The printing system provides the session object when it calls the sync function.
Gets a numeric value that represents an opaque ticket reference. This function returns
true
if the operation was successful.Passes back the ticket reference to the caller.
Handling the Help Event in a Printing Dialog
This section explains how your printing dialog extension can override the default behavior of the help button in a printing dialog. Of course, you don’t want to override the help button unless your pane is visible.
The tasks are straightforward:
Add a field for a handler reference to the context described in Defining a Context.
In the open function described in Open, install a Carbon event handler that handles the command event associated with the help button. Save the handler reference in the context.
In the close function described in Close, remove the handler to restore the default behavior of the help button.
Handling a Window Command Event
Listing A-3 shows how to implement a Carbon event handler that detects and handles a help-button click in a printing dialog. The installing function—described in Installing a Help Event Handler—configures this handler for command events only.
Listing A-3 An event handler for the help event in a printing dialog
static OSStatus MyHandleHelpEvent// 1 |
( |
EventHandlerCallRef call, |
EventRef event, |
void *userData |
) |
{ |
HICommand commandStruct;// 2 |
OSStatus result = eventNotHandledErr;// 3 |
GetEventParameter (// 4 |
event, kEventParamDirectObject, |
typeHICommand, NULL, sizeof(HICommand), |
NULL, &commandStruct |
); |
if (commandStruct.commandID == 'help') {// 5 |
result = MyDisplayHelp();// 6 |
} |
return result; |
} |
Here’s what the code in Listing A-3 does:
Declares the name and parameters for a Carbon event handler of type
EventHandlerProcPtr
. In this implementation,event
is the only parameter actually used.Declares a data structure for a command event. See the Carbon Event Manager reference for details.
Initializes the return code. The usual default value
noErr
is not appropriate here, because in this contextnoErr
means “event handled”.Retrieves the event data. Since this handler is installed at the window level, the event could contain one of several different commands.
Checks the command signature to see if the help button was clicked.
Calls a custom function you implement to display the help book for your application or printer module.
Installing a Help Event Handler
Listing A-4 shows how to write a function that installs a help event handler, specifying the printing dialog as the event target.
Listing A-4 Installing a help event handler
#define kMyNumberOfEventTypes 1 |
extern OSStatus MyInstallHelpEventHandler |
( |
WindowRef inWindow, |
EventHandlerRef *outHandler |
) |
{ |
static const EventTypeSpec sEventTypes [kMyNumberOfEventTypes] =// 1 |
{ |
{ kEventClassCommand, kEventCommandProcess } |
}; |
OSStatus result = noErr; |
EventHandlerRef handler = NULL; |
EventHandlerUPP handlerUPP = NewEventHandlerUPP (MyHandleHelpEvent);// 2 |
result = InstallWindowEventHandler (// 3 |
inWindow, |
handlerUPP, |
kMyNumberOfEventTypes, |
sEventTypes, |
NULL, |
&handler |
); |
*outHandler = handler;// 4 |
return result; |
} |
Here’s what the code in Listing A-4 does:
Defines an array of event type specifiers. This array represents the set of event types you want to handle. In this case, you need to handle only one type.
Creates the universal procedure pointer used by the Carbon Event Manager to call your event handler.
Installs the handler. On return,
context->handler
contains theEventHandlerRef
used later to remove the event handler.Stores this handler reference in the context.
Removing a Help Event Handler
Listing A-5 shows how to write a function that removes the help event handler described in Installing a Help Event Handler.
Listing A-5 Removing a help event handler
extern OSStatus MyRemoveHelpEventHandler ( |
EventHandlerRef *helpHandlerP, |
EventHandlerUPP *helpHandlerUPP |
) |
{ |
OSStatus result = noErr; |
if (*helpHandlerP != NULL) |
{ |
result = RemoveEventHandler (*helpHandlerP);// 1 |
*helpHandlerP = NULL;// 2 |
} |
if (*helpHandlerUPP != NULL) |
{ |
DisposeEventHandlerUPP (*helpHandlerUPP);// 3 |
*helpHandlerUPP = NULL;// 4 |
} |
return result; |
} |
Here’s what the code in Listing A-4 does:
Removes the help event handler.
Deletes the reference to the handler in your context.
Deallocates the UPP used by the Carbon Event Manager to call your help event handler.
Deletes the reference to this UPP in your context.
Further Reading
For more information about the Carbon event model and writing Carbon event handlers, and see Carbon Event Manager Programming Guide.
Copyright © 2002, 2006 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2006-10-03