Creating Handlers¶
Adobe Reader and Acrobat plugins and PDF Library applications can add new types of tools, annotations, actions, file systems, and so on, thereby expanding the number of supported object types. To accomplish this task, the Acrobat core API provides a collection of callback routines called handlers that support objects. Handlers perform operations, such as creating and destroy objects, handling mouse clicks, handling keyboard events, and so on.
About handlers¶
To add a new handler, you must write callback functions, create the appropriate data structure containing the callbacks and other data, and pass the structure to Acrobat by invoking the appropriate method. Subsequently, Acrobat automatically invokes the correct callback when it encounters an object of the type handled by the handler.
It is possible to subclass existing handlers or to create entirely new handler types. For example, a plugin can subclass the built-in text annotation handler by adding the ability to hide annotations. To accomplish this task, perform the following tasks:
Obtain the built-in text annotation handler structure by invoke the
AVAppGetAnnotHandlerByNamemethod.Copy the structure before modifying it (not modifying the original).
Replace the handler’s
Drawcallback with one that invokes the built-inDrawcallback (obtained from the structure) if annotations are visible, or simply return without drawing anything if annotations are hidden.Register the new handler by invoking the
AVAppRegisterAnnotHandlermethod with a new type.
If a handler requires more data than provided in the predefined structures that are described in this section, you can append additional data to the predefined structures. To do this, create a new structure type with the predefined structure as its first member and the additional data as subsequent members. Before passing the expanded structure to an Acrobat method, cast the structure to the predefined structure type. Upon return of the structure from Acrobat, re-cast the structure to its expanded type to access the appended data.
Each handler data structure contains a size field, which specifies the structure’s size. This field provides future compatibility. Different versions of the structure have different sizes, allowing Acrobat to determine which version your plugin was written to use.
Note
Regardless of whether your plugin adds data to the predefined structures, it must pass the size of the predefined structure (rather than the size of its expanded structure) in the size field.
Action handlers¶
Support for action types can be added by defining and registering an action handler. For example, the Acrobat Weblink plugin uses this ability to add support for URL links.
To add a new action type, you must provide a set of callbacks. Specify them in the AVActionHandlerProcs structure, and invoke the AVAppRegisterActionHandler method to register them.
By using an action handler, you can perform the following tasks:
Perform an action, such as setting a specific view, by invoking the
AVActionPerformProcmethod.Allow the user to set the action’s properties (if the properties can be set) by invoking the
AVActionDoPropertiesProcmethod.Initialize an action’s dictionary with default values by invoking the
AVActionFillActionDictProcmethod.Display a string containing brief instructions for the action by invoking the
AVActionGetInstructionsProcmethod.Display various text strings to be used in dialog boxes by invoking one of the following methods:
AVActionGetButtonTextProc,AVActionGetStringOneTextProc, orAVActionGetStringTwoTextProc.Copy the action by invoking the
AVActionCopyProcmethod.
Annotation handlers¶
Support for annotation types in Acrobat can be added by defining and registering an annotation handler. For example, the Acrobat movie plugin uses an annotation handler to support video annotations.
To add an annotation type, you must provide a set of callbacks, specify them in the AVAnnotHandler structure, and register them with AVAppRegisterAnnotHandler.
By using an annotation handler, you can perform the following tasks:
Draw the annotation by using the
AVAnnotHandlerDrawProccallback method.Handle mouse clicks in the annotation by using the
AVAnnotHandlerDoClickProccallback method.Control the cursor shape when the cursor is over the annotation by using the
AVAnnotHandlerAdjustCursorProccallback method.Determine whether or not a specified point is within the annotation boundary by using the
AVAnnotHandlerPtInAnnotViewBBoxProccallback method.Return the rectangle bounding that the annotation occupies by using the
AVAnnotHandlerGetAnnotViewBBoxProccallback method.Highlight (unhighlight) the annotation when it is added to (removed from) the selection by using the following callback methods:
AVAnnotHandlerNotifyAnnotAddedToSelectionProcorAVAnnotHandlerNotifyAnnotRemovedFromSelectionProc.Return the annotation’s subtype by using the
AVAnnotHandlerGetTypeProccallback method.Get the annotation’s layer by using the
AVAnnotHandlerGetLayerProccallback method.
Note
For information about working with annotations, see Creating Annotations.
AVCommand handlers¶
An AVCommand represents an action that a user can perform on the current document or the current selection in the current document. AVCommands are exposed to Adobe Reader or Acrobat through AVCommand handlers. You can add new command types by defining and registering an AVCommand handler. Commands can be executed interactively, programmatically, or through batch processing.
Creating an AVCommand handler¶
AVCommand handlers consist of a series of callback functions contained in the AVCommandHandlerRec structure (see AVExpt.h). To create a command handler, perform the following tasks:
Initialize an instance of the
AVCommandHandlerRecstructure.Register the
AVCommandHandlerRecstructure by invoking theAVAppRegisterCommandHandlermethod.
static AVCommandHandlerRec gAVCmdHandler;
const char *kCmdName = "MinimalCommand";
static ACCB1 AVCommandStatus ACCB2 DoWorkImpl (AVCommand cmd)
{
AVAlertNote("The DoWorkImpl method was invoked");
return kAVCommandDone;
}
void InitializeCommandHandler()
{
memset (&gAVCmdHandler, 0, sizeof(AVCommandHandlerRec));
gAVCmdHandler.size = sizeof(AVCommandHandlerRec);
gAVCmdHandler.Work = ASCallbackCreateProto (AVCommandWorkProc,
&DoWorkImpl);
AVAppRegisterCommandHandler (ASAtomFromString(kCmdName),
&gAVCmdHandler);
}
Note
To view a complete example, see Running commands.
Invoking AVCommands¶
To programmatically invoke AVCommands using AVCommand methods, perform the following tasks:
Instantiate the command by invoking the
AVCommandNewmethod, providing the registered name of the command:
ASAtom cmdName;
AVCommand cmd;
cmdName = ASAtomFromString ("MinimalCommand");
cmd = AVCommandNew(cmdName);
Configure the command by setting required and optional parameters.
Run the command by invoking the
AVCommandExecuteorAVCommandWorkmethod.
Configuring AVCommands¶
Prior to executing an AVCommand, you configure three categories of properties:
Input parameters (required)
Configuration parameters (optional - initialized to defaults)
AVCommand parameters (optional - initialized to defaults)
Setting input parameters¶
At minimum, you must configure input parameters. The command must be provided with a PDDoc object that represents the PDF document on which to operate, as shown in the following example. For information about a PDDoc object, see Creating a PDDoc object.
//Create a PDDoc object based on the current PDF document
AVDoc avDoc = AVAppGetActiveDoc();
AVPageView pageView = AVDocGetPageView(avDoc);
PDPageNumber pageNum = AVPageViewGetPageNum(pageView);
PDDoc pdDoc = AVDocGetPDDoc(avDoc);
//Create an ASCab object to store input parameters
ASCab inputs = ASCabNew();
ASCabPutPointer (inputs, kAVCommandKeyPDDoc, PDDoc, pdDoc, NULL);
//Set the input parameters
if (kAVCommandReady != AVCommandSetInputs(cmd, inputs)) {
// Handle error
//Destroy the ASCab container
ASCabDestroy (inputs);
Note
For more information about the AVCommandSetInputs method, see the Acrobat and PDF Library API Reference.
Setting configuration parameters¶
Optionally you can set configuration parameters. The default UI policy is for commands to be fully interactive. To invoke the command programmatically, create an ASCab object and populate it with the appropriate parameters, as shown in the following example.
// Create an ASCab object to store config parameters
ASCab config = ACabNew();
ASCabPutInt (config, "UIPolicy", kAVCommandUISilent);
if (kAVCommandReady != AVCommandSetConfig (cmd, config)) {
// Handle error
ASCabDestroy (config);
}
Setting AVCommand parameters¶
An AVCommand parameter set is specific to each command. For example, the Document Summary command accepts values for these parameters: Title, Subject, Author, Keywords, Binding, and LeaveAsIs. (See the Acrobat and PDF Library API Reference.)
You can create an ASCab object to store the appropriate parameters; then create empty ASText objects to hold the parameter values and place these values into the ASCabs object. The following example uses this approach to set the Document Summary Title and Subject values.
const char *docTitleValue = "Document Title";
const char *docSubjectValue = "Document Subject";
//Create an ASCab object to hold command parameters
ASCab params = ASCabNew();
ASText text = ASTextNew();
ASTextSetEncoded(text, docTitleValue,(ASHostEncoding)PDGetHostEncoding());
ASCabPutText (params, docTitleValue, text);
//Clear the ASText object
text = ASTextNew();
ASTextSetEncoded(text, docSubjectValue,(ASHostEncoding)PDGetHostEncoding());
ASCabPutText(params, docSubjectValue, text);
Running commands¶
The following code example shows an entire example of creating an AVCommand and running it.
void InitializeCommandHandler()
{
//Declare local variables
static AVCommandHandlerRec gAVCmdHandler;
const char *kCmdName = "MinimalCommand";
ASAtom cmdName;
AVCommand cmd;
const char *docTitleValue = "Document Title";
const char *docSubjectValue = "Document Subject";
//Create a PDDoc object based on the current PDF document
AVDoc avDoc = AVAppGetActiveDoc();
AVPageView pageView = AVDocGetPageView(avDoc);
PDPageNumber pageNum = AVPageViewGetPageNum(pageView);
PDDoc pdDoc = AVDocGetPDDoc(avDoc);
//Create an AVCommandHandlerRec object
memset (&gAVCmdHandler, 0, sizeof(AVCommandHandlerRec));
gAVCmdHandler.size = sizeof(AVCommandHandlerRec);
gAVCmdHandler.Work = ASCallbackCreateProto (AVCommandWorkProc, DoWorkImpl);
AVAppRegisterCommandHandler (ASAtomFromString(kCmdName),&gAVCmdHandler);
//Invoke the AVCommand
cmdName = ASAtomFromString ("MinimalCommand");
cmd = AVCommandNew(cmdName);
//Set the input parameters
ASCab inputs = ASCabNew();
ASCabPutPointer (inputs, kAVCommandKeyPDDoc, PDDoc, pdDoc, NULL);
//Set the input parameters and destroy the container ASCab
if (kAVCommandReady != AVCommandSetInputs (cmd, inputs)) {
// Handle error
}
//Create an ASCab object to hold command parameters
ASCab params = ASCabNew();
ASText text = ASTextNew();
ASTextSetEncoded(text, docTitleValue,(ASHostEncoding)PDGetHostEncoding());
ASCabPutText (params, docTitleValue, text);
//Clear the ASText object
text = ASTextNew();
ASTextSetEncoded(text, docSubjectValue,(ASHostEncoding)PDGetHostEncoding());
ASCabPutText(params, docSubjectValue, text);
//Invoke the command
AVCommandExecute(cmd);
}
static ACCB1 AVCommandStatus ACCB2 DoWorkImpl (AVCommand cmd)
{
AVAlertNote("The DoWorkImpl method was invoked");
return kAVCommandDone;
}
Exposing AVCommands to the batch framework¶
Acrobat or Adobe Reader builds the list of commands that users see in the Batch Sequences and Batch Edit Sequence dialog boxes from an internal list of AVCommands referred to as the global command list.
Adding a handler to the global command list¶
To expose a command to the batch framework, the AVCommand handler must first add an instance of the command to this global list by invoking the AVAppRegisterGlobalCommand method.
AVCommand cmd = AVCommandNew(ASAtomFromString(kCmdName));
AVAppRegisterGlobalCommand(cmd);
Although this step can be performed at any time once the command handler is registered, handlers commonly register commands from within the AVCommandRegisterCommandsProc callback (of the AVCommandHandlerRec structure).
Supporting properties¶
When building a list of batchable commands, Adobe Reader or Acrobat iterates through its internal command list, querying each command for the CanBatch and GroupTitle properties. To be exposed through the batch framework user interface, a command must support these properties (that is, return true and a valid ASText object, respectively). The AVCommand handler must implement the GetProps callback of the AVCommandHandlerRec structure.
If an AVCommand supports these properties, Adobe Reader or Acrobat queries a number of additional properties as the user interacts with the batch framework. Of these additional properties, only two are required: Title and Generic Title. A command must provide the title strings that will be displayed in the Batch Sequences and Batch Edit Sequence dialog boxes.
const char *kCmdTitle = "Command Title";
const char *kGroupTitle = "Group Title";
const char *kCmdGenericTitle = "Generic Title";
ASBool doItAll = false;
if (ASCabNumEntries(params) == 0)
doItAll = true;
if (doItAll || ASCabKnown (params, kAVCommandKeyGroupTitle))
{
// Create a new text object and insert it into the ASCab
text = ASTextNew();
ASTextSetEncoded (text, kGroupTitle, (
ASHostEncoding)PDGetHostEncoding());
ASCabPutText(params, kAVCommandKeyGroupTitle, text);
}
if (doItAll || ASCabKnown (params, kAVCommandKeyCanBatch))
ASCabPutBool (params, kAVCommandKeyCanBatch, true );
if (doItAll || ASCabKnown (params, kAVCommandKeyGenericTitle))
{
//Create a new text object and insert it into the ASCab
text = ASTextNew();
ASTextSetEncoded (text, kCmdGenericTitle,
(ASHostEncoding)PDGetHostEncoding());
ASCabPutText (params, kAVCommandKeyGenericTitle, text);
}
if (doItAll || ASCabKnown (params, kAVCommandKeyTitle))
{
// Create another text object and insert it into the ASCab
text = ASTextNew();
ASTextSetEncoded (text, kCmdTitle,
(ASHostEncoding)PDGetHostEncoding());
ASCabPutText (params, kAVCommandKeyTitle, text);
Note
The params object was declared in Running an AVCommand.
File format conversion handlers¶
A plugin can add file conversion handlers to Acrobat (but not Adobe Reader) for performing the following file conversion operations:
To import a PDF document from another file format.
To export a PDF document to another file format.
To add a new file conversion handler, you provide a set of callback functions, specify them in the AVConversionToPDFHandler or AVConversionFromPDFHandler structures, and invoke the AVAppRegisterToPDFHandler or AVAppRegisterFromPDFHandler methods to register them.
Specify the file types that the plugin can convert and whether it can perform synchronous conversion (required for the handler to be accessible from the batch framework). Upon registration, the conversion handlers are automatically added to the respective Open and Save As dialog boxes.
By using a file format conversion handler, you can perform the following tasks:
Provide default settings for the conversion by using the
AVConversionDefaultSettingsProccallback method.Provide conversion parameter information by using the
AVConversionParamDescProccallback method.Display a settings dialog box by using the
AVConversionSettingsDialogProccallback method.Convert a non-PDF file to or from a PDF file by invoking either the
AVConversionConvertToPDFProcorAVConversionConvertFromPDFProccallback methods.
File specification handlers¶
A file specification handler converts between a PDFileSpec object and an ASPathName object. Each file specification handler works with a single file system, which the handler specifies.
To create a new file specification handler, a plugin or application must provide callbacks that:
Convert an
ASPathNameto aPDFileSpec. It is called byPDFileSpecNewFromASPath.Convert a
PDFileSpecto anASPathName.
Selection servers¶
A selection server enables the selection of specific data types such as annotations, text, or graphics. You can also create selection servers to enable the selection of data types not already supported. To add a new selection server, you must provide a set of callbacks, specify them in the AVDocSelectionServer data structure, and register them using an AVDocRegisterSelectionServer object.
By using a selection server, you can perform the following tasks:
Return the selection type serviced by the handler by using the
AVDocSelectionGetTypeProccallback method.Highlight or unhighlight a selection by using the
AVDocSelectionHighlightSelectionProccallback method.Handle key presses by using the
AVDocSelectionKeyDownProccallback method.Delete the selection by invoking the
AVDocSelectionDeleteProcmethod.Cut the selection to the clipboard by using the
AVDocSelectionCutProccallback method.Copy the selection to the clipboard by using the
AVDocSelectionCopyProccallback method.Paste the selection from the clipboard by using the
AVDocSelectionPasteProccallback method.Enumerate the items in the current selection by using the
AVDocSelectionEnumSelectionProccallback method.Scroll the view so that the current selection is available by using the
AVDocSelectionShowSelectionProccallback method.Determine whether or not the Properties menu item is enabled by using the
AVDocSelectionCanPropertiesProccallback method.If the selection type has a properties dialog box, display the dialog box by using the
AVDocSelectionPropertiesProccallback method.
For a complete list of the callbacks in a selection server, see the description of AVDocSelectionServer in the Acrobat and PDF Library API Reference.
Note
The SelectionServer sample plugin that is located in the Acrobat SDK shows an example of a selection server.
Tool callbacks¶
To add a new tool, you must provide a set of callbacks, specify them in the AVTool data structure, and register them using AVAppRegisterTool. By using tool callbacks, you can perform the following tasks:
Activate the tool when the tool is selected by using the
ActivateProcTypecallback method.Deactivate the tool when another tool is selected by using the
DeactivateProcTypecallback method.Handle mouse clicks by using the
DoClickProcTypecallback method.Handle key presses by using the
DoKeyDownProcTypecallback method.Control the cursor shape by using the
AdjustCursorProcTypecallback method.Return the tool’s name by using the
GetTypeProcTypecallback method.Indicate whether the tool stays active after it is used by using the
IsPersistentProcTypecallback method.Determine whether the tool is enabled by using the
AVComputeEnabledProccallback method. For example, if a tool is meant to be used within documents, but there are no documents open, it does not make sense to activate the tool.
Note
For a complete list of callbacks, see the description of AVTool in the Acrobat and PDF Library API Reference.
Window handlers¶
When a plugin creates a window, it can register the window, so that it behaves like other windows in Acrobat; for example, when Adobe Reader or Acrobat is minimized or hidden. For each window that a plugin provides, a window handler must be provided. Window handlers are used only in the Mac OS version of Adobe Reader or Acrobat. Windows versions of Acrobat instead use the platform’s native window handling mechanisms. (See Opening a PDF document in an external window.)
To define a window handler, you must provide a set of callbacks, specify them in an AVWindowHandler structure, and pass the structure to AVWindowNew or AVWindowNewFromPlatformThing. The window handler’s callbacks are automatically called by Acrobat. Default behavior is used for any missing callbacks.
By using a window handler, you can perform the following tasks:
Handle mouse clicks in the window by using the
AVWindowMouseDownProccallback method.Handle keystrokes in the window by using the
AVWindowKeyDownProccallback method.Draw the window’s contents by using the
AVWindowDrawProccallback method.Permit or prevent closing of the window by using the
AVWindowWillCloseProccallback method.Clean up after the window has been closed by using the
AVWindowDidCloseProccallback method.Do anything that must be done when the window is activated or deactivated by using the following callback methods:
AVWindowDidActivateProcorAVWindowWillDeactivateProc.Permit or constrain window size changes by using the
AVWindowWillBeResizedProccallback method.Determine whether the Cut, Copy, Paste, Clear, SelectAll, and Undo menu items are enabled by using the
AVWindowCanPerformEditOpProccallback method.Perform Cut, Copy, Paste, Clear, SelectAll, and Undo operations by using the
AVWindowPerformEditOpProccallback method.Control the shape of the cursor when it is within the window by using the
AVWindowAdjustCursorProccallback method.
For a complete list of callbacks in a window handler, see the description of AVWindowHandler in the Acrobat and PDF Library API Reference.
File systems¶
Plugins can add new file systems to Acrobat or Adobe Reader, to access files on a device that cannot be accessed as a local hard disk, such as a socket or a modem line.
To add a new file system, you must provide a set of callbacks and specify them in the ASFileSysRec structure. This structure is passed as a parameter to calls that require a file system. A file system handler does not require explicit registration.
By using a file system handler, you can perform the following tasks:
Open a file by using the
ASFileSysOpenProccallback method.Close a file by using the
ASFileSysCloseProccallback method.Flush a file’s buffered data to disk by using the
ASFileSysFlushProccallback method.Get or set the current position in a file by using one of the following callback methods:
ASFileSysSetPosProcorASFileSysGetPosProc.Get or set a file’s logical size by using one of the following callback methods:
ASFileSysGetEofProcorASFileSysSetEofProc.Read data from a file by using the
ASFileSysReadProccallback method.Write data to a file by using the
ASFileSysWriteProccallback method.Delete a file by using the
ASFileSysRemoveProccallback method.Rename a file by using the
ASFileSysRenameProccallback method.Get a file’s name by using the
ASFileSysGetNameProccallback method.Get a file system’s name by using the
ASFileSysGetFileSysNameProccallback method.Determine whether two files are the same by using the
ASFileSysIsSameFileProccallback method.Get a path to a temporary file by using the
ASFileSysGetTempPathNameProccallback method.Copy a path (not the underlying file) by using the
ASFileSysCopyPathNameProccallback method.Convert between device-independent and device-dependent path by using the
ASFileSysDiPathFromPathProccallback method.Dispose of a path (not the underlying file) by using the
ASFileSysDisposePathNameProccallback method.Flush data on a volume by using the
ASFileSysFlushVolumeProccallback method.Handle asynchronous I/O operations by using the following callback methods:
ASFileSysAsyncReadProcorASFileSysAsyncWriteProc.Handle multiple read requests by using the
ASFileSysMReadRequestProccallback method.
For details about each of the callbacks in a file system, see the description of ASFileSysRec in the Acrobat and PDF Library API Reference.
Progress monitors¶
Progress monitors provide feedback to a user on the progress of a time-consuming operation. Some potentially time-consuming methods in the Acrobat core API require a progress monitor as a parameter. Acrobat has a default progress monitor, which generally is sufficient for plugins to use. The built-in progress monitor can be obtained by using the AVAppGetDocProgressMonitor method.
Plugins can use the default progress monitor or implement their own by providing a set of callbacks, specifying them in the ASProgressMonitorRec data structure, and passing a pointer to the structure to the methods that require a progress monitor (there is no explicit registration method).
Using a progress monitor, you can perform the following tasks:
Initialize the progress monitor and display it with a current value of zero by invoking the
PMBeginOperationProcmethod.Draw a full progress monitor, then remove the progress monitor from the display by invoking the
PMEndOperationProcmethod.Set the value that corresponds to a full progress monitor display by invoking the
PMSetDurationProcmethod.Set the current value of the progress monitor and update the display by invoking the
PMSetCurrValueProcmethod.Get the progress monitor’s maximum value by invoking the
PMGetDurationProcmethod.Get the progress monitor’s current value by invoking the
PMGetCurrValueProcmethod.
For details, see the description of ASProgressMonitorRec in the Acrobat and PDF Library API Reference.
Transition handlers¶
Transitions allow effects such as dissolves or wipe-downs when displaying a new page. New transition types can be added by defining and registering a transition handler.
To add a new transition, you must provide a set of callbacks, specify them in the AVTransHandler data structure, and register them by invoking the AVAppRegisterTransHandler method.
Using a transition handler, you can perform the following tasks:
Get the transition type by invoking the
AVTransHandlerGetTypeProcmethod.Perform the transition (change to the next page with this transition style) by invoking the
AVTransHandlerExecuteProcmethod.Fill in the transition dictionary in the PDF file by using either the
AVTransHandlerInitTransDictProcorAVTransHandlerCompleteTransDictProcmethods.Provide information for the user interface that sets the attributes of the transition by invoking the
AVTransHandlerGetUINameProcmethod.
Adding message handling¶
Plugins can add their own DDE messages and Apple events to those supported by Acrobat and Adobe Reader. On Windows, plugins can register to receive DDE messages directly. On Mac OS, plugins must hook into Acrobat or Adobe Reader’s Apple event handling loop to handle Apple events. To do this, replace the API’s AVAppHandleAppleEvent method. For information about replacing methods, see Replacing HFT methods.
If a plugin receives an Apple event it does not want to handle, it should invoke the implementation of the method it replaced, allowing other plugins or Acrobat or Adobe Reader the opportunity to handle the Apple event.
Note
Plugins should use the DDEML library to handle DDE messages. Problems may arise if they do not.