3D PLM Enterprise Architecture

User Interface - Frame

Creating a Combo Command Header

How to create a command header class whose the representation is a combo in a toolbar?
Use Case

Abstract

This 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 a combo. 


What You Will Learn With This Use Case

This use case illustrates the creation of a customized command header. In a toolbar, its graphic representation is a combo 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 a CATDlgCombo instance. 

The data used by the the graphic representation is the value of the current color in the combo. This data is dependent of the instance of a V5 document. 

You can also read the CAAAfrMRUHeader use case [1] which presents another customized command header. In this case, the graphic representation is a dynamic list of push items in a menu of the menu bar. Contrarily to the current use case, the data (a list of string) is independent of the document. 

To take full advantage of this article, you can first read "The Command Headers" technical article [2], and precisely the "Creating Customized Command Headers" section.  

[Top]

The CAAAfrComboColorHeader Use Case

CAAAfrComboColorHeader is a use case of the CAAApplicationFrame.edu framework that illustrates ApplicationFrame framework capabilities.

[Top]

What Does CAAAfrComboColorHeader Do

CAAAfrComboColorHeader creates a command header whose the graphic representation is a combo color in a toolbar. The following picture shows the header in the Customized Command Header toolbar:

Fig.1 The combo header

If you drop down the combo, you have the choice between ten colors:

Fig.2 Ten values of the combo
The combo needs two information:
  • The available colors in the combo. These ten color are "hard" coded.  
  • The current selected color. This information is kept by a component linked to the CAAGeometry document. This component is the CAASysGeomRootObj component. Refer to the referenced article for complete details on the CAAGeometry document and the CAASysGeomRootObj component [3].

The CAASysGeomRootObj component is the component controlling the data used by the graphic representation. It manages the current value of the color through the CAAIAfrTemporaryObjectColor interface. This interface enables us to get and set the current color. However the color is not persistent (not streamed) because the CAAGeometry document is not "streamable".

Fig.3 Component Controlling the Data Used by the Graphic Representation - UML Diagram

The CAASysGeomRootObj component plays the role of controller [2], when the current color value is modified using the CAAIAfrTemporaryObjectColor interface, the CAAEAfrTemporaryObjectColor implementation class sends a notification, a CAAAfrComboColorNotification class instance. 

The combo header class is an instance of a class 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:

Fig.4 Combo Header - UML Diagram

CAAAfrComboColorHeader is a component which must implement the CATIAfrCommandHeaderRep interface to provide the customized graphic representation. This interface contains three methods:

Fig.5 Class Instantiating the Graphic Representation - UML Diagram

The CAAAfrComboRep class creates a CATDlgCombo [4] class instance and sets a callback to be inform when the current color is changed. Therefore, if there are several instances of the CAAAfrComboColorHeader class in the same document, see the How to Launch CAAAfrComboColorHeader section, all the representations will be automatically updated. 

The combo header is instantiated in an Add-in of the workshop of the CAAGeometry document. The last step of the Step by Step section explains this instantiation.

[Top]

How to Launch CAAAfrComboColorHeader

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]

Where to Find the CAAAfrComboColorHeader Code

The CAAAfrComboColorHeader use case is made of several classes located in three 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.

The CAAAfrCustCommandHdrModel.m module contains classes to define (update) the component controlling the current color.

The CAAAfrCustomizedCommandHeader.m module contains classes to define the combo color header:

The CAAAfrGeoWksAddin2.m module contains an Add-in of the CAAGeometry workshop 

[Top]

Step-by-Step

There are four logical steps in CAAAfrComboColorHeader:

  1. Creating the Component Representing the Current Color in the Combo
  2. Creating the Component Representing the Command Header 
  3. Creating the Class Instantiating the Graphic Representation
  4. Instantiating the Combo Header Class

[Top]

Creating the Data Model Representing the Current Color in the Combo

The current color is kept by the CAASysGeomRootObj component which implements the CAAIAfrTemporaryObjectColor interface to set and retrieve the current color (Fig.3). When the color is modified on the component (Set method) a CAAAfrComboColorNotification notification is sent by the callback mechanism [5]. 

Here the CAAIAfrTemporaryObjectColor interface such as you can see it in the PublicInterfaces directory of the CAAApplicationFrame.edu framework. Refer to the Creating an Interface use case [6] for more details on its creation. 

...
#include <CATBaseUnknown.h>      

class ExportedByCAAAfrCustCommandHdrModel CAAIAfrTemporaryObjectColor: public CATBaseUnknown
{
  CATDeclareInterface;

  public:
      virtual HRESULT GetCurrentColor(int & oRed, int & oGreen, int & oBlue) const = 0 ;
      virtual HRESULT SetCurrentColor(int & iRed, int & iGreen, int & iBlue) = 0 ;
};
...

This interface is implemented by the CAASysGeomRootObj component thanks to the CAAEAfrTemporaryObjectColor class extension. 

...
#include "TIE_CAAIAfrTemporaryObjectColor.h"              
TIE_CAAIAfrTemporaryObjectColor(CAAEAfrTemporaryObjectColor); 

CATImplementClass (CAAEAfrTemporaryObjectColor,DataExtension, 
                          CATBaseUnknown, CAASysGeomRootObj);
...

The CAAEAfrTemporaryObjectColor class states that it implements the CAAIAfrTemporaryObjectColor interface thanks to the TIE_CAAIAfrTemporaryObjectColor macro. This extension class is dedicated to this component, and the CATImplementClass macro declares that the CAAEAfrTemporaryObjectColor class is data extension class, thanks to the DataExtension keyword, and that it extends the component whose main class is CAASysGeomRootObj. The third parameter must always be set to CATBaseUnknown, makes no sense, and is unused for extensions. 

In the constructor class, you can see that the default value is red ( 255,0,0). 

...
CAAEAfrTemporaryObjectColor::CAAEAfrTemporaryObjectColor(): CATBaseUnknown()
                            
{    
   _RedComp   = 255   ;
   _GreenComp = 10    ;
   _BlueComp  = 0     ; 
}

CAAEAfrTemporaryObjectColor::~CAAEAfrTemporaryObjectColor(){}
...

The GetCurrentColor returns the three data members representing the red, blue and green components of the current color. 

...
HRESULT CAAEAfrTemporaryObjectColor::GetCurrentColor(int & oRed, int & oGreen, int & oBlue) const
{
   oRed   = _RedComp ;
   oGreen = _GreenComp ;
   oBlue  = _BlueComp ; 

   return (S_OK) ;
}
...

The SetCurrentColor valuates the three data members using the input argument:

...
HRESULT CAAEAfrTemporaryObjectColor::SetCurrentColor(int & iRed, int & iGreen, int & iBlue) 
{
   _RedComp   = iRed   ;
   _GreenComp = iGreen;
   _BlueComp  = iBlue; 
...

and sends a notification:

...
    CATCallbackManager * pCBManager = ::GetDefaultCallbackManager(this) ;
    if ( NULL != pCBManager )
    {
         CAAAfrComboColorNotification * pNotification = new CAAAfrComboColorNotification();
         pCBManager->DispatchCallbacks(pNotification,this);
         pNotification->Release(); pNotification = NULL ;
    }
   return (S_OK) ;
}
...

The SetCurrentColor method publishes the notification that states the current color is modifying. To do this, the global function GetDefaultCallbackManager retrieves the callback manager associated by default with the CAAEAfrTemporaryObjectColor class instance, and this callback uses its DispatchCallbacks method to inform its subscribers or listeners that the current color is modifying by means of the CAAAfrComboColorNotification notification created.

Refer to the callback use case [7] which explains in details the callback mechanism, and how the CAAAfrComboColorNotification must be created. You will learn why the CAAAfrComboColorNotification class instance is deleted just after the DispatchCallbacks call. See the constructor of the CAAAfrComboColorRep class. 

[Top]

Creating the Component Representing the Command Header 

The combo header is a component which must Object Modeler and C++ derive from CATAfrDialogCommandHeader and must implement the CATIAfrCommandHeaderRep interface (Fig.4). This paragraph is divided in two parts:

Component Creation

Here the CAAAfrComboColorHeader header file:

//ApplicationFrame framework
#include "CATAfrDialogCommandHeader.h"

class ExportedByCAAAfrCustomizedCommandHeader CAAAfrComboColorHeader : public CATAfrDialogCommandHeader
{
  CATDeclareHeaderResources;
  CATDeclareClass ;

  public:
    CAAAfrComboColorHeader(const CATString & iHeaderName);

    virtual ~CAAAfrComboColorHeader();
    CATCommandHeader * Clone() ;
      
  private:
    CAAAfrComboColorHeader(CATCommandHeader *iHeaderToCopy);
    CAAAfrComboColorHeader(const CAAAfrComboColorHeader &iObjectToCopy);
    CAAAfrComboColorHeader & operator = (const CAAAfrComboColorHeader &iObjectToCopy);
};

CAAAfrComboColorHeader 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:

About the mandatory private methods:

Here the CAAAfrComboColorHeader header file:

#include "CAAAfrComboColorHeader.h"

CATImplementClass(CAAAfrComboColorHeader, 
                  Implementation,
                  CATAfrDialogCommandHeader, 
                  CATNull);

CATImplementHeaderResources(CAAAfrComboColorHeader,  
			 CATAfrDialogCommandHeader,          
			 CAAAfrComboColorHeader);            

CAAAfrComboColorHeader::CAAAfrComboColorHeader(const CATString & iHeaderName) : 
    CATAfrDialogCommandHeader(iHeaderName){}

CAAAfrComboColorHeader::~CAAAfrComboColorHeader(){}

CATCommandHeader * CAAAfrComboColorHeader::Clone ()                                  
{ 
    return new CAAAfrComboColorHeader(this); 
}   

CAAAfrComboColorHeader::CAAAfrComboColorHeader(CATCommandHeader * iHeaderToCopy):
                          CATAfrDialogCommandHeader(iHeaderToCopy)
{}	                  

CATIAfrCommandHeaderRep implementation

This interface of the ApplicationFrame framework must be implemented by all command header whose the graphic representation is customized. On Fig.4, you see that the CAAEAfrCommandHeaderRepForComboColor class is the implementation of this interface for the CAAAfrComboColorHeader component. 

Here the CAAEAfrCommandHeaderRepForComboColor header file

...
class CAAEAfrCommandHeaderRepForComboColor : public CATBaseUnknown
{
  CATDeclareClass;
public:
  
  CAAEAfrCommandHeaderRepForComboColor();
  virtual ~CAAEAfrCommandHeaderRepForComboColor();
  
  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:
  CAAEAfrCommandHeaderRepForComboColor(const CAAEAfrCommandHeaderRepForComboColor &iObjectToCopy);
  CAAEAfrCommandHeaderRepForComboColor & operator = (const CAAEAfrCommandHeaderRepForComboColor &iObjectToCopy);
};      

The CATDeclareClass macro declares that CAAEAfrCommandHeaderRepForComboColor belongs to a component. CreateToolbarRep, CreateMenuRep, and CreateCtxMenuRep are methods of the CATIAfrCommandHeaderRep interface.

Here the CAAEAfrCommandHeaderRepForComboColor source file

...
#include <TIE_CATIAfrCommandHeaderRep.h>
TIE_CATIAfrCommandHeaderRep(CAAEAfrCommandHeaderRepForComboColor);

CATImplementClass(CAAEAfrCommandHeaderRepForComboColor, 
                  DataExtension,
                  CATBaseUnknown, 
                  CAAAfrComboColorHeader);
};
CAAEAfrCommandHeaderRepForComboColor::
           CAAEAfrCommandHeaderRepForComboColor():CATBaseUnknown(){}

CAAEAfrCommandHeaderRepForComboColor::~CAAEAfrCommandHeaderRepForComboColor(){}
...      

The CAAEAfrCommandHeaderRepForComboColor class states that it implements the CATIAfrCommandHeaderRep interface thanks to the TIE_CATIAfrCommandHeaderRep macro. The CATImplementClass macro declares that the CAAEAfrCommandHeaderRepForComboColor class is a data extension, thanks to the DataExtension keyword, that extends CAAAfrComboColorHeader. 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 CAAEAfrCommandHeaderRepForComboColor::CreateToolbarRep
         (const CATDialog * iParent,CATAfrCommandHeaderRep ** oHdrRep)
{
   HRESULT rc = E_FAIL ;

   if ( oHdrRep != NULL )
   {
      CATString Name = "CAAAfrComboRepId" ;
      CAAAfrComboRep * pComboRep = new CAAAfrComboRep(iParent,Name);

      *oHdrRep = (CATAfrCommandHeaderRep *) pComboRep ;
      rc = S_OK ;
   }

   return rc ;
}
...      

The CreateToolbarRep method provides the class instantiating the graphic representation of the combo header. This method is called each time the header command must be represented in a toolbar.

The CAAAfrComboRep class is a CATCommand class (Fig.5) which instantiates the graphic representation of the combo header (a CATDlgCombo instance). 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 CATDlgCombo instance. Name is the command name of the CAAAfrComboRep class. You can set the same identifier for all CAAAfrComboRep class instances. 

You do not have to take care of the CAAAfrComboRep class instance, the returned value, oHdrRep is kept by the frame application, and the deletion of this pointer is automatically done.  

...
HRESULT CAAEAfrCommandHeaderRepForComboColor::
             CreateMenuRep (const CATDialog * iParent,CATAfrCommandHeaderRep ** oHdrRep)
{
  return  E_FAIL ;
}

HRESULT CAAEAfrCommandHeaderRepForComboColor::
          CreateCtxMenuRep (const CATDialog * iParent,CATAfrCommandHeaderRep ** oHdrRep)
{
  return E_FAIL;
}

The combo header has no representation in the menu bar or in a contextual menu, so CreateMenuRep and CreateCtxMenuRep return E_FAIL.

[Top]

Creating the Class Instantiating the Graphic Representation

This class is the CAAAfrComboRep class. Its main roles are:

Here the CAAAfrComboRep header file:

...
class CAAAfrComboRep : public CATAfrCommandHeaderRep
{
public:
  CAAAfrComboRep(const CATDialog * iParent, CATString & iCommandName);
  virtual ~CAAAfrComboRep();

  HRESULT Build();

private:
  void SelectCB(CATCommand * iPublishingCommand, 
                CATNotification * iNotification, 
                CATCommandClientData iData);

  void ModifiedCB(CATCallback       iEvent, 
                  void            *       , 
                  CATNotification * iNotification, 
                  CATCallbackEvent  iData,
		          CATSubscriberData iCallBack);
  HRESULT SetCurrentColor() ;

  CAAAfrComboRep(const CAAAfrComboRep &iObjectToCopy);
  CAAAfrComboRep & operator = (const CAAAfrComboRep &iObjectToCopy);

private:
     CATDlgCombo    * _pCombo;
     CATBaseUnknown * _pUIActiveObject ;
     int              _ColorTable[30] ;
};

Here the CAAAfrComboRep source file:

[Top]

Instantiating the Combo Header Class

The combo header is used in the CAAGeometry document. An instance of this header has been created in an Add-in of the workshop of the document. Here is an extract of the CAAAfrGeoChartWindowAdn class which is an implementation of the CAAIAfrGeometryWksAddin interface. 

...
void CAAAfrGeoChartWindowAdn::CreateCommands()
{
...
   new CAAAfrComboColorHeader("CAAAfrComboColorHdr");
}

The combo command header is created using its constructor class. 


In Short

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]


References

[1] Creating a Most Recent Used Command Header
[2] The Command Headers
[3] The CAAGeometry Sample
[4] CATDlgCombo
[5] The Callback Mechanism
[6] Creating an Interface
[7] The Callback Mechanism
[8] The CAA Command Model
[9] Object Modeler Inheritances
[Top]

History

Version: 1 [Fev 2004] Document created
[Top]

Copyright © 2004, Dassault Systèmes. All rights reserved.