3D PLM Enterprise Architecture |
User Interface - Frame |
Creating a Setting ControllerEncapsulating the access to the setting file |
Use Case |
AbstractThis article shows how to create a setting controller. |
This use case is intended to show how to create a setting controller component in order to encapsulate and ensure a unique access to a setting file. The setting controller enables several applications to access the parameters stored in a setting file, without having to know about the internal storage details. Setting controller ensures a consistent access to a setting file for different applications, the Tools/Options command being the most important of these applications.
This article describes a concrete use case of a setting controller. For more explanations, refer to the technical article [1] on the topic.
[Top]
CAACafCtrlToolsOptions is a use case of the CAACATIAApplicationFrm.edu framework that illustrates the CATIAApplicationFrame framework capabilities.
[Top]
CAACafCtrlToolsOptions creates the setting controller for a setting file. The
options are used in our CAAGeometry
document.
This setting controller is used by the Elements property page accessible with the Tools/Options command. The use case "Creating a Property Page for Application Properties" [2] describes how to create this property page.
This property page displays three parameters which are inside the following frames:
CAAV5 Geometrical Creation
workbench. The
element identifiers can be permanently:
These three parameters are saved in the CAACafGeometryElt
setting file and must always be accessible through the CAACafGeometryEltSettingCtrl
setting controller. This controller is a component which implements the
following interfaces:
Commit, Save,
etc.[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.
[Top]
The CAACafCtrlToolsOptions use case is made of classes and interfaces located in the CAACafCtrlToolsOptions.m module and in the ProtectedInterfaces directory of the CAACATIAApplicationFrm.edu framework:
Windows | InstallRootDirectory\CAACATIAApplicationFrm.edu\CAACafCtrlToolsOptions.m\ |
Unix | InstallRootDirectory/CAACATIAApplicationFrm.edu/CAACafCtrlToolsOptions.m/ |
where InstallRootDirectory
is the directory where the CAA CD-ROM
is installed.
These classes and interfaces are:
CAAICafGeometryEltSettingAtt | Interface to access each parameter |
TIE_CAAICafGeometryEltSettingAtt | TIE to this interface |
CAACafGeometryEltSettingCtrl | Setting controller component main class |
CAAECafGeometryEltSettingAtt | Setting controller component extension class that implements CAAICafGeometryEltSettingAtt |
CAAECafSettingManagmentForGeometryElt | Setting controller component extension class that implements CATIIniSettingManagment |
GetCAACafGeometryEltSettingCtrl | Factory function to retrieve the setting controller |
[Top]
To create a setting controller, there are five main steps:
[Top]
The CAAICafGeometryEltSettingAtt interface is dedicated to the access of the three parameters:
Here is the CAAICafGeometryEltSettingAtt
header file:
#include "IUnknown.h" #include "CAACafCtrlToolsOptions.h" extern IID IID_CAAICafGeometryEltSettingAtt; class CATString; class CATSettingInfo ; class ExportedByCAACafCtrlToolsOptions CAAICafGeometryEltSettingAtt : public IUnknown { public : virtual HRESULT Initialize() = 0; virtual HRESULT GetIdentifierVisibility(CATString & oIdVisibility) = 0; virtual HRESULT SetIdentifierVisibility(const CATString & iIdVisibility) = 0; virtual HRESULT GetInfoIdentifierVisibility(CATSettingInfo * oInfo) = 0; virtual HRESULT GetMaxPointCurve(int & oMaxPoint) = 0; virtual HRESULT SetMaxPointCurve(const int iMaxPoint) = 0; virtual HRESULT GetInfoMaxPointCurve(CATSettingInfo ** oInfoArray, int * oNbSettingInfo) = 0; virtual HRESULT GetImplPointVisibility(CATString & oImplPointVisibility) = 0; virtual HRESULT SetImplPointVisibility(const CATString & iImplPointVisibility) = 0; virtual HRESULT GetInfoImplPointVisibility(CATSettingInfo * oInfo) = 0; }; |
This Object Modeler interface derives from the IUnknown interface.
Like any interface, it has an IID declared as IID_ followed by the interface
name. This interface is exported by the CAACafCtrlToolsOptions.m
module.
This interface defines:
One Initialize
method. Refer to the "The Setting
Controller" technical article [1] for more
details about this important method.Setxxx
to
modify the parameter (SetIdentifierVisibility,
SetMaxPointCurve and SetImplPointVisibility)
Getxxx
to retrieve
the parameter (GetIdentifierVisibility,
GetMaxPointCurve and GetImplPointVisibility)
GetInfoxxx
to retrieve the CATSettingInfo
instance necessary to construct the dialog object acting as a lock (G
etInfoIdentifierVisibility,
GetInfoMaxPointCurve and GetInfoImplPointVisibility)
Here is the CAAICafGeometryEltSettingAtt
source file:
#include <CAAICafGeometryEltSettingAtt.h> IIID IID_CAAICafGeometryEltSettingAtt={ /* 8a2969d2-0e0d-11d5-85c1-00108335648a */ 0x8a2969d2, 0x0e0d, 0x11d5, {0x85, 0xc1, 0x00, 0x10, 0x83, 0x35, 0x64, 0x8a} }; |
This file includes a GUID [3], shown in bold typeface.
#include "CAAICafGeometryEltSettingAtt.h" |
The Multi-Workspace Application Builder (mkmk) will generate the TIE for this interface, this is the TIE_CAAICafGeometryEltSettingAtt.h found in the ProtectedGenerated directory.
Located in the CNext/code/dictionary, directory modify or create the CAACATIAApplicationFrm.edu.idd file by including the following line:
{8a2969d2-0e0d-11d5-85c1-00108335648a} CAAICafGeometryEltSettingAtt |
The first part is the GUID [3] defined two steps before, and the second part is the name of the interface.
[Top]
Here is the CAACafGeometryEltSettingCtrl
header file:
#include "CATBaseUnknown.h" #include "CATIniCleanerSettingCtrl.h" class CAACafGeometryEltSettingCtrl : public CATBaseUnknown { CATDeclareClass; public: CAACafGeometryEltSettingCtrl(); virtual ~CAACafGeometryEltSettingCtrl(); static HRESULT GetSettingController(CAACafGeometryEltSettingCtrl ** oCtrl); private: CAACafGeometryEltSettingCtrl(const CAACafGeometryEltSettingCtrl &iObjectToCopy); CAACafGeometryEltSettingCtrl & operator = (const CAACafGeometryEltSettingCtrl &iObjectToCopy); private: static CATIniCleanerSettingCtrl _CleanerCtrl ; }; |
The CAACafGeometryEltSettingCtrl
C++ class derives from CATBaseUnknown.
The CATDeclareClass
macro declares that the CAACafGeometryEltSettingCtrl
class belongs to a component. The copy constructor and the
"=" operator are set as private to prevent the compiler from
automatically creating them as public.
The CAACafGeometryEltSettingCtrl
component class is created
only once during a session. The GetSettingController
method
returns the unique pointer to this class. To manage the destruction of this
pointer, an instance of the CATIniCleanerSettingCtrl class is used. The
_CleanerCtrl
static data member contains this unique pointer.
Here is the CAACafGeometryEltSettingCtrl
source file:
#include "CAACafGeometryEltSettingCtrl.h" #include "CAAICafGeometryEltSettingAtt.h" #include "CATIIniSettingManagment.h" #include "CATErrorDef.h" #include "CATBoolean.h" CATIniCleanerSettingCtrl CAACafGeometryEltSettingCtrl::_CleanerCtrl ; CATImplementClass(CAACafGeometryEltSettingCtrl, Implementation, CATBaseUnknown , CATNull); CAACafGeometryEltSettingCtrl::CAACafGeometryEltSettingCtrl() { } CAACafGeometryEltSettingCtrl::~CAACafGeometryEltSettingCtrl() { } ... |
The _CleanerCtrl
static data member is created.
The CATImplementClass
macro declares that the CAACafGeometryEltSettingCtrl
class is a component main class thanks to the Implementation
keyword, and it also OM-derives [4] from CATBaseUnknown.
The constructor and destructor are empty.
... HRESULT CAACafGeometryEltSettingCtrl::GetSettingController (CAACafGeometryEltSettingCtrl ** oCtrl) { HRESULT rc = S_OK ; if ( NULL != oCtrl ) { *oCtrl = NULL ; CATBaseUnknown * pCtrl = _CleanerCtrl.GetController(); if ( NULL == pCtrl ) { CAACafGeometryEltSettingCtrl * SettingController = NULL; SettingController = new CAACafGeometryEltSettingCtrl(); if ( NULL == SettingController ) { rc = E_OUTOFMEMORY ; }else { CATBoolean Init = FALSE ; // The Initialization is mandatory CAAICafGeometryEltSettingAtt * pISettingAtForCtrl = NULL ; rc = SettingController->QueryInterface(IID_CAAICafGeometryEltSettingAtt, (void**) &pISettingAtForCtrl ); if ( SUCCEEDED(rc) ) { rc = pISettingAtForCtrl->Initialize(); if ( SUCCEEDED(rc) ) { CATIIniSettingManagment * pIMgtAtForCtrl = NULL ; rc = SettingController->QueryInterface(IID_CATIIniSettingManagment, (void**) &pIMgtAtForCtrl ); if ( SUCCEEDED(rc) ) { // For the first Roolback pIMgtAtForCtrl->Commit() ; pIMgtAtForCtrl->Release(); pIMgtAtForCtrl = NULL; // The cleaner keeps the unique instance _CleanerCtrl.SetController(SettingController); *oCtrl = SettingController ; Init = TRUE ; } } pISettingAtForCtrl->Release(); pISettingAtForCtrl = NULL ; } if ( FALSE == Init ) { SettingController->Release() ; SettingController = NULL ; } } }else { *oCtrl = (CAACafGeometryEltSettingCtrl *) pCtrl ; } }else rc = E_FAIL ; return rc ; } |
The goal of this method is to return a pointer to the CAACafGeometryEltSettingCtrl
class. This unique pointer is saved in the _CleanerCtrl
data
member.
Before setting the new controller in _CleanerCtrl,
using the SetController
method, it is first necessary to execute the following methods:
Initialize
method of the CAAICafGeometryEltSettingAtt
interfaceCommit
method of the CATIIniSettingManagment
interface[Top]
The implement class is the CAAECafGeometryEltSettingCtrl
class.
Here is the CAAECafGeometryEltSettingCtrl
header file:
#include "CATBaseUnknown.h" class CATSettingRepository ; #include "CAAICafGeometryEltSettingAtt.h" class CAAECafGeometryEltSettingAtt: public CATBaseUnknown { CATDeclareClass; public: CAAECafGeometryEltSettingAtt(); virtual ~CAAECafGeometryEltSettingAtt(); virtual HRESULT Initialize() ; virtual HRESULT GetIdentifierVisibility(CATString & oIdVisibility) ; virtual HRESULT SetIdentifierVisibility(const CATString & iIdVisibility) ; virtual HRESULT GetInfoIdentifierVisibility(CATSettingInfo * oInfo) ; virtual HRESULT GetMaxPointCurve(int & oMaxPoint) ; virtual HRESULT SetMaxPointCurve(const int iMaxPoint) ; virtual HRESULT GetInfoMaxPointCurve(CATSettingInfo ** oInfoArray, int * oNbSettingInfo) ; virtual HRESULT GetImplPointVisibility(CATString & oImplPointVisibility) ; virtual HRESULT SetImplPointVisibility(const CATString & iImplPointVisibility) ; virtual HRESULT GetInfoImplPointVisibility(CATSettingInfo * oInfo) ; private: CAAECafGeometryEltSettingAtt(const CAAECafGeometryEltSettingAtt &iObjectToCopy); CAAECafGeometryEltSettingAtt & operator = (const CAAECafGeometryEltSettingAtt &iObjectToCopy); private: CATSettingRepository * _pSettingRep ; }; #endif |
The CAAECafGeometryEltSettingAtt
C++ class derives from CATBaseUnknown.
The CATDeclareClass
macro declares that the CAAECafGeometryEltSettingAtt
class belongs to a component. The copy constructor and the
"=" operator are set as private to prevent the compiler from
automatically creating as public.
The public methods other than the constructor and the destructor, are methods defined in the CAAICafGeometryEltSettingAtt interface.
In the private data section, _pSettingRep is a pointer to the CATSettingRepository [5] used to access the attributes of the setting file.
Here is the CAAECafGeometryEltSettingCtrl
source file:
CAACafGeometryEltSettingCtrl
setting controller
#include "CAAECafGeometryEltSettingAtt.h" #include "CATString.h" #include "CATSettingRepository.h" #include "TIE_CAAICafGeometryEltSettingAtt.h" TIE_CAAICafGeometryEltSettingAtt(CAAECafGeometryEltSettingAtt); CATImplementClass(CAAECafGeometryEltSettingAtt, DataExtension, CATBaseUnknown, CAACafGeometryEltSettingCtrl); ... |
The CAAECafGeometryEltSettingAtt
class states that it
implements the CAAICafGeometryEltSettingAtt interface thanks to the TIE_CAAICafGeometryEltSettingAtt
macro. This extension class is dedicated to the controller component. The CATImplementClass
macro declares that the CAAECafGeometryEltSettingAtt
class is a
data extension class, thanks to the DataExtension
keyword, and
that it extends the component whose main class is CAACafGeometryEltSettingCtrl
.
The third parameter must always be set to CATBaseUnknown (unused
parameter)
Constructor -
Destructor
... CAAECafGeometryEltSettingAtt::CAAECafGeometryEltSettingAtt():_pSettingRep(NULL) { _pSettingRep = CATSettingRepository::GetRepository("CAACafGeometryElt") ; } CAAECafGeometryEltSettingAtt::~CAAECafGeometryEltSettingAtt() { _pSettingRep = NULL ; } ... |
In the constructor, the setting repository pointer for the CAACafGeometryElt.CATSetting
file
is retrieved. In the destructor, this pointer is
set to NULL. No Release
should be involved on this pointer the
System framework already takes care of the life cycle of those objects.
Initialize
method
... HRESULT CAAECafGeometryEltSettingAtt::Initialize() { HRESULT rc = S_OK ; HRESULT rctemp = E_FAIL ; CATString ident ; rctemp = GetIdentifierVisibility(ident); if ( FAILED(rctemp) ) rc = rctemp ; rctemp = GetImplPointVisibility(ident); if ( FAILED(rctemp) ) rc = rctemp ; int value ; rc = GetMaxPointCurve(value); if ( FAILED(rctemp) ) rc = rctemp ; return rc ; } |
The method calls all the Getxxx
method: GetIdentifierVisibility,
GetImplPointVisibility
and GetMaxPointCurve.
The method
returns rctemp if at least one call fails.
It is important to call each Getxxx
method to ensure that
the default values, given in the Getxxx
methods, are defined
and put onto the repository.
GetIdentifierVisibility
method
HRESULT CAAECafGeometryEltSettingAtt::GetIdentifierVisibility( CATString & oIdVisibility) { HRESULT rc = E_FAIL ; if ( NULL != _pSettingRep ) { CATString Ident("IdHide"); long flag = _pSettingRep->ReadSetting("Identifier",&Ident); if ( 1 == flag ) { oIdVisibility = Ident ; rc =S_OK; } } return rc ; } |
The goal of this method is to return information about how the
identifiers are visualized. This information is stored in the setting
repository under the "Identifier
" attribute. The call
to the ReadSetting
method of the CATSettingRepository
class, using Identifier
as first argument, retrieves the
information as it is currently in the setting repository.
The Ident
variable is initialized with a default value. When
there is no administration setting file, this default value is the reset
value.
SetIdentifierVisibility
method
HRESULT CAAECafGeometryEltSettingAtt::SetIdentifierVisibility( const CATString & iIdVisibility) { HRESULT rc = E_FAIL ; CATString StIdHide("IdHide"); CATString StIdShow("IdShow"); CATString StIdPreSelectShow("IdPreSelectShow"); if ( (StIdHide == iIdVisibility) || (StIdShow == iIdVisibility) || (StIdPreSelectShow == iIdVisibility) ) { if ( NULL != _pSettingRep ) { CATString Ident = iIdVisibility ; long flag = _pSettingRep->WriteSetting("Identifier",&Ident); if ( 1 == flag ) { rc =S_OK; } } } return rc ; } |
The goal of this method is to modify the information about how the
identifiers are visualized. This information is stored in the setting
repository under the "Identifier
" attribute. The call
to the WriteSetting
method of the CATSettingRepository
class, using Identifier
as first argument, modifies this
information. The validity of the input data is checked before modifying the
repository (not necessary if the first argument is an enum ).
GetInfoIdentifierVisibility
method
HRESULT CAAECafGeometryEltSettingAtt::GetInfoIdentifierVisibility( CATSettingInfo * oInfo,int iFlag ) { HRESULT rc = E_FAIL ; if ( NULL != _pSettingRep ) { long flag = _pSettingRep->GetInfo("Identifier",oInfo, iFlag) ; if ( 0 == flag ) { rc = S_OK ; } } return rc ; } |
This method calls the GetInfo
method of the CATSettingRepository
class with Identifier
as first argument, and returns the unique
CATSettingInfo dedicated to this parameter.
GetInfoMaxPointCurve
method
HRESULT CAAECafGeometryEltSettingAtt::GetInfoMaxPointCurve( CATSettingInfo ** oInfoArray, int *oNbSettingInfo ) { HRESULT rc = E_FAIL ; if ( (NULL != _pSettingRep) && ( NULL != oNbSettingInfo) && ( NULL != oInfoArray ) ) { *oNbSettingInfo = 0 ; *oInfoArray = NULL ; CATSettingInfo info ; long flag = _pSettingRep->GetInfo("MaxPointCurve",&info) ; if ( 0 == flag ) { *oNbSettingInfo = 1 ; *oInfoArray = new CATSettingInfo [*oNbSettingInfo] ; (*oInfoArray)[0] = info ; rc = S_OK ; } } return rc ; } |
This method returns an array of CATSettingInfo and not one CATSettingInfo. In this use case a mere pointer to CATSettingInfo is enough since the parameter is represented by one attribute. However the array of CATSettingInfo pointer example is given in case your parameter is represented by several attributes or you are unsure about possible internal storage evolution.
In the interface dictionary dedicated to the CAACATIAApplicationFrm.edu
framework, it is necessary to add the following line to indicate that the CAACafGeometryEltSettingCtrl
component implements the CAAICafGeometryEltSettingAtt interface in the CAACafCtrlToolsOptions
module.
CAACafGeometryEltSettingCtrl CAAICafGeometryEltSettingAtt libCAACafCtrlToolsOptions
[Top]
The CATIIniSettingManagment interface manages general methods of the
setting repository. The implemention class is the CAAECafSettingManagmentForGeometryElt
class.
Here is the CAAECafSettingManagmentForGeometryElt
header file:
#include "CATIIniSettingManagment.h"
#include "CATEIniSettingManagment.h"
class CAAECafSettingManagmentForGeometryElt: public CATEIniSettingManagment
{
CATDeclareClass;
public:
CAAECafSettingManagmentForGeometryElt();
virtual ~CAAECafSettingManagmentForGeometryElt();
private:
CAAECafSettingManagmentForGeometryElt(const CAAECafSettingManagmentForGeometryElt &iObjectToCopy);
CAAECafSettingManagmentForGeometryElt & operator = (const CAAECafSettingManagmentForGeometryElt &iObjectToCopy);
};
The CAAECafSettingManagmentForGeometryElt
C++ class derives
from CATEIniSettingManagment. This adapter class is defined in the
InteractiveInterfaces framework. The CATDeclareClass
macro
declares that the CAAECafSettingManagmentForGeometryElt class belongs to a
component. The copy constructor and the " =" operator are set as
private to prevent the compiler from automatically creating as public.
- Source file
Here is the CAAECafSettingManagmentForGeometryElt
source file:
#include "CAAECafSettingManagmentForGeometryElt.h"
#include "TIE_CATIIniSettingManagment.h"
TIE_CATIIniSettingManagment(CAAECafSettingManagmentForGeometryElt);
CATImplementClass(CAAECafSettingManagmentForGeometryElt,
DataExtension,
CATBaseUnknown,
CAACafGeometryEltSettingCtrl);
CAAECafSettingManagmentForGeometryElt::CAAECafSettingManagmentForGeometryElt():
CATEIniSettingManagment("CAACafGeometryElt")
{
}
CAAECafSettingManagmentForGeometryElt::~CAAECafSettingManagmentForGeometryElt()
{
}
The CAAECafSettingManagmentForGeometryElt
class states that it
implements the CATIIniSettingManagment interface thanks to the TIE_CATIIniSettingManagment
macro. This extension class is dedicated to the controller component. The CATImplementClass
macro declares that the CAAECafSettingManagmentForGeometryElt
class is a data extension class, thanks to the DataExtension
keyword and that it extends the component whose main class is CAACafGeometryEltSettingCtrl
.
The third parameter must always be set to CATBaseUnknown; it makes no
sense here as it.
The constructor calls the constructor of the CATEIniSettingManagment
adaptor using the name of the setting file, CAACafGeometryElt
,
the same name as in the CAAECafGeometryEltSettingAtt constructor. Refer to
the Constructor-Destructor section
in previous step.
The destructor is empty.
In the interface dictionary dedicated to the CAACATIAApplicationFrm.edu
framework, it is necessary to add the following line in order to declare that
the CAACafGeometryEltSettingCtrl component implements the CATIIniSettingManagment
interface in the CAACafCtrlToolsOptions
module.
CAACafGeometryEltSettingCtrl CATIIniSettingManagment libCAACafCtrlToolsOptions
[Top]
The CAACafGeometryEltSettingCtrl header class is located in a LocalInterfaces directory, so that the only way to retrieve a pointer on it, is to use the public global function. This function returns a pointer to an interface implemented by the setting controller component.
Here is the GetCAACafGeometryEltSettingCtrl
header file:
#include "IUnknown.h"
#include "CAACafCtrlToolsOptions.h"
HRESULT ExportedByCAACafCtrlToolsOptions
GetCAACafGeometryEltSettingCtrl(const IID & iInterfaceIdentifier ,
void ** oInterfacePointer) ;
The GetCAACafGeometryEltSettingCtrl
global function is
exported by the CAACafCtrlToolsOptions
module.
Here is the GetCAACafGeometryEltSettingCtrl
source file:
#include "GetCAACafGeometryEltSettingCtrl.h" #include "CAACafGeometryEltSettingCtrl.h" #include "CATErrorDef.h" HRESULT GetCAACafGeometryEltSettingCtrl(const IID & iInterfaceIdentifier, void ** oInterfacePointer) { HRESULT rc = S_OK ; if ( NULL != oInterfacePointer ) { CAACafGeometryEltSettingCtrl * pCtrl = NULL ; rc = ::CAACafGeometryEltSettingCtrl::GetSettingController(&pCtrl); if ( SUCCEEDED(rc) && ( NULL != pCtrl) ) { rc = pCtrl->QueryInterface(iInterfaceIdentifier,oInterfacePointer); pCtrl->Release(); pCtrl= NULL ; } else { rc = E_FAIL ; } }else rc = E_FAIL ; return rc ; } |
The GetSettingController
method of the CAACafGeometryEltSettingCtrl
class is called to the retrieve the unique pointer of the CAACafGeometryEltSettingCtrl
class. Then, a QueryInterface
on the input interface is called,
to retrieve the requested interface pointer.
[Top]
This use case has demonstrated how to create a setting controller through the creation of:
[Top]
Version: 1 [Jan 2002] | Document created |
[Top] |
Copyright © 2002, Dassault Systèmes. All rights reserved.