3D PLM Enterprise Architecture |
User Interface - Frame |
Creating an Add-inCustomizing a workshop or a workbench |
Use Case |
AbstractThis article shows how to create an add-in. |
This use case is intended to show how to create an add-in to a given workbench. An add-in is an object that gathers commands to work on the document and arrange them in one or several toolbars and menu items. Command headers are used to make the link between the add-in and the commands.
[Top]
CAAAfrGeoOperationAdn is a use case of the CAAApplicationFrame.edu framework that illustrates the ApplicationFrame framework capabilities.
[Top]
The CAAAfrGeoOperationAdn use case creates an add-in to the CAA Geometrical Creation workbench for the CAAGeometry document. Is is made up of:
The Operation toolbar. It includes three commands: Union, Subtract, and Fillet. |
It includes three commands: Union, Subtract, and Fillet and a separator just after Conferencing. |
[Top]
See the section entitled "How to Launch the CAAGeometry Use Case" in the "The CAAGeometry Sample" use case for a detailed description of how this use case should be launched.
Do not type the module name on the command line, but type CNEXT instead. When the application is ready, do the following:
[Top]
The CAAAfrGeoOperationAdn use case is made of a single class named CAAAfrGeoOperationAdn located in the CAAAfrGeoCreationWkbAddin.m module of the CAAApplicationFrame.edu framework:
Windows | InstallRootDirectory\CAAApplicationFrame.edu\CAAAfrGeoCreationWkbAddin.m\ |
Unix | InstallRootDirectory/CAAApplicationFrame.edu/CAAAfrGeoCreationWkbAddin.m/ |
where InstallRootDirectory
is the directory where the CAA CD-ROM
is installed.
[Top]
To create the add-in, you should create the module directory to store the add-in code along with its two subdirectories LocalInterfaces and src. For this example, this directory is named CAAAfrGeoOperationAdn.m and can be found in the CAAApplicationFrame.edu framework. Then you will need to create the following files.
In the CAAAfrGeoOperationAdn.m\LocalInterfaces directory: | |
CAAAfrGeoOperationAdn.h | The header file of the add-in description class |
In the CAAAfrGeoOperationAdn.m\src directory: | |
CAAAfrGeoOperationAdn.cpp | The header file of the add-in description class |
In the dictionary, that is the CNext\code\dictionary directory, referenced at run time using the CATDictionaryPath environment variable, create or update: | |
CAAApplicationFrame.edu.dico | The interface dictionary |
In the CNext\resources\msgcatalog directory, referenced at run time using the CATMsgCatalogPath environment variable: | |
CAAAfrGeoOperationAdn.CATNls | The add-in message file |
CAAAfrGeoOperationAdnHeader.CATNls and CAAAfrGeoOperationAdnHeader.CATRsc |
The command header resource files |
To create the CAA Geometrical Creation workbench, there are four steps:
# | Step | Where |
---|---|---|
1 | Create the add-in description class | LocalInterfaces and src |
2 | Create the command headers | CreateCommands method |
3 | Create the add-in and arrange the commands | CreateToolbars method |
4 | Provide the resources | Resource files |
[Top]
#include "CATBaseUnknown.h" // Needed to derive from CATBaseUnknown class CATCmdContainer; // Needed by CreateToolbars class CAAAfrGeoOperationAdn : public CATBaseUnknown { CATDeclareClass; public: CAAAfrGeoOperationAdn(); virtual ~CAAAfrGeoOperationAdn(); void CreateCommands(); CATCmdContainer * CreateToolbars(); }; |
// Local Framework #include "CAAAfrGeoOperationAdn.h" // ApplicationFrame Framework #include <CATCreateWorkshop.h> // To use NewAccess - SetAccess - SetAccessChild ... // Declaration of a new Command Header Class #include "CATCommandHeader.h" // See Creating the Command Headers MacDeclareHeader(CAAAfrGeoOperationAdnHeader); CATImplementClass(CAAAfrGeoOperationAdn, DataExtension, CATBaseUnknown, CAAAfrGeoOperationAddin); #include <TIE_CAAIAfrGeoCreationWkbAddin.h> TIE_CAAIAfrGeoCreationWkbAddin(CAAAfrGeoOperationAdn); CAAAfrGeoOperationAdn::CAAAfrGeoOperationAdn() {} CAAAfrGeoOperationAdn::~CAAAfrGeoOperationAdn() {} void CAAAfrGeoOperationAdn::CreateCommands() { ... // See Creating the Command Headers } CATCmdContainer * CAAAfrGeoOperationAdn::CreateToolbars() { ... // See Creating the Toolbar and Arranging the Commands } |
The CAAAfrGeoOperationAdn class states that it implements the CAAIAfrGeoCreationWkbAddin
interface thanks to the TIE_CAAIAfrGeoCreationWkbAddin
macro. The
CATImplementClass
macro declares that the CAAAfrGeoOperationAdn
class is a data extension, thanks to the DataExtension
keyword,
that extends CAAAfrGeoOperationAddin. The third argument must always
be set as CATBaseUnknown or CATNull for any kind of extension. The name
of the latetype, the fourth argument of the CATImplementClass macro, mustn't be
the same as an existing C++ class name or an existing latetype name.
Update the interface dictionary, that is a file named, for example, CAAApplicationFrame.dico, whose directory's pathname is concatenated at run time in the CATDictionaryPath environment variable, and containing the following declaration to state that the CAAAfrGeoOperationAddin component implements the CAAIAfrGeoCreationWkbAddin interface, and whose code is located in the libCAAAfrGeoCreationWkbAddin shared library or DLL.
CAAAfrGeoOperationAddin CAAIAfrGeoCreationWkbAddin libCAAAfrGeoCreationWkbAddin |
Note that the component main class name is used to refer to the component in the interface dictionary, and never the extension class names. Note also that the shared library or DLL to associate with the component/interface pair is the one that contains the code created by the call to the TIE macro (This is generally the same library than the one that contains the interface implementation code, since the TIE macro is usually included in the extension class source file.) This is because when a client asks a component for an interface pointer, the TIE class is instantiated first, and it either retrieves the existing instance of the appropriate extension class, or otherwise instantiates it.
[Top]
This is done by the CreateCommands
method. Each command
available in your add-in must have a command header. A command header is an
instance of a command header class, and different commands can share the same
command header class to create their command header. Refer to The Command
Headers for more details.
A command header class is created for the commands, named
CAAAfrGeoOperationAdnHeader using the MacDeclareHeader
macro.
#include "CATCommandHeader.h" MacDeclareHeader(CAAAfrGeoOperationAdnHeader); |
The MacDeclareHeader
macro creates the header file and the
source file for the CAAAfrGeoOperationAdnHeader class, and associates with
this class the resource files CAAAfrGeoOperationAdnHeader.CATNls and
CAAAfrGeoOperationAdnHeader.CATRsc. See Providing the
Resources.
CreateCommands
method. This method should contain one instantiation statement of the
command header class per command header. Each statement has the following
form, for example for the Union command.
void CAAAfrGeoOperationAdn::CreateCommands() { ... new CAAAfrGeoOperationAdnHeader("Union", "CommandLib", "UnionCmd", (void *)NULL): ... } |
The command header constructor has the following arguments:
Union
is the identifier you need to assign to the command
header. It will be used afterwards:
CommandLib
is the name of the shared library or DLL
containing the Union command's code, without the prefix lib, and without
the suffix depending on the operating system.UnionCmd
is the name of the Union command class[Top]
Finally, we'll create the toolbar and arrange the commands. This is the job
of the CreateToolbars
method.
CATCmdContainer * CAAAfrGeoOperationAdn::CreateToolbars() { NewAccess(CATCmdContainer,pCAAAfrOperationTlb,CAAAfrOperationTlb); NewAccess(CATCmdStarter,pCAAAfrTUnionStr,CAAAfrTUnionStr); SetAccessCommand(pCAAAfrTUnionStr,"CAAAfrUnionHdr"); SetAccessChild(pCAAAfrOperationTlb,pCAAAfrTUnionStr); NewAccess(CATCmdStarter,pCAAAfrTSubstractStr,CAAAfrTSubstractStr); SetAccessCommand(pCAAAfrTSubstractStr,"CAAAfrSubstractHdr"); SetAccessNext(pCAAAfrTUnionStr,pCAAAfrTSubstractStr); NewAccess(CATCmdStarter,pCAAAfrTFilletStr,CAAAfrTFilletStr); SetAccessCommand(pCAAAfrTFilletStr,"CAAAfrFilletHdr"); SetAccessNext(pCAAAfrTSubstractStr,pCAAAfrTFilletStr); AddToolbarView(pCAAAfrOperationTlb,-1,Right); // Invisible toolbar ... } |
Here is what's happen:
NewAccess
macro. pCAAAfrOperationTlb is the variable used to handle the Operation toolbar command container
instance pointer, and CAAAfrOperationTlb is the identifier used
to refer to it in the add-in resource files. This identifier must be unique
among all the toolbar identifiers that can be found within the application [1].
The Operation toolbar default location is defined using the AddToolbarView
macro, where -1
means that the toolbar is invisible by default
(1
means visible), and Right
means that the
toolbar is docked at the right side of the application window.NewAccess
macro. pCAAAfrTUnionStr is the
variable used to handle a pointer to that instance, and CAAAfrTUnionStr
is its identifier.SetAccessCommand
macro. The second parameter is
the Union command header identifier defined as the first parameter of
the command header constructor. Refer to Creating the
Command HeadersProceed in the same way for the other commands, except that they are set as
next of one another using the SetAccessNext
macro.
CATCmdContainer * CAAAfrGeoOperationAdn::CreateToolbars() { ... NewAccess(CATCmdContainer,pCAAAfrOperationMbr,CAAAfrOperationMbr); NewAccess(CATCmdContainer,pCAAAfrOperationToolsMnu,CATAfrToolsMnu); SetAccessChild(pCAAAfrOperationMbr,pCAAAfrOperationToolsMnu); NewAccess(CATCmdSeparator,pCAAAfrOperationToolsSep,CAAAfrOperationToolsSep); SetAccessChild(pCAAAfrOperationToolsMnu,pCAAAfrOperationToolsSep); NewAccess(CATCmdStarter,pCAAAfrMUnionStr,CAAAfrMUnionStr); SetAccessCommand(pCAAAfrMUnionStr,"CAAAfrUnionHdr"); SetAccessNext(pCAAAfrOperationToolsSep,pCAAAfrMUnionStr); NewAccess(CATCmdStarter,pCAAAfrMSubstractStr,CAAAfrMSubstractStr); SetAccessCommand(pCAAAfrMSubstractStr,"CAAAfrSubstractHdr"); SetAccessNext(pCAAAfrMUnionStr,pCAAAfrMSubstractStr); NewAccess(CATCmdStarter,pCAAAfrMFilletStr,pCAAAfrMFilletStr); SetAccessCommand(pCAAAfrMFilletStr,"CAAAfrFilletHdr"); SetAccessNext(pCAAAfrMSubstractStr,pCAAAfrMFilletStr); SetAddinMenu(pCAAAfrOperationTlb,pCAAAfrOperationMbr); ... } |
Here is what's happen:
pCAAAfrOperationMbr
CATAfrToolsMnu
name,
a container with the same name is created.NewAccess
macro in using the CATCmdSeparator
keyword.NewAccess
macro. pCAAAfrMUnionStr is the
variable used to handle a pointer to that instance, and CAAAfrMUnionStr is its identifier.SetAccessCommand
macro. The second parameter is
the Union command header identifier defined as the first parameter of
the command header constructor. Refer to Creating the
Command HeadersProceed in the same way for the other commands, except that they are set as
next of one another using the SetAccessNext
macro.
The container, pCAAAfrOperationMbr
, declared as menu
thanks to the SetAddinMenu
method. The first argument of this
method, pCAAAfrOperationTlb
, is the first chained toolbar,
those returned by the method-see the next section. The second argument is
the container itself pCAAAfrOperationMbr
.
CATCmdContainer * CAAAfrGeoOperationAdn::CreateToolbars() { ... return pCAAAfrOperationTlb ; } |
The first chained toolbar, pCAAAfrOperationTlb
, is returned by this method.
[Top]
You should provide the resources for the toolbar, the menu and for all its commands. They are classified into the following:
More about Internationalization and resources can be found in Internationalizing Your Client Application.
[Top]
I create a workbench addin but it's not available, or a system failure occurs. | |
Check your latetype name in the CATImplementClass macro. The latetype name mustn't be an existing C++ class name or an existing latetype name. |
I create a command starter for a command, and I arrange it in the menu bar or in a toolbar, but the command doesn't display in the menu bar or toolbar where I place it. | |
The command starter is not associated with a command header, and is thus not displayed, since the command cannot be launched without command header. | |
Check your CreateToolbars method. The command
starter must be associated with a command header for the command you want
to display thanks to the SetAccessCommand macro. |
[Top]
An add-in gathers commands to customize a workshop or a workbench without you need to modify the workshop or workbench's code. You simply need to implement the interface that the workshop or workbench exposes for add-ins.
[Top]
[1] | Checklist for CAA V5 C++ Naming Rules |
[2] | Creating Resources for Workshops and Workbenches |
[3] | Creating Resources for Command Headers |
[Top] |
Version: 1 [Jan 2000] | Document created |
Version: 2 [Sep 2002] | Menu item addition |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.