C++ Context Class factory
In order to connect C++ context classes to the corresponding database resources, a context class factory has to be provided (CreateContext()). The factory must return a context class instance for each valid resource reference number (see examples below). When using ODE, the context class factory is generated by the ClassEditor or Designer. Otherwise it has to be implemented explicitly.
The CreateContext() function must an entry point in a dynamic library. Usually, separate libraries are provided for database context classes and GUI context classes. The name of context class library (except platform specific extensions) has to be defined in the resource database (database context library) and /or in the application's configuration or ini-file (option variables CTXI_DLL for database context library and PROJECT_DLL for GUI context library).
// Simple user-defined ContextClass factory
void *__cdecl CreateContext (int32 resid )
{
void *ctx_void = 0;
switch ( resid ) {
case 602630 : ctx_void = new cStdWizard(); break;
case 603810 : ctx_void = new cStdOutputArea(); break;
case 603811 : ctx_void = new cStdProjectTree(); break;
// ...
// more ltable entries
// ...
default :
}
}
// ContextClass factory generated by ClassEditor
void *__cdecl CreateContext (int32 resid )
{
using namespace odabagui;
typedef int32 (* context_create_pointer)(BaseContext **);
typedef std::map<int32,context_create_pointer> FunctionTable;
static FunctionTable function_table;
static bool initialized = false;
BaseContext *ctx_void = NULL;
if ( !initialized ) {
function_table.insert(FunctionTable::value_type(602630,cStdWizard::Create));
function_table.insert(FunctionTable::value_type(603810,cStdOutputArea::Create));
function_table.insert(FunctionTable::value_type(603811,cStdProjectTree::Create));
// ...
// more ltable entries
// ...
initialized = true;
}
Application::resetApplicationError();
FunctionTable::iterator it = function_table.find(resid);
if ( it != function_table.end() )
(*it->second)(&ctx_void);
Application::resetApplicationError();
return(ctx_void);
}
In order to define proper context class factories, the development database should be checked for resource references associated with a context class. This could be done writing a simple OSI function. A better way is, however, generating context classes
directly from database definitions by defining a template that collects the resource references (SDB_ResourceRef), which are associated with a context class. Since relevant information is stored in the resource reference object, the template just needs to select resource references having a context class associated, in order to create a proper CreateContext() function. This is more or less, what the ClassEditor is doing just using another template and a bit more sophisticated class selection in order to support several context classes in different projects.
$template CreateCCFactory()$
void *__cdecl CreateContext (int32 resid )
{
void *ctx_void = 0;
switch ( resid ) {
$SDB_ResourceRef()->CreateCCLine()$
default : ;
}
}
$end$
$template SDB_ResourceRef::CreateCCLine()$
$while next$\
$if context_class.count > 0$\
case $__AUTOIDENT$ : ctx_void = new $context_class.get(0).sys_ident$(); break;
$end$\
$end$\
$end$