Dynamic Creation


Click here to change the theme.

It is possible to create an object derived from CObject by using CRuntimeClass::CreateObject if the CRuntimeClass object has it's members set for the class to be created, as in CObject Class: Dynamic Object Creation. There is not a documented way, however, to create an object dynamically, using a class name that is specified during execution instead of in the source code. It can be done simply by getting a CRuntimeClass object for the class. The "GetClass" function provided here will do that. Therefore the following could be used to create (and delete) a  CStringArray object:

	CRuntimeClass* pClass;
CString ClassName("CStringArray");
CObject *pObject;
pClass = GetClass(ClassName);
if (!pClass)
	// Error: Class not found
pObject = pClass->CreateObject();
if (!pObject)
	// Error: Not creatable
// Use the object
delete pObject;

The following function (GetClass) is a modified version of code from CRuntimeClass::Load. To compile, AFXIMPL.H from the MFC source code must be included, as in:

#include "..\SRC\AFXIMPL.H" // for AfxLockGlobals and AfxUnlockGlobals

The following GetClass function searches for the CRuntimeClass* for a class.

CRuntimeClass* GetClass(LPCTSTR ClassName) {
	CRuntimeClass* pClass;
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
for (pClass = pModuleState->m_classList; pClass != NULL; pClass = pClass->m_pNextClass) {
	if (lstrcmpA(ClassName, pClass->m_lpszClassName) == 0) {
		AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
		return pClass;
		}
	}
AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
#ifdef _AFXDLL
// search classes in shared DLLs
AfxLockGlobals(CRIT_DYNLINKLIST);
for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL; pDLL = pDLL->m_pNextDLL) {
	for (pClass = pDLL->m_classList; pClass != NULL; pClass = pClass->m_pNextClass) {
		if (lstrcmpA(ClassName, pClass->m_lpszClassName) == 0) {
			AfxUnlockGlobals(CRIT_DYNLINKLIST);
			return pClass;
			}
	}
}
AfxUnlockGlobals(CRIT_DYNLINKLIST);
#endif
return NULL;
}