3D PLM Enterprise Architecture |
User Interface - Frame |
Creating Editors in ToolbarHow to create a command header class whose the representation is an editor in a toolbar? |
Use Case |
AbstractThis use case explains how to create a specialized command header. This command header has a customized graphic representation. In place of a check button into a toolbar, the graphic representation is two editors. |
This use case illustrates the creation of a customized command header. In a toolbar, its graphic representation is two editors in place of a check button, the default representation. You will learn how to:
It is a component which must derive from the CATAfrDialogCommandHeader class.
It is a component which must derive from the CATAfrCommandHeaderRep class and which instantiates two CATDlgEditor instances.
The data used by the the graphic representation is the count of lines and points in the document. This data is dependent of the instance of a V5 document.
You can also read
To take full advantage of this article, you can first read "The Command Headers" technical article [3], and precisely the "Creating Customized Command Headers" section.
[Top]
CAAAfrEltCountHeader is a use case of the CAAApplicationFrame.edu framework that illustrates ApplicationFrame framework capabilities.
[Top]
CAAAfrEltCountHeader creates a command header whose the graphic representation is two editors in a toolbar. The following picture shows the header in the "Tools Palette" toolbar [4]:
There is a command header displaying the count of points and lines created in the CAAGeometry document [5]
The CAASysGeomCont component is the component controlling the data used by the graphic representation. It manages the list of elements in the CAAGeometry document through the CAAISysCollection interface.
The CAASysGeomCont component plays the role of controller [3], when a line or a point is created (or deleted), the CAAISysCollection interface is used, and the CAAEAfrCollection class sends a notification, a CAASysCollectionModifNotif class instance.
The EltCount header is an instance of a class, CAAAfrEltCountHeader ,deriving from the CATAfrDialogCommandHeader class, like any command header whose the graphic representation is customized. The following UML diagram describes in details the schema of classes:
CAAAfrEltCountHeader is a component which must implement the CATIAfrCommandHeaderRep interface to provide the customized graphic representation. This interface contains three methods:
CreateCtxMenuRep
: it returns nothingCreateMenuRep
: it returns nothingCreateToolbarRep
: it instantiates an instance of the CAAAfrEltCountRep
class. This class is
described by the following UML diagram:The CAAAfrEltCountRep class creates CATDlgEditor [6] class instances and sets a callback to be inform when lines or points are created or deleted.
The EltCount header is instantiated in the Tools Palette for a workbench of the CAAGeometry document [4].
[Top]
See the section entitled "How to Launch CAAAfrPaletteOptions" in the use case [4] for a detailed description of how this use case should be launched.
[Top]
The CAAAfrEltCountHeader use case is made of several classes mainly located in modules of the CAAApplicationFrame.edu framework:
Windows | InstallRootDirectory\CAAApplicationFrame.edu\ |
Unix | InstallRootDirectory/CAAApplicationFrame.edu/ |
where InstallRootDirectory
is the directory where the CAA CD-ROM
is installed.
CAAAfrCustomizedCommandHeader
.m
module contains
classes to define the EltCount header and its graphic representation.
CAAAfrGeoModel.m
module contains
It is the data extension of the CAAISysCollection interface implemented on the CAASysGeomCont component. Both ( component+interface) are defined in the CAASystem.edu framework. [5]
[Top]
There are three logical steps in CAAAfrEltCountHeader:
[Top]
Count of lines and points are kept by the CAASysGeomCont component which implements the CAAISysCollection interface (Fig.2). When a point/Line is created/deleted in the current CAAGeometry document, a CAASysCollectionModifNotif notification is sent by the callback mechanism [7].
Here the CAAISysCollection interface such as you can see it in the PublicInterfaces directory of the CAASystem.edu framework. Refer to the Creating an Interface use case [8] for more details on its creation.
... class ExportedByCAASysGeoModelInf CAAISysCollection : public CATBaseUnknown { CATDeclareInterface; public: virtual HRESULT GetNumberOfObjects(int * oCount) = 0; virtual HRESULT GetObject (int iRank, CATBaseUnknown ** oObject) = 0; virtual HRESULT AddObject (CATBaseUnknown * iObject) = 0; virtual HRESULT RemoveObject (CATBaseUnknown * iObject) = 0; virtual HRESULT Empty () =0 ; }; ... |
This interface is implemented by the CAASysGeomCont component thanks to the CAAEAfrCollection class extension.
... #include "TIE_CAAISysCollection.h" TIE_CAAISysCollection(CAAEAfrCollection); CATBeginImplementClass(CAAEAfrCollection,DataExtension,CATBaseUnknown,CAASysGeomCont); CATAddClassExtension(CAASysSampCont) ; CATEndImplementClass(CAAEAfrCollection); ... |
The CAAEAfrCollection class states that it implements the CAAISysCollection
interface thanks to the TIE_
CAAISysCollection
macro. This extension class is dedicated to this component, and the CATBeginImplementClass
macro declares that the CAAEAfrCollection class is data
extension class, thanks to the DataExtension
keyword, and that it
extends the component whose main class is CAASysGeomCont. The third parameter
must always be set to CATBaseUnknown, makes no sense, and is unused for
extensions.
The AddObject
adds an element in the CAAGeometry document. _pListe
is a data member of the CAAEAfrCollection class.
... HRESULT CAAEAfrCollection::AddObject (CATBaseUnknown * iObject) { ... _pListe->Append(iObject); ... |
and sends a notification:
... CAASysCollectionModifNotif * pNotifModif = new CAASysCollectionModifNotif(); ::GetDefaultCallbackManager(this)->DispatchCallbacks(pNotifModif,this); pNotifModif->Release() ; pNotifModif = NULL ; ... |
The AddObject
method publishes the notification that states
the list of element in the document is modifying. To do this, the global function GetDefaultCallbackManager
retrieves the callback manager associated by default with the CAAEAfrCollection
class
instance, and this callback uses its DispatchCallbacks
method to
inform its subscribers or listeners that liste is modifying by means of the CAASysCollectionModifNotif
notification created.
Refer to the callback use case [9] which explains
in detail the callback mechanism, and how the CAASysCollectionModifNotif
must be created. You will learn why the CAASysCollectionModifNotif
class instance is deleted just after the DispatchCallbacks
call.
[Top]
The EltCount header is a component which must Object Modeler and C++ derive from CATAfrDialogCommandHeader and must implement the CATIAfrCommandHeaderRep interface (Fig.3). This paragraph is divided in two parts:
Here the CAAAfrEltCountHeader header file:
//ApplicationFrame framework #include "CATAfrDialogCommandHeader.h" class ExportedByCAAAfrCustomizedCommandHeader CAAAfrEltCountHeader : public CATAfrDialogCommandHeader { CATDeclareHeaderResources; CATDeclareClass ; public: CAAAfrEltCountHeader(const CATString & iHeaderName); virtual ~CAAAfrEltCountHeader(); CATCommandHeader * Clone() ; private: CAAAfrEltCountHeader(CATCommandHeader *iHeaderToCopy); CAAAfrEltCountHeader(const CAAAfrEltCountHeader &iObjectToCopy); CAAAfrEltCountHeader & operator = (const CAAAfrEltCountHeader &iObjectToCopy); }; |
CAAAfrEltCountHeader derives from CATAfrDialogCommandHeader.
It is mandatory for a command header whose the graphic representation is
customized. The CATDeclareClass
macro declares that it belongs to a
CAA component. The CATDeclareHeaderResources
macro inserts the
methods to manage the command header resources.
About the mandatory public methods:
constructor
with a reference to a const
CATString
destructor
,
Clone
method inherited from CATCommandHeader and
used to duplicate the command header instance. Refer to the "Customized
Command Header Class Structure" section of the technical article about
the command headers [2]. You will have all the
details about the Clone
method. About the mandatory private methods:
constructor
taking a pointer to a CATCommandHeader
is dedicated to the Clone
method.
constructor
are declared in the private part, and
are not implemented in the source file. This prevents the compiler from
creating them as public without you know.Here the CAAAfrEltCountHeader header file:
#include "CAAAfrEltCountHeader.h" CATImplementClass(CAAAfrEltCountHeader, Implementation, CATAfrDialogCommandHeader, CATNull); CATImplementHeaderResources(CAAAfrEltCountHeader, CATAfrDialogCommandHeader, CAAAfrEltCountHeader); CAAAfrEltCountHeader::CAAAfrEltCountHeader(const CATString & iHeaderName) : CATAfrDialogCommandHeader(iHeaderName){} CAAAfrEltCountHeader::~CAAAfrEltCountHeader(){} CATCommandHeader * CAAAfrEltCountHeader::Clone () { return new CAAAfrEltCountHeader(this); } CAAAfrEltCountHeader::CAAAfrEltCountHeader(CATCommandHeader * iHeaderToCopy): CATAfrDialogCommandHeader(iHeaderToCopy) {} |
CATImplementClass
macro makes the class CAAAfrEltCountHeader a component main class (Implementation
)
that OM-derives [10] from CATAfrDialogCommandHeader. CATImplementHeaderResources
macro is used in conjunction
with the CATDeclareHeaderResources
macro in the header file. It
states that the CAAAfrEltCountHeader class derives from CATAfrDialogCommandHeader,
and that its associated resource file names use the class name: CAAAfrEltCountHeader.CATNls and
CAAAfrEltCountHeader.CATRsc
respectively. The base class name set as second argument helps to use
resource concatenation. The third argument could be set to the name of
another class that is associated with resource files that use its class
name, or to the name, without suffix, of an already existing resource file
pair.Clone
method returns a copy construction instance of
this.CATIAfrCommandHeaderRep implementation
This interface of the ApplicationFrame framework must be implemented by all command header whose the graphic representation is customized. On Fig.3, you see that the CAAEAfrCommandHeaderRepForEltCount class is the implementation of this interface for the CAAAfrEltCountHeader component.
Here the CAAEAfrCommandHeaderRepForEltCount header file
... class CAAEAfrCommandHeaderRepForEltCount: public CATBaseUnknown { CATDeclareClass; public: CAAEAfrCommandHeaderRepForEltCount(); virtual CAAEAfrCommandHeaderRepForEltCount(); virtual HRESULT CreateToolbarRep (const CATDialog * iParent, CATAfrCommandHeaderRep ** oHdrRep) ; virtual HRESULT CreateMenuRep (const CATDialog * iParent, CATAfrCommandHeaderRep ** oHdrRep) ; virtual HRESULT CreateCtxMenuRep (const CATDialog * iParent, CATAfrCommandHeaderRep ** oHdrRep) ; private: CAAEAfrCommandHeaderRepForEltCount(const CAAEAfrCommandHeaderRepForEltCount&iObjectToCopy); CAAEAfrCommandHeaderRepForEltCount& operator = (const CAAEAfrCommandHeaderRepForEltCount&iObjectToCopy); }; |
The CATDeclareClass
macro declares that CAAEAfrCommandHeaderRepForEltCount
belongs to a component. CreateToolbarRep
, CreateMenuRep
,
and CreateCtxMenuRep
are methods of the CATIAfrCommandHeaderRep
interface.
Here the CAAEAfrCommandHeaderRepForEltCount source file
... #include <TIE_CATIAfrCommandHeaderRep.h> TIE_CATIAfrCommandHeaderRep(CAAEAfrCommandHeaderRepForEltCount); CATImplementClass(CAAEAfrCommandHeaderRepForEltCount, DataExtension, CATBaseUnknown, CAAAfrEltCountHeader); }; CAAEAfrCommandHeaderRepForEltCount:: CAAEAfrCommandHeaderRepForEltCount():CATBaseUnknown(){} CAAEAfrCommandHeaderRepForEltCount::~CAAEAfrCommandHeaderRepForEltCount(){} ... |
The CAAEAfrCommandHeaderRepForEltCount class states that it
implements the CATIAfrCommandHeaderRep
interface thanks to the TIE_CATIAfrCommandHeaderRep
macro. The CATImplementClass
macro declares that the CAAEAfrCommandHeaderRepForEltCount class is a
data extension, thanks to the DataExtension
keyword, that extends
CAAAfrEltCountHeader. The third argument must always be set as CATBaseUnknown
or CATNull for any kind of extension. The class constructor and the
class destructor are empty.
... HRESULT CAAEAfrCommandHeaderRepForEltCount::CreateToolbarRep (const CATDialog * iParent,CATAfrCommandHeaderRep ** oHdrRep) { HRESULT rc = E_FAIL ; if ( oHdrRep != NULL ) { CATString Name = "CAAAfrEltCountRepId" ; CAAAfrEltCountRep * pEltCountRep = new CAAAfrEltCountRep(iParent,Name); *oHdrRep = (CATAfrCommandHeaderRep *) pEltCountRep ; rc = S_OK ; } return rc ; } ... |
The CreateToolbarRep
method provides the class instantiating the
graphic representation of the EltCount header. This method is called each time the header
command must be represented in a toolbar.
The CAAAfrEltCountRep class is a CATCommand class (Fig.4) which instantiates the graphic representation of the EltCount header (two CATDlgEditor instances). It is detailed in the Creating the Component Instantiating the Graphic Representation section, just below.
iParent
is a CATDialog component. It will be the dialog
parent of the CATDlgEditor instances. Name
is the command name
of the CAAAfrEltCountRep class.
You can set the same identifier for all CAAAfrEltCountRep class
instances.
You do not have to take care of the CAAAfrEltCountRep class instance, the
returned value, oHdrRep
is kept by the frame application, and the
deletion of this pointer is automatically done.
... HRESULT CAAEAfrCommandHeaderRepForEltCount:: CreateMenuRep (const CATDialog * iParent,CATAfrCommandHeaderRep ** oHdrRep) { return E_FAIL ; } HRESULT CAAEAfrCommandHeaderRepForEltCount:: CreateCtxMenuRep (const CATDialog * iParent,CATAfrCommandHeaderRep ** oHdrRep) { return E_FAIL; } |
The EltCount header has no representation in the menu bar or in a contextual
menu, so CreateMenuRep
and CreateCtxMenuRep
return
E_FAIL.
[Top]
This class is the CAAAfrEltCountRep class. Its main roles are:
Set a callback to be informed when a modification occurs in the list of elements controlled by the CAASysGeomCont component
Create two CATDlgEditor instances
Change the contents of the CATDlgEditor instances when a notification is sent by the CAASysGeomCont component
Here the CAAAfrEltCountRep header file:
... class CAAAfrEltCountRep : public CATAfrCommandHeaderRep { public: CAAAfrEltCountRep(const CATDialog * iParent, CATString & iCommandName); virtual ~CAAAfrEltCountRep(); HRESULT Build(); private: void ModifiedCB(CATCallback iEvent, void * , CATNotification * iNotification, CATCallbackEvent iData, CATSubscriberData iCallBack); HRESULT ValuateEditors() ; CAAAfrEltCountRep(const CAAAfrEltCountRep &iObjectToCopy); CAAAfrEltCountRep & operator = (const CAAAfrEltCountRep &iObjectToCopy); private: CATDlgEditor * _pEdtPoint; CATDlgEditor * _pEdtLine; CAAISysCollection * _piSysCollection ; }; |
The CAAAfrEltCountRep class derives from the CATAfrCommandHeaderRep class (Fig.4)
The Build
method is a method of the CATAfrCommandHeaderRep
class. You must overwrite this method. In the CATAfrCommandHeaderRep
class it is a pure virtual method. This method is called by the frame
application just after the CAAAfrEltCountRep class instantiation, in
other words just after the CreateToolbarRep
method call.
In private methods
The ModifiedCB
method is a callback method
called when the CAASysGeomCont component sends a CAASysCollectionModifNotif
notification.
The ValuateEditors
is called by Build
and ModifiedCB
methods to modify the current value of _pEdtPoint
and _pEdtLine
,
the data members
In data member
_pEdtPoint
and _pEdtLine,
two CATDlgEditor
class
instance created in the Build
method
_piSysCollection
a CAAISysCollection
interface pointer on the CAASysGeomCont component of the current
CAAGeometry document.
Here the CAAAfrEltCountRep source file:
The First step consists in to retrieve the CAASysGeomCont component.
Refer to the code file for details about pContainer
. It is
useless for the use case to detail this part of code.
... CAAAfrEltCountRep::CAAAfrEltCountRep(const CATDialog * iParent,CATString & iCommandName): CATAfrCommandHeaderRep(iParent,iCommandName), _piSysCollection(NULL),_pEdtPoint(NULL),_pEdtLine(NULL) { ... rc = pContainer->QueryInterface(IID_CAAISysCollection, (void**)&_piSysCollection); ... |
The second and last step consists in to set a callback method to be informed when the CAASysGeomCont component will send a CAASysCollectionModifNotif notification.
... if ( NULL != _piSysCollection ) { ::AddCallback(this, _piSysCollection, "CAASysCollectionModifNotif", (CATSubscriberMethod)&CAAAfrEltCountRep::ModifiedCB, NULL); } } |
AddCallback
is a static global function whose the
parameters are:
this:
The subscriber_piSysCollection
: The publisher CAASysCollectionModifNotif
:
The notification class sent by
the publisherModifiedCB:
The method of this which is called when a CAASysCollectionModifNotif
notification is sentNULL:
No parameters for the callback methodThe Destructor class
... CAAAfrEltCountRep::~CAAAfrEltCountRep() { if ( NULL != _piSysCollection ) { ::RemoveSubscriberCallbacks(this, _piSysCollection); _piSysCollection->Release(); _piSysCollection = NULL ; } if ( NULL != _pEdtPoint ) { _pEdtPoint->RequestDelayedDestruction(); _pEdtPoint = NULL ; } if ( NULL != _pEdtLine ) { _pEdtLine->RequestDelayedDestruction(); _pEdtLine = NULL ; } }... |
At the end, the callback set in the constructor must be removed from the callback manager [9], and the CATDlgEditor instances must be released.
You must overwrite this method. The goal of this method is to create the graphic representation and to initialize it.
...
HRESULT CAAAfrEltCountRep::Build()
{
// Creation of the dialog object
const CATDialog * pParent = NULL ;
GetDialogParent(&pParent);
_pEdtPoint = new CATDlgEditor((CATDialog *)pParent, "CAAAfrEdtPoint",
CATDlgEdtReadOnly);
_pEdtLine = new CATDlgEditor((CATDialog *)pParent, "CAAAfrEdtLine",
CATDlgEdtReadOnly);
// Sets the value in the editors
|
The first step consists in to retrieve the Dialog parent of the graphic
representation to create. This information is kept by the CATAfrCommandHeaderRep
class, and retrieved by its GetDialogParent
method. Then you can
create CATDlgEditor class instance using, pParent
, the
Dialog parent. The second argument of the CATDlgEditor class is the
identifier of the dialog object, and the last one is the type of editor (CATDlgEdtReadOnly
).
Then, you call ValuateEditors
to initialize the contents of the
editors.
The ModifyCB
method is called when the CAASysGeomCont component sends the
CAASysCollectionModifNotif notification. It informs the CAAAfrEltCountRep class instance, that
the count of lines/points on the CAASysGeomCont component has been changed by someone. It
is done thanks to the ValuateEditors
method.
...
void CAAAfrEltCountRep::ModifiedCB(CATCallback,
void *,
CATNotification * iNotification,
CATCallbackEvent,
CATSubscriberData)
{
|
This method consists in to retrieve the list of elements
into the CAAGeometry document, and modify, thanks to the SetText
method, the current value on _pEdtPoint
and _pEdtLine
,
the two data
members of the CAAAfrEltCountRep class.
... HRESULT CAAAfrEltCountRep::ValuateEditors() { ... int nbeltcont = 0 ; _piSysCollection->GetNumberOfObjects(&nbeltcont); int NbPoint = 0 ; int NbLine = 0 ; for (int i=1 ; i <= nbeltcont ; i++) { CATBaseUnknown * pObject = NULL ; rc = _piSysCollection->GetObject(i,&pObject); if (SUCCEEDED(rc)) { CAAISysPoint * piSysPoint = NULL; rc = pObject ->QueryInterface(IID_CAAISysPoint, (void**)&piSysPoint); if (SUCCEEDED(rc)) { // it's a point NbPoint ++ ; piSysPoint -> Release(); piSysPoint = NULL ; } CAAISysLine * piSysLine = NULL; rc = pObject ->QueryInterface(IID_CAAISysLine, (void**)&piSysLine); if (SUCCEEDED(rc)) { // it's a line NbLine ++ ; ... CATUnicodeString stNbPoint ; stNbPoint.BuildFromNum(NbPoint) ; CATUnicodeString stNbLine ; stNbLine.BuildFromNum(NbLine) ; _pEdtPoint->SetText(stNbPoint); _pEdtLine ->SetText(stNbLine); ... |
[Top]
This use case has explained how to create a command header whose the graphic representation is customized:
The component controlling the data used by the graphic representation is dependent of the document.
[Top]
Version: 1 [Fev 2004] | Document created |
[Top] |
Copyright © 2004, Dassault Systèmes. All rights reserved.