Mechanical Modeler

Adding a Contextual Sub-Menu

Implementing CATIContextualSubMenu
Use Case
Creating a New Geometrical Feature: The Combined Curve > Adding a Contextual Sub-Menu

Abstract

This article shows how to insert commands in the contextual menu when selecting a combined curve instance. 


What You Will Learn With This Use Case

This use case is intended to show you how insert commands in the contextual menu associated with the combined curve [1]. Once this mechanical feature implements the CATIEdit interface [2], the commands will be added in a sub-menu of its contextual menu. So in other words, this article explains how to implement the CATIContextualSubMenu (ApplicationFrame) interface. 

[Top]

The CAAMmrContextualSubMenu Use Case

CAAMmrContextualSubMenu is a use case of the CAAMechanicalModeler.edu framework that illustrates ApplicationFrame framework capabilities.

[Top]

What Does CAAMmrContextualSubMenu Do

CAAMmrContextualSubMenu enables you to add commands in the sub-menu of the contextual menu associated with the Combined Curve feature. The picture below shows the sub-menu of the Combined Curve. There are two pictures because, the last command can be either Deactivate or Activate. You will see how the switch can be done.

Once the Combined Curve implements CATIEdit, its contextual menu contains at the end the "CombineCrv object" item. This items contains a sub-menu which, by default, contains only the Definition item. In implementing the CATIContextualSubMenu interface on the Combined Curve you can insert other commands after the Definition item.

The new commands are Parent/Children, Reset Properties, Deactivate or Activate. Four Dassault Systèmes commands. To reuse it, you should retrieve their command header identifiers [3].  The "Workshop Exposition" command enables you to find them.

Launch CATIA, when the application is ready:

In the CATMmrPartWks.txt find out the "Parent/Children", "Reset Properties", "Deactivate" and "Activate" strings: 

The identifiers of the command header instances are the Id strings, so CATParentChildrenHdr, CATMmrPrtResetPropHdr, CATPrtInactiveHdr and CATPrtActiveHdr  for the "Parent/Children", "Reset Properties", "Deactivate" and "Activate" commands respectively. These four identifiers will be associated with the starters of the menu. 

[Top]

How to Launch CAAMmrContextualSubMenu

See the section entitled "How to Launch the Combined Curve Use Case" in the "Creating a New Geometrical Feature: The Combined Curve" use case for a detailed description of how this use case should be launched.

[Top]

Where to Find the CAAMmrContextualSubMenu Code

The CAAMmrContextualSubMenu use case is made of one single class, the CAAEMmrCombinedCurveContSubMenu class, located in the CAAMmrCombinedCurveUI.m module of the CAAMechanicalModeler.edu framework:

Windows InstallRootDirectory\CAAMechanicalModeler.edu\CAAMmrCombinedCurveUI.m\
Unix InstallRootDirectory/CAAMechanicalModeler.edu/CAAMmrCombinedCurveUI.m/

where InstallRootDirectory is the directory where the CAA CD-ROM is installed.

[Top]

Step-by-Step

To implement the CATIContextualSubMenu interface, there are two steps: 

  1. Creating the Sub-Menu Description Class
  2. Creating the Sub-Menu 

[Top]

Creating the Sub-Menu Description Class

  1. Create the CAAEMmrCombinedCurveContSubMenu.h file
  2. #include "CATBaseUnknown.h"
    
    class CATCmdAccess;
    
    class CAAEMmrCombinedCurveContSubMenu : public CATBaseUnknown
    {
      CATDeclareClass;
    
      public:
    
        CAAEMmrCombinedCurveContSubMenu();
        virtual ~CAAEMmrCombinedCurveContSubMenu();
    
        virtual CATCmdAccess * GetContextualSubMenu() ;
     
      private :
    
        CAAEMmrCombinedCurveContSubMenu(const CAAEMmrCombinedCurveContSubMenu &iObjectToCopy);
        CAAEMmrCombinedCurveContSubMenu & operator = (const CAAEMmrCombinedCurveContSubMenu &iObjectToCopy);
    
    
      private :
    
        CATCmdAccess  *  _pMenu ;
        CATCmdStarter *  _pCAAMmrSwapActiveStr ;
    };

    The GetContextualSubMenu method returns _pMenu created in the constructor class. _pCAAMmrSwapActiveStr is the starter associated with the Activate or the Deactivate command, also created in the constructor class. 

  3. Create the CAAEMmrCombinedCurveContSubMenu.cpp file
  4. #include "CAAEMmrCombinedCurveContSubMenu.h"
    #include "CATCreateWorkshop.h"
    
    CATImplementClass(CAAEMmrCombinedCurveContSubMenu,DataExtension,
                           CATBaseUnknown,CombinedCurve);
    
    #include "TIE_CATIContextualSubMenu.h"
    TIE_CATIContextualSubMenu(CAAEMmrCombinedCurveContSubMenu);
    ...

    The CAAEMmrCombinedCurveContSubMenu class states that it implements the CATIContextualSubMenu interface thanks to the TIE_CATIContextualSubMenu macro. The CATImplementClass macro declares that the CAAEMmrCombinedCurveContSubMenu class is a data extension, thanks to the DataExtension keyword, that extends CombinedCurve. The third argument must always be set as CATBaseUnknown or CATNull for any kind of extension.

    ...
    CAAEMmrCombinedCurveContSubMenu::CAAEMmrCombinedCurveContSubMenu():_pMenu(NULL,_pCAAMmrSwapActiveStr(NULL)	
                          				   
    {
        Creating the Sub-Menu
    }
    
    CAAEMmrCombinedCurveContSubMenu::~CAAEMmrCombinedCurveContSubMenu()
    {
      
      if ( NULL != _pMenu) _pMenu->Release() ;
      _pMenu = NULL ;
    }
    
    
    CATCmdAccess *  CAAEMmrCombinedCurveContSubMenu::GetContextualSubMenu()
    {
       Checking the Activate/Deactivate Command
       return (_pMenu);
    }

    In this implementation, the structure of menu is constant, _pMenu is created in the constructor and released in the destructor. Otherwise, you can create it in the GetContextualMenu method. But in this case, you should release it in the destructor and at the beginning of the GetContextualMenu method.

  5. Updating the Interface Dictionary
  6. Update the interface dictionary, that is a file named, for example, CAAMechanicalModeler.dico, whose directory's pathname is concatenated at run time in the CATDictionaryPath environment variable, and containing the following declaration to state that the CombinedCurve component implements the CATIContextualSubMenu interface, and whose code is located in the libCAAMmrCombinedCurveUI shared library or DLL.

    CombinedCurve CATIContextualSubMenu libCAAMmrCombinedCurveUI

Creating the Sub-Menu 

 
   NewAccess(CATCmdStarter,pCAAMmrResetPropertiesStr,CAAMmrResetPropertiesStr);
   NewAccess(CATCmdStarter,pCAAMmrParentChildrenStr,CAAMmrParentChildrenStr);


   CATIMechanicalProperties * pMechProp = NULL ;
   HRESULT rcMechProp = QueryInterface(IID_CATIMechanicalProperties, (void**) & pMechProp);
   if ( SUCCEEDED(rcMechProp) )
   {
      NewAccess(CATCmdStarter,pCAAMmrSwapActiveStr,CAAMmrSwapActiveStr);
     _pCAAMmrSwapActiveStr = pCAAMmrSwapActiveStr ;
   }
    
   _pMenu = pCAAMmrParentChildrenStr ;
   SetAccessNext(pCAAMmrParentChildrenStr,pCAAMmrResetPropertiesStr);

   if ( NULL != _pCAAMmrSwapActiveStr )
   { 
      SetAccessNext(pCAAMmrResetPropertiesStr,_pCAAMmrSwapActiveStr);
   }
    
   SetAccessCommand(pCAAMmrResetPropertiesStr,"CATMmrPrtResetPropHdr");
   SetAccessCommand(pCAAMmrParentChildrenStr,"CATParentChildrenHdr");

The menu is created thanks macros contained in the CATCreateWorkshop file. For each item there are three macros. Here are the explanations for the Reset Properties and the Activate/Deactivate commands:

In a contextual menu or in a contextual sub menu implementation, it is not recommended to create command headers. So you should reuse command header identifiers created previously. To be sure that the command header will be created when the menu will be invoked, you should use an identifier created in a workshop, or in Add-ins of the workshop. The Workshop Exposition command can help you to retrieve the Dassault Systèmes identifiers.

Refer to the technical article entitled "Command Headers" [3] for complete details about the re-usage of the command header identifiers. 

The picture below shows the relationship between the starters and shows that _pMenu is the first starter of the chain. 

where pXXX1 and pXXX2 are starters that you will have added so in the code:

 ...  
   NewAccess(CATCmdStarter,pXXX1 ,XXX1);
   NewAccess(CATCmdStarter,pXXX2 ,XXX2);

   SetAccessCommand(pXXX1 ,"XXX1Hdr");
   SetAccessCommand(pXXX2 ,"XXX2Hdr");

   SetAccessNext(pCAAMmrResetPropertiesStr,pXXX1 );
   SetAccessNext(pXXX1 ,pXXX2 );
...

 The _pMenu destruction deletes also the chained CATCmdAccess class instances.

[Top]

Checking the Activate/Deactivate Command

 
    if ( NULL != _pCAAMmrSwapActiveStr )
    {
       CATIMechanicalProperties * pMechProp = NULL ;
       HRESULT rcMechProp = QueryInterface(IID_CATIMechanicalProperties, (void**) & pMechProp);
       if ( SUCCEEDED(rcMechProp) )
       {
          int IsFeatureDeactivate = pMechProp->IsInactive();

          if ( 0 == IsFeatureDeactivate )
          { 
             SetAccessCommand(_pCAAMmrSwapActiveStr,"CATPrtInactiveHdr");
          }else
          {
             SetAccessCommand(_pCAAMmrSwapActiveStr,"CATPrtActiveHdr");
          }
...

The GetContextualMenu method is called each time the contextual menu must be displayed. So it is at this moment that you must set the right command to the _pCAAMmrSwapActiveStr starter.

[Top]


In Short

This use case explains how to implement the CATIContextualSubMenu interface and how to retrieve Dassault Systèmes command header identifiers.

[Top]


References

[1] Creating a New Geometrical Feature: the Combined Curve
[2] Editing the Combined Curve
[3] Command Headers
[Top]

History

Version: 1 [Fev 2003] Document created
Version: 2 [Jan 2005] Document updated to take the CATIMechanicalProperties interface into account
[Top]

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