Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS Tech Support » About DECLARE_DYNCREATE Collapse All
Subject Author Date
tera t Aug 28, 2007 - 1:21 AM

Hello.

Please teach it.
In CDialog, there is a description of DECLARE_DYNCREATE.
Even if I do not declare DECLARE_DYNCREATE, I can call it in DoModal.
I do not understand a meaning to declare DECLARE_DYNCREATE.

Technical Support Aug 29, 2007 - 12:31 PM

In addition to what Christina said, we would like to add the following. MFC allows you to easily get run-time information about any CObject-derived classes. The CRuntimeClass class describes type information about some other class. Most of MFC classes have run-time class information. You can also describe your classes. A pointer to the CRuntimeClass object allows you to create an instance of the class which it describes and easily find out whether it is derived from some other known class described by other pointer to the CRuntimeClass object. You can describe your class using the following ways:

1) Add the DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC to the implementation of your class, which makes it possible to get run-time description of your classes and determineif one class is derived from another class:

CYourDialogClass1 * p1 = . . .
CYourDialogClass2 * p2 = . . .
CRuntimeClass * pRtc1 = p1->GetRuntimeClass();
      ASSERT( pRtc1 != NULL );
CRuntimeClass * pRtc2 = p2->GetRuntimeClass();
      ASSERT( pRtc2 != NULL );
      if( pRtc2->IsDerivedFrom( pRtc1 ) )
            ::AfxMessageBox( _T("CYourDialogClass2 derived from CYourDialogClass1") );
      else if( pRtc1->IsDerivedFrom( pRtc2 ) )
            ::AfxMessageBox( _T("CYourDialogClass1 derived from CYourDialogClass2") );
      else
            ::AfxMessageBox( _T("There is no inheritance between CYourDialogClass1 and CYourDialogClass1") );
You can do the same using class names and the RUNTIME_CLASS() preprocessor function:
CYourDialogClass1 * p1 = . . .
CYourDialogClass2 * p2 = . . .
      if( p2->IsKindOf( RUNTIME_CLASS( CYourDialogClass1 ) ) )
            ::AfxMessageBox( _T("CYourDialogClass2 derived from CYourDialogClass1") );
      else if( p1->IsKindOf( RUNTIME_CLASS( CYourDialogClass2 ) ) )
            ::AfxMessageBox( _T("CYourDialogClass1 derived from CYourDialogClass2") );
      else
            ::AfxMessageBox( _T("There is no inheritance between CYourDialogClass1 and CYourDialogClass1") );
If some function in your code has a CWnd * pWnd parameter and some part of this function expects that this CWnd * pointer must be a pointer to the CDialog * object, you can use the following assertion:
ASSERT( pWnd->IsKindOf( RUNTIME_CLASS( CButton ) ) );
Or this:ASSERT_KINDOF( CButton, pWnd );If you need to use a CButton * pointer after that, then you can get it using the following code:
CButton * pButton = STATIC_DOWNCAST( CButton, pWnd );
The line of code above should be invoked if you know that the pWnd pointer will really point to a CButton</coded> object. If you do not know this and it may point to a <code>CButton object in some cases and to other class object in some other cases, you should you use type checking assertion failures like described above. You should analyze the type of the CWnd * pWnd pointer dynamically:
CButton * pButton = DYNAMIC_DOWNCAST( CButton, pWnd );
if( pButton != NULL )
{
            ::AfxMessageBox( _T("pWnd is button") );
            return . . .
}
CComboBox * pComboBox = DYNAMIC_DOWNCAST( CComboBox, pWnd );
if( pComboBox != NULL )
{
            ::AfxMessageBox( _T("pWnd is combo box") );
            return . . .
}
. . .
2) Add the DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE into the implementation of your class. This includes all the previously described features plus allows you to create your classes dynamically by their run-time descriptions. Let us say you have saved the description of your class in some part of your code:
CYourDialogClass1 * p1 = . . .
CRuntimeClass * pRtc1 = p1->GetRuntimeClass();
      ASSERT( pRtc1 != NULL );
The pRtc1 is the description of your class. Then some function in your code can receive a pRtc1 pointer in a parameter and invoke the following:
CObject * pObject = pRtc1->CreateObject();
The pObject pointer is really a CYourDialogClass1 pointer and you can check and use its type as described above. 3) Add the DECLARE_SERIAL/IMPLEMENT_SERIAL to the implementation of your class. This includes both features described above plus allows you to load/save objects with run-time class information from/to MFC archives. If you have a pointer to some object, then you can serialize it with its run-time type:
   CArchive & ar = . . .
CObject * pObject = . . .
      ASSERT_VALID( pObject );
CRuntimeClass * pRTC = pObject->GetRuntimeClass();
      ASSERT( pRTC != NULL );
      ar.WriteClass( pRTC );
      pObject->Serialize( ar );
This allows you to load an object of serializeable type from the archive dynamically. I.e. object of exactly the same type will be created from the archived data:
   CArchive & ar = . . .
CRuntimeClass * pRTC = ar.ReadClass();
      ASSERT( pRTC != NULL );
CObject * pObject = pRTC->CreateObject();
      ASSERT_VALID( pObject );
      pObject->Serialize( ar );

Suhai Gyorgy Aug 28, 2007 - 5:21 AM

This has nothing to do with ProfUIS, it’s an MFC issue.
MSDN can tell you about it. Read this