DECLARE_DYNAMIC and IMPLEMENT_RUNTIMECLASS macros in VC8

I have migrated one project from vc6 to vc8. In MFC they have added GetThisClass function under RUNTIME_CLASS now my project is not building.

#define RUNTIME_CLASS(class_name) (class_name::GetThisClass())

static CRuntimeClass* PASCAL GetThisClass();

////////

VC8 afx.h file

#ifdef _AFXDLL

#define DECLARE_DYNAMIC(class_name) \

protected: \

static CRuntimeClass* PASCAL _GetBaseClass(); \

public: \

static const CRuntimeClass class##class_name; \

static CRuntimeClass* PASCAL GetThisClass(); \

virtual CRuntimeClass* GetRuntimeClass() const; \

#define _DECLARE_DYNAMIC(class_name) \

protected: \

static CRuntimeClass* PASCAL _GetBaseClass(); \

public: \

static CRuntimeClass class##class_name; \

static CRuntimeClass* PASCAL GetThisClass(); \ /// Not in Vc6

virtual CRuntimeClass* GetRuntimeClass() const; \

#else

#define DECLARE_DYNAMIC(class_name) \

public: \

static const CRuntimeClass class##class_name; \

virtual CRuntimeClass* GetRuntimeClass() const; \

#define _DECLARE_DYNAMIC(class_name) \

public: \

static CRuntimeClass class##class_name; \

virtual CRuntimeClass* GetRuntimeClass() const; \

#endif

#ifdef _AFXDLL

#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew, class_init) \

CRuntimeClass* PASCAL class_name::_GetBaseClass() \

{ return RUNTIME_CLASS(base_class_name); } \

AFX_COMDAT const CRuntimeClass class_name::class##class_name = { \

#class_name, sizeof(class class_name), wSchema, pfnNew, \

&class_name::_GetBaseClass, NULL, class_init }; \

CRuntimeClass* PASCAL class_name::GetThisClass() \ // Not in VC6

{ return _RUNTIME_CLASS(class_name); } \

CRuntimeClass* class_name::GetRuntimeClass() const \

{ return _RUNTIME_CLASS(class_name); } \

I have added implementation for this function but still it is giving runtime error.

error C2039: 'GetThisClass' : is not a member of 'CGXExcelFontTable'
..\include\grid\gxextbl.h(216) : see declaration of 'CGXExcelFontTable'
..\src\grid\excel\gxextbl.cpp(47) : error C2065: '_RUNTIME_CLASS' : undeclared identifier

Any suggession is welcome.

Thanks in Advance.

Madhur




Answer this question

DECLARE_DYNAMIC and IMPLEMENT_RUNTIMECLASS macros in VC8

  • Fylar

    Just on a short look: Your class is a template so the classname doesn't match.



  • DIG

    Yes, Martin you are right but we have written our own macro in vc6 that is using IMPELEMENT / DECLARE mfc macro, now if i'm trying to modify our macro accroding to vc8 mfc for GetThisClass function then it is giving compilation error otherwise it is giving runtime error.

    Error : 1>gxextbl.obj : error LNK2019: unresolved external symbol "public: static struct CRuntimeClass * __stdcall CGXExcelFontTable::GetThisClass(void)" ( GetThisClass@CGXExcelFontTable@@SGPAUCRuntimeClass@@XZ) referenced in function "public: virtual struct CRuntimeClass * __thiscall CGXExcelFontTable::GetRuntimeClass(void)const " ( GetRuntimeClass@CGXExcelFontTable@@UBEPAUCRuntimeClass@@XZ)

    some inputs:

    class CGXExcelFontTable : public CGXExcelBaseTable<fontStruct, CGXStyle> {

    DECLARE_DYNCREATE(CGXExcelFontTable)

    ---- }

    template<class T, class T1 = _cgxNullClass>

    class CGXExcelBaseTable : public CGXExcelTable {

    DECLARE_DYNAMIC(CGXExcelBaseTable)

    --- }

    class CGXExcelTable : public CObject {

    DECLARE_DYNAMIC(CGXExcelTable)

    -- }

    GXEXIMPLEMENT_DYNAMIC(CGXExcelBaseTable, CGXExcelTable, T, T1)

    GXEXIMPLEMENT_DYNCREATE(CGXExcelFontTable, CGXExcelBaseTable, fontStruct, CGXFont)

    #define GXEXRUNTIME_CLASS(class_name, temp_arg, temp_arg1) ((CRuntimeClass*)(&class_name<temp_arg, temp_arg1>::class##class_name))

    #ifdef _AFXDLL

    #define GXEXIMPLEMENT_RUNTIMECLASS(class_name, base_class_name, temp_arg, temp_arg1, wSchema, pfnNew)\

    template<class temp_arg, class temp_arg1>\

    CRuntimeClass* PASCAL class_name<temp_arg, temp_arg1>::_GetBaseClass()\

    { return RUNTIME_CLASS(base_class_name); }\

    template<class temp_arg, class temp_arg1>\

    const AFX_DATADEF CRuntimeClass class_name<temp_arg, temp_arg1>::class##class_name = {\

    #class_name, sizeof(class##class_name), wSchema, pfnNew,\

    &class_name::_GetBaseClass, NULL };\

    template<class temp_arg, class temp_arg1>\

    CRuntimeClass* class_name<temp_arg, temp_arg1>::GetRuntimeClass() const\

    { return GXEXRUNTIME_CLASS(class_name, temp_arg, temp_arg1); }

    //CRuntimeClass* PASCAL class_name::GetThisClass() \

    // { return _RUNTIME_CLASS(class_name); }

    #define GXEXDERIMPLEMENT_RUNTIMECLASS(class_name, base_class_name, temp_arg, temp_arg1, wSchema, pfnNew)\

    CRuntimeClass* PASCAL class_name::_GetBaseClass()\

    { return GXEXRUNTIME_CLASS(base_class_name, temp_arg, temp_arg1); }\

    const AFX_DATADEF CRuntimeClass class_name::class##class_name = {\

    #class_name, sizeof(class##class_name), wSchema, pfnNew,\

    &class_name::_GetBaseClass, NULL };\

    CRuntimeClass* class_name::GetRuntimeClass() const\

    { return RUNTIME_CLASS(class_name); }

    #else

    #define GXEXIMPLEMENT_RUNTIMECLASS(class_name, base_class_name, temp_arg, temp_arg1, wSchema, pfnNew) \

    template<class temp_arg, class temp_arg1>\

    const AFX_DATADEF CRuntimeClass class_name<temp_arg, temp_arg1>::class##class_name = { \

    #class_name, sizeof(class class_name<temp_arg, temp_arg1>), wSchema, pfnNew, \

    RUNTIME_CLASS(base_class_name), NULL }; \

    template<class temp_arg, class temp_arg1>\

    CRuntimeClass* class_name<temp_arg, temp_arg1>::GetRuntimeClass() const \

    { return GXEXRUNTIME_CLASS(class_name, temp_arg, temp_arg1); } \

    #define GXEXDERIMPLEMENT_RUNTIMECLASS(class_name, base_class_name, temp_arg, temp_arg1, wSchema, pfnNew) \

    const AFX_DATADEF CRuntimeClass class_name::class##class_name = { \

    #class_name, sizeof(class class_name), wSchema, pfnNew, \

    GXEXRUNTIME_CLASS(base_class_name, temp_arg, temp_arg1), NULL }; \

    CRuntimeClass* class_name::GetRuntimeClass() const \

    { return RUNTIME_CLASS(class_name); }

    #endif //_AFXDLL

    #define GXEXIMPLEMENT_DYNAMIC(class_name, base_class_name, temp_arg, temp_arg1) \

    GXEXIMPLEMENT_RUNTIMECLASS(class_name, base_class_name, temp_arg, temp_arg1, 0xFFFF, NULL)

    #define GXEXIMPLEMENT_DYNCREATE(class_name, base_class_name, temp_arg, temp_arg1) \

    CObject* PASCAL class_name::CreateObject() \

    { return new class_name; } \

    GXEXDERIMPLEMENT_RUNTIMECLASS(class_name, base_class_name, temp_arg, temp_arg1, 0xFFFF, \

    class_name::CreateObject)

    #define GXEX_TRY(fn)\

    try\

    {\

    fn ;\

    }\

    catch(READSEEKEXCEP* pErr)\

    {\

    pErr->ReportError();\

    pErr->Destroy();\

    }

    #endif //_GXEXMAC_H__

    Hope you will get some clue..

    Thanks in advance.

    Regards,

    Madhur



  • Tasnim

    And why is this a problem As long as you do not simulate or rewrote the macros for your own purpose there is no problem, beause the IMPELEMENT/DECLARE macros do everything thats needed.

  • DECLARE_DYNAMIC and IMPLEMENT_RUNTIMECLASS macros in VC8