Important: The information in this document is obsolete and should not be used for new development.
Recipes--Scripting
The recipes and sample code in this section describe how to support Apple events in your application, how to define a recordable command class, how to set object properties with Apple events, how to support a custom Apple event, how to write a simple script that can be attached to window objects in your application, how to initialize MacApp's scripting support to use a custom subclass ofTOSADispatcher
, and how to override theGetContainedObject
method to look for contained objects matching a type you are interested in.Supporting Apple Events in Your Application--A General Outline
A MacApp application is scriptable by default, since it automatically supports the four required Apple events plus a number of events from the Core suite. MacApp's scripting support is initialized automatically from theIApplication
method, so it requires no special initialization by your application.This outline describes the steps most MacApp applications take to add support for additional Apple events or to modify MacApp's default behavior. To provide additional scripting support in your application, you perform these steps:
- Factor your application. Factoring consists of
- separating code that controls the user interface from code that responds to user actions
- breaking functions into discrete operations that can be implemented as separate tasks
For more information, see "Factoring," beginning on page 143.
- Establish an event suite by identifying the additional Apple events your application will support, or the ones it will modify (see page 142).
- Define an
'aete'
resource for your new or modified events. The easiest way to do this is to copy and modify MacApp's default'aete'
resource. The'aete'
resource provides information to a scripting component about the Apple events an application supports and about the human-language terminology associated with those events. (See "Define an 'aete' Resource," beginning on page 356.)- Define one or more
'aedt'
resources for your custom Apple events. An'aedt'
resource maps a received Apple event (by class ID and descriptor type) to a MacApp command number. (See "Define an 'aedt' Resource for the Custom Event," beginning on page 362.)- Identify the classes you will use to handle your custom events. If those classes don't descend from classes that already use the mixin class
MScriptableObject
, add it to their definition.When you mix in
MScriptableObject
to a class, the constructor for that class should initializeMScriptableObject
with a unique object model class ID. For example, MacApp'sTFile
class implements its constructor method as follows:
TFile::TFile()
: MScriptableObject(cFile)
{
.
.
.
}This code sets the
fOMClassID
field of theTFile
class (inherited from theMScriptableObject
class) tocFile
. This field is used by methods such asCountContainedObjects
,GetObjectProperty
, andMakeObjectSpecifier
.- Determine which properties of your objects can be set by Apple events. Override the
GetObjectProperty
andSetObjectProperty
methods ofMScriptableObject
to get and set those properties. You may also have to override theGetSetPropertyInfo
method. (See "Recipe--Setting Object Properties With Apple Events," beginning on page 355.)- Optionally override other methods of
MScriptableObject
so your scriptable classes can describe themselves to the Object Support Library (OSL). This can include overriding theGetContainedObject
,GetIndContainedObject
, andCountContainedObjects
methods. (See "Recipe--Overriding the GetContainedObject Method," beginning on page 368.)- Override the
MScriptableObject::DoScriptCommand
method to add support for your custom events. In theDoScriptCommand
method you typically create a command to perform the operation specified by an Apple event. (See "Override DoScriptCommand to Handle the Custom Event," beginning on page 364.)- To handle core events, override additional methods in
MScriptableObject
, such asDoAEMove
,DoAEOpen
,DoAEClose
, and so on. (Some of these methods are overridden in MacApp classes. For example, theTWindow
class provides aDoAEMove
method.)- To perform a recordable operation, define a command class that descends from
TCommand
(or one of MacApp's many predefined subclasses). Override theMakeAppleEvent
method to create an Apple event that describes the command operation.
Recipe--Defining a Recordable Command Class
MacApp'sTCommand
class contains support for sending an Apple event that describes the command operation. Sending an Apple event makes the operation recordable and allows attached scripts to respond to the command. You can read more about this topic in "Command Objects and Apple Events," beginning on page 120. This recipe adds scripting-related information to the recipe for implementing an undoable Zoom In menu command, which begins on page 334.To define a recordable command class, you perform these steps:
You also perform this additional step:
- Follow all five steps shown in "Recipe--Implementing an Undoable Zoom In Menu Command," beginning on page 334:
- Define a command-number constant for the Zoom In menu item.
- Add the Zoom In menu item to a
'CMNU'
resource in your resource file.- Implement a command class that handles Zoom In and override the
DoIt
,UndoIt
, andRedoIt
methods.- Override the
DoSetupMenus
method in the view class to enable the Zoom In menu item when appropriate.- Override the
DoMenuCommand
method in the document class to create and post a command object to perform the zoom operation.Each of these steps is described in the recipe for an undoable Zoom In menu command.
The sample code in this recipe is from the IconEdit application.
- Override the
MakeAppleEvent
method in theTZoomInCommand
class.
Override MakeAppleEvent in the TZoomInCommand Class
TheTCommand::MakeAppleEvent
method creates an Apple event that describes the command operation. For theTZoomInCommand
class, the operation is zooming in on an icon. TheTZoomInCommand
class is shown in "Implement a Command Class That Handles Zoom In," beginning on page 335.For the
TZoomInCommand
class, theMakeAppleEvent
method is defined as follows:
TAppleEvent * TZoomInCommand::MakeAppleEvent() // Override. { CTempDescdirectObjectDesc; TAppleEvent * theZoomInAppleEvent = new TAppleEvent; theZoomInAppleEvent->IAppleEvent(kAEIconEditClass, kAEZoomInID, gServerAddress, kAENoReply); fIconDocument->MakeObjectSpecifier(directObjectDesc, fIconDocument->GetSpecifierForm()); theZoomInAppleEvent->WriteParameter(keyDirectObject, directObjectDesc); return theZoomInAppleEvent; }This method first creates a newTAppleEvent
object and initializes it for the Zoom In command. The constant kAENoReply indicates that no reply to the Apple event is expected. The constants kAEIconEditClass and kAEZoomInID are defined as follows:
const OSType kAEIconEditClass = 'ICED'; // Event class. const OSType kAEZoomInID = 'ZmIn';// Event ID.For more information on how event class and ID constants are used, see "Define an 'aedt' Resource for the Custom Event," beginning on page 362.The MakeAppleEvent method next asks its document to create an object specifier (see page 350), then writes the specifier to the Apple event. The result is a Zoom In Apple event that specifies an icon document object to be zoomed.
- Note
- The TDocument::GetSpecifierForm method returns
formName
, so the object specifier identifies the document by name.Recipe--Setting Object Properties With Apple Events
This recipe depends on MacApp's built-in support for handling set property Apple events. To understand how that support works, you should read about theTSetPropertyCommand
andTPropertyAccessor
classes, beginning on page 155.To add support to a class to set object properties based on received Apple events, you perform the following steps:
The sample code shown in this recipe is from the IconEdit application.
- Identify the property or properties the class will support.
- Define an
'aete'
resource with information on the class and the properties that can be set by Apple events.- Mix in the
MScriptableObject
class (if it isn't already mixed in).- Initialize
MScriptableObject
with an object model class ID for the class.- Override the
GetObjectProperty
andSetObjectProperty
methods.- If necessary, override the
GetSetPropertyInfo
method.
Identify the Property or Properties the Class Will Support
Apple event object classes may have one or more properties. A property is identified by a four-character property ID, which can also be represented by a constant. Constants for properties always begin with the letter "p". Many are defined in the header fileAERegistry.h
. Table 14-1 lists the constant names and property IDs for some common properties. You can read more about properties in Inside Macintosh: Interapplication Communication.The IconEdit application supports
pColor
as a property that specifies the current icon color of an object based on theTIconDocument
class.Table 14-1
Common object properties
Property Property ID Description pBounds
'pbnd'
Coordinates of a window pClass
'pcls'
Class ID of an Apple event object pColor
'colr'
Text color pFillColor
'flcl'
Fill color pFont
'font'
Font pIsModal
'pmod'
Indicates whether a window is modal pName
'pnam'
Name of an Apple event object pScriptTag
'psct'
Script system identifier pTextPointSize
'ptps'
Point size pTextStyle
'txst'
Text style pVisible
'pvis'
Indicates whether a window is visible MacApp classes that mix in
MScriptableObject
override theGetObjectProperty
andSetObjectProperty
methods to get and set the object properties they support. For example, theTWindow
class returns thepClass
,pBounds
,pName
,pHasCloseBox
,pHasTitleBar
,pIsModal
,pIsResizable
,pIsZoomable
,pIsZoomed
, andpSelection
properties in itsGetObjectProperty
method. In itsSetObjectProperty
method, it can handlepBounds
,pName
, andpIsZoomed
(the other properties are read only). As a result, you can use a script to read or set many window properties without writing any additional application code.Define an 'aete' Resource
An'aete'
resource provides information to a scripting component about the Apple events an application supports and about the human-language terminology to associate with those events.The best way to supply information about your custom events is to copy MacApp's default
'aete'
resource, located in the fileDefaults.r
, add it to your application's resource definition file, and modify it to include your custom events.The IconEdit application modifies MacApp's default
'aete'
resource to add an icon suite of supported Apple events. The following code, from the fileIconEdit.r
, shows the part of IconEdit's'aete'
resource that allows an icon document to handle the color property:
{ /* array Classes: 1 elements */ /* [1] */ "document", cDocument, "IconEdit document", { /* array Properties: 1 elements */ /* [1] */ "icon_color", pColor, cRGBColor, "color in which the icon is drawn", reserved, singleItem, notEnumerated, readWrite, Reserved8, noApostrophe, notFeminine, notMasculine, singular }, { /* array Elements: 0 elements */ } },For more information about the format of an'aete'
resource, see the "Apple Event Terminology Resources" chapter of Inside Macintosh: Interapplication Communication.Mix in the MScriptableObject Class
Your class that gets and sets object properties must mix inMScriptableObject
unless it descends from a class that already mixes inMScriptableObject
. TheTIconDocument
class is a descendant of theTDocument
class, which mixes in MScriptableObject. TheTDocument
class is declared as follows to mix in MScriptableObject:
class TDocument : public TCommandHandler, public MScriptableObjectInitialize MScriptableObject With an Object Model Class ID
If your class that gets and sets object properties doesn't already mix inMScriptableObject
, the constructor for your class should initializeMScriptableObject
with a unique object model ID. For example, the constructor method for theTDocument
class is implemented as follows:
TDocument::TDocument() : MScriptableObject(cDocument), fTitle(gEmptyString), fWindowList(NULL), . . . { }This implementation demonstrates a C++ mechanism for supplying a method with a list of default values. The line: MScriptableObject(cDocument),
invokes a constructor for MScriptableObject and initializes the
fOMClassID
field tocDocument
. The subsequent lines initialize fields of theTDocument
class.Override GetObjectProperty and SetObjectProperty
Your class that supports modifying object properties with Apple events overrides theGetObjectProperty
andSetObjectProperty
methods to get and set the properties it works with. For theTIconDocument
class, these methods look for thepColor
property. For any other property, they callInherited
.
Boolean TIconDocument::GetObjectProperty(CAEDesc& thePropertyValue, DescType whichProperty, const CAEDesc& desiredType) { Boolean hasProperty = TRUE; switch (whichProperty) { case pColor: thePropertyValue.PutRGBColor(fColor); // Set color. break; default: hasProperty = Inherited::GetObjectProperty( thePropertyValue, whichProperty, desiredType); break; } return hasProperty; }The GetObjectProperty method gets the document's icon color from thefColor
field and writes it to the passed descriptor object,thePropertyValue
.
void TIconDocument::SetObjectProperty( const CAEDesc& thePropertyValue, DescType whichProperty) { switch(whichProperty) { case pColor: thePropertyValue.GetRGBColor(fColor); this->RedrawViews(); break; default: Inherited::SetObjectProperty(thePropertyValue, whichProperty); break; } }The SetObjectProperty method writes the color from the passed descriptor object,thePropertyValue
, to the document'sfColor
field. It then calls theRedrawViews
method to force the icon to be redrawn with the new color.If Necessary, Override GetSetPropertyInfo
TheGetSetPropertyInfo
method is described in "The TSetPropertyCommand Class," beginning on page 155. Your class overridesGetSetPropertyInfo
only if it needs to change the default values supplied by theMScriptableObject
class. The TIconDocument class overridesGetSetPropertyInfo
to supply a command number:
void TIconDocument::GetSetPropertyInfo(DescTypewhichProperty, CommandNumber&cmdNum, Boolean& canUndo, Boolean& causesChange, TCommandHandler* &theContext) { switch(whichProperty) { case pColor: cmdNum = cSetColor; canUndo = TRUE; causesChange = TRUE; theContext = this; break; default: Inherited::GetSetPropertyInfo(whichProperty, cmdNum, canUndo, causesChange, theContext); break; } }The icon document sets only thepColor
property, so for any other property this method just callsInherited
.Recipe--Supporting a Custom Apple Event
To support a custom Apple event (or any number of them), your application performs many of the steps shown in the general outline beginning on page 351. This recipe shows how the IconEdit application supports a Zoom In event.To use a custom Apple event in your application, you perform these steps:
The sample code shown in this recipe is from the IconEdit application.
- Identify the custom event to be supported.
- Describe the custom event in your application's
'aete'
resource.- Define an
'aedt'
resource for the custom event.- Make sure the class that handles the custom event mixes in the
MScriptableObject
class.- If necessary, override methods of
MScriptableObject
so that your scriptable class can describe itself to the OSL.- Override the
MScriptableObject::DoScriptCommand
method to handle the custom event.
Identify the Custom Apple Event
The IconEdit application defines custom events to invert an icon, zoom in and zoom out on an icon, and draw or erase the points in an icon. This recipe examines the Zoom In event.Define an 'aete' Resource That Includes the Custom Event
An'aete'
resource provides information to a scripting component about the Apple events an application supports, and about the human-language terminology to associate with those events. You can copy MacApp's default'aete'
resource, located in the fileDefaults.r
, add it to your application's resource definition file, and modify it to include your custom events.The IconEdit application modifies MacApp's default
'aete'
resource to add an Icon suite of supported Apple events. The following code, from the fileIconEdit.r
, shows the part of IconEdit's'aete'
resource that allows an icon document to handle the Zoom In event:
/* [2] */ "zoom_in", "increases the magnification of the target document", 'ICED', 'ZmIn', noReply, "", replyOptional, singleItem, notEnumerated, notTightBindingFunction, Reserved8, verbEvent, Reserved3, typeObjectSpecifier, "the document to zoom into", directParamRequired, singleItem, notEnumerated, doesntChangeState, Reserved12, { /* array OtherParams: 0 elements */ }For more information about the format of an'aete'
resource, see the "Apple Event Terminology Resources" chapter of Inside Macintosh: Interapplication Communication.Define an 'aedt' Resource for the Custom Event
MacApp uses resources of type'aedt'
to install Apple event callback routines for an application's custom events (see "InstallDispatchHandlers," beginning on page 151). An'aedt'
resource is an array of entries, each of which maps an Apple event class and ID pair to a MacApp command number.To handle a custom Apple event in your application, you define an Apple event class and ID for the event, as well as a command number to associate with them. Then you add an
'aedt'
resource to your resource definition file and include an entry for the event. You can store as many entries as you want in one'aedt'
resource, and you can have multiple'aedt'
resources.The IconEdit application defines the following 'aedt' resource in the file
IconEdit.r
to support Apple events specifying the operations to invert, zoom in, zoom out, and draw points:
resource 'aedt' (kAEIconEditDispatchTable, #if qNames "IconEdit Events", #endif purgeable) { { /* array: 4 elements */ /* [1] */ 'ICED', 'INVT', 1002, /* [2] */ 'ICED', 'ZmIn', 1000, /* [3] */ 'ICED', 'ZmOt', 1001, /* [4] */ 'ICED', 'DrPt', 1003 } };The IconEdit application defines the following constants for working with its custom Apple events (theIconEdit.r
resource file ought to define similar constants and use them in the'aedt'
resource shown above):
const OSType kSignature ='ICED'; // Application signature. const OSType kAEInvertID = 'INVT';// Custom Apple event IDs. const OSType kAEZoomInID = 'ZmIn'; const OSType kAEZoomOutID = 'ZmOt'; const OSType kAEDrawPoints = 'DrPt'; const CommandNumber cZoomIn=1000;// Zoom In menu command. const CommandNumber cZoomOut=1001;// Zoom Out menu command. const CommandNumber cInvert=1002;// Invert menu command. const CommandNumber cDrawCommand =1003;// Drawing in the icon view. const CommandNumber cDrawPointsCommand = 1004;// Set point Apple event.Add the Mixin Class MScriptableObject
MacApp dispatches Apple events through a global Apple event dispatcher object, described in "Dispatching Apple Events," beginning on page 150. The event dispatcher expects the specified objects to be descendants ofMScriptableObject
, a MacApp mixin class with fields and methods for working with Apple events.Several MacApp classes, including
TDocument
andTWindow
, already useMScriptableObject
. If you define a class that handles Apple events and doesn't descend from a class that already usesMScriptableObject
, you should addMScriptableObject
to the class definition.The
TIconDocument
class is a descendant of theTDocument
class, which is declared as follows:
class TDocument : public TCommandHandler, public MScriptableObjectIf Necessary, Override Certain Methods of MScriptableObject
MacApp's global Apple event dispatcher object calls routines of the Object Support Library to help resolve the object specified by the event. The OSL uses callback routines in the event dispatcher object to ask objects to describe themselves.To aid in this process, your classes that handle Apple events may need to override methods of
MScriptableObject
(such asGetContainedObject
,GetIndContainedObject
, andCountContainedObjects
) to describe their elements. This information can help determine if the document matches the one specified by an Apple event. For an example of how to override theGetContainedObject
method, see "Recipe--Overriding the GetContainedObject Method," beginning on page 368.Override DoScriptCommand to Handle the Custom Event
When MacApp identifies the object specified by an Apple event, it calls theDoScriptCommand
method of that object. The class that handles your custom Apple event overridesDoScriptCommand
to handle events it knows about.The
TIconDocument
class overridesDoScriptCommand
and supplies the following code to create a command to zoom in on an icon:
case cZoomIn: TZoomInCommand * theZoomInCommand = new TZoomInCommand(); theZoomInCommand->IZoomInCommand(this); theZoomInCommand->Process(); break;Note that this code does not set the command'sfUseAppleEvent
field toTRUE
. Because the Zoom In command is being created in response to an Apple event, there is no need to send an Apple event to show that the operation was performed. TheTZoomInCommand
class is described in "Recipe--Defining a Recordable Command Class," beginning on page 353.Recipe--Attaching a Script to Objects in Your Application
"Attaching Scripts," beginning on page 158, describes MacApp's mechanism for attaching scripts to objects in your application. MacApp provides true attachability through its Apple-event-dispatching mechanism and itsMScriptableObject
class--that is, a script can be attached to an object, and any Apple events specifying that object will first be dispatched to the attached script.You attach a script to an object that mixes in MScriptableObject by calling the
SetObjectProperty
method and passing two values: aCAEDesc
value that describes the script and aDescType
value that specifies thepScript
property. Since many MacApp classes already mix in MScriptableObject, you can attach scripts to objects based on these classes (or on subclasses you define) without writing any additional application code.When a script is attached to any object in the application, MacApp's global Apple event dispatcher object installs a callback routine to predispatch Apple events. The predispatch routine gives attached scripts a chance to handle Apple events dispatched by the application, whether they are generated internally or received from an outside source.
The following is a simple script that you can run from the Script Editor application. It attaches a script to each open window in the DemoText sample application. When you close a window with the script attached, the script intercepts the close operation and forces the document to be saved.
script forceSaveOnClose on close of theCloseObj saving savingValue display dialog "Entering Script" display dialog "The original saving value:" display dialog savingValue set savingValue to yes display dialog "The new saving value:" display dialog savingValue set savingFile to a reference to file "YourHardDisk:YourSaveFolder:SavedFile" continue close of theCloseObj saving savingValue saving in savingFile display dialog "Finished - Exiting Script" end close end script on run set the script of every window of application "DemoText" to forceSaveOnClose end runTo test this script, you perform the following steps:
This script attaches the
- Build a version of the DemoText application that includes MacApp's attachability support.
To enable attachability in your application, you must build the application with the
qAttachable
flag set toTRUE
. "Common Command-Line Options," beginning on page 678, describes how to build your application with attachability or without it, using MPW's MABuild system.- Run the DemoText application. Open one or more windows.
- Run the Script Editor application.
- Open a new script window.
- Copy the script shown above into the script window.
- Change "DemoText" to match the current name of the application on your computer (for example, "DemoTextPPC_nd").
- Change "YourHardDisk
:YourSaveFolder:
" to specify a disk and folder location on your current machine. If desired, change "SavedFile
" to a different filename.- Click the Run button to run the script.
forceSaveOnClose
script to each open window in the DemoText application (actually, to each window's document).How MacApp Attaches the Script
When you run the script with Script Editor, the line
set the script of every window of application "DemoText" to forceSaveOnClosesends an Apple event to the DemoText application, telling it to set thepScript
property of each window to theforceSaveOnClose
script. The mechanism for setting object properties is described in Chapter 6, "Scripting," beginning on page 155 (in the sections describing theTSetPropertyCommand
andTPropertyAccessor
classes) and in "Recipe--Setting Object Properties With Apple Events," beginning on page 355.When MacApp receives the Apple event, it creates a list containing a
TPropertyAccessor
object for each open window and uses the list to initialize aTSetPropertyCommand
object. TheTSetPropertyCommand
object uses MacApp's attachability mechanism (page 158) to attach the script to each window.
MacApp even automates saving a script when you close the document it is attached to. When you save a DemoText document with the
- Note
- When you attach a script to a window object by setting the
pScript
property, the window defers to its document, so the script is actually attached to the document.forceSaveOnClose
script attached, the script is automatically saved in the document's resource fork (unless you change the value of the document'sfSaveAttachedScript
field toFALSE
). When you open the document, it automatically reads the script, creates a script object, and attaches it to the document object.What Happens When the Script Is Executed
When you close a window in the DemoText application, MacApp creates and posts aTCloseFileDocCommand
. When the command is processed, it sends akAEClose
Apple event that specifies the document to be closed.If a script is attached to any object in the application, MacApp's global Apple event dispatcher object attempts to predispatch each Apple event for handling by an attached script. In this case, the predispatch handler method dispatches the Apple event to the document's attached script.
The
forceSaveOnClose
script gains control after the user has been asked whether to save the document. TheforceSaveOnClose
script then performs the following actions (assuming you don't cancel the script and no errors are encountered):
- It displays the alert "Entering Script".
- It displays the user's original save choice ("yes" if the user chose to save, "no" if the user chose not to save the document).
- It sets the save choice to "yes" and displays the new choice.
- It saves the file to the specified location.
- It displays the alert "Finished - Exiting Script".
Where You Go From Here
This recipe presents a simple script that hard-codes the name and location of the saved file and contains no error checking. Yet it demonstrates how attached scripts can greatly alter the behavior of a MacApp application. For example, a user can attach a similar script to a document representing an office form, so that every time the document is saved, the default behavior is overridden and the document is backed up to a server.Other uses for attached scripts are limited only by your imagination and the diabolical cunning of your end users.
Recipe--Overriding the GetContainedObject Method
When your application receives an Apple event, MacApp attempts to dispatch the event to the specified object. (Object specifiers are described beginning on page 350.) During the dispatching process, the OSL makes callbacks to methods of MacApp's global Apple event dispatcher object, attempting to identify the Apple event object with the specified properties.As part of this process, the
TOSADispatcher::ObjectAccessor
method makes the following call:
resultObject = containerObject->GetContainedObject( desiredClass, form, selectionData);GetContainedObject is a method ofMScriptableObject
, so it can be overridden by any class that mixes inMScriptableObject
. The ultimate container (the first object queried by the OSL when resolving an object specifier) is the application object. TheTApplication
class overrides GetContainedObject to look for contained files. If the desired object is not a file, it callsInherited
, which results in a call toMScriptableObject::GetContainedObject
. That method looks for contained objects matching the desired name, relative position, range, unique ID, or absolute position.To override the
GetContainedObject
method to return contained objects that match a form you are interested in, you perform the following steps:
The sample code shown in this recipe is taken from the MacApp
- Define a class that mixes in the
MScriptableObject
class.- Provide an override version of the
GetContainedObject
method.
TWindow
class.Define a Class That Mixes In the MScriptableObject Class
To override theGetContainedObject
method, your class must descend from theMScriptableObject
class or theMDefaultScriptableObject
class, or from a class that mixes in one of those classes. Many MacApp classes (includingTApplication
,TDocument
, andTWindow
) mix in one of these classes, so you don't have to write any additional code for your application, document, or window classes to mix in theMScriptableObject
class.Provide an Override Version of the GetContainedObject Method
Your version ofGetContainedObject
should check for a contained object matching the form or forms it is interested in. If it doesn't find one, it should call MScriptableObject::GetContainedObject. The following is the GetContainedObject method from MacApp'sTWindow
class:
MScriptableObject* TWindow::GetContainedObject( DescType desiredType, DescType selectionForm, const CAEDesc&selectionData) { MScriptableObject * result = NULL; if (this->IsShown() && !fFloats) { if (gApplication->IsDocumentClass(desiredType)) result = fDocument; else if (fDocument && (desiredType != cProperty) && (desiredType != this->GetOMClass())) result = fDocument->GetContainedObject(desiredType, selectionForm, selectionData); } if (!result) result = MScriptableObject::GetContainedObject(desiredType, selectionForm, selectionData); return result; }This code checks whether the desired type is a document or a property. If the desired type is a document (determined by calling the application object'sIsDocumentClass
method), this method returns the window'sfDocument
reference as the contained object. If the desired type is a property, it gives its document a chance to return the contained object. If the desired type is neither a document or a property, it calls the MScriptableObject::GetContainedObject method to look for other types.Recipe--Installing a Custom Subclass of TOSADispatcher
By default, MacApp's scripting support creates a global Apple event dispatcher object (accessed through TOSADispatcher::fgDispatcher) of typeTOSADispatcher
. However, you can define a custom subclass ofTOSADispatcher
and cause MacApp to use your type instead. When you create a custom Apple event dispatcher, you still access it through TOSADispatcher::fgDispatcher.To install a custom subclass of
TOSADispatcher
, you perform the following steps:
The sample code shown in this recipe is for a generic application.
- Define your custom subclass of
TOSADispatcher
(not shown).- Register your custom subclass.
- Call the
InitUScripting
method of your custom subclass.
Define a Custom Subclass of TOSADispatcher
Several other recipes describe how to define a class, including "Recipe--Defining a Class," beginning on page 277, and "Recipe--Defining a Subclass of TApplication," beginning on page 289. This recipe assumes that you have defined a custom subclass ofTOSADispatcher
namedTYourOSADispatcher
.Register Your Custom Subclass
You must register your custom subclass ofTOSADispatcher
so that theInitUScripting
method will be able to create an instance of your class. You register your custom class with the following line:
MA_REGISTER_CLASS(TYourOSADispatcher);Call the InitUScripting Method of Your Custom Subclass
You need to call theInitUScripting
method of your custom subclass before callingIApplication
. A reasonable place to do so is in yourmain
function or in the initialization method of your application class, using code like the following:
void TYourApplication::IYourApplication() { // Init your custom dispatcher BEFORE calling IApplication. TYourOSADispatcher::InitUScripting(&TYourOSADispatcher::fgClassDesc); this->IApplication(kFileType, kSignature); // Additional application initialization code, if necessary. }When IYourApplication callsTYourOSADispatcher
::InitUScripting
, theInitUScripting
method creates an instance ofTYourOSADispatcher
and stores a reference to it in the static global variableTYourOSADispatcher
::fgDispatcher
.
- Note
- If you skip this step,
InitUScripting
will create an instance ofTOSADispatcher
rather than an instance of your custom class,TYourOSADispatcher
.