IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

CMap et serialisation


Sujet :

MFC

  1. #1
    Membre averti
    Inscrit en
    Septembre 2005
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 47
    Par défaut CMap et serialisation
    Bonjour,

    Est il possible de serialiser un objet contenant une CMap, avec pour chaque elements de ma CMap une autre CMap.
    Pour etre plus claire peut etre :
    J'ai un objet MonObjet qui contient une CMap d'objet Toto. Un objet Toto contient lui aussi une CMap d'objet Tata.

    Est ce possible d'archiver le tout ? MonObjet en entier ???

    J'ai essayer de mettre cela en place et pour l'instant, MonObjet est archive ainsi que la CMap d'objets Toto mais mes CMap d'objets Tata sont vides.

    Merci de votre aide,
    Marie.

  2. #2
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055

  3. #3
    Membre averti
    Inscrit en
    Septembre 2005
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 47
    Par défaut
    Oui, je me suis base la dessus pour creer mon archive.
    Sauf que j'arrive a archiver et recuperer la premiere CMap mais pas les CMap contenu dans chaque element de ma premiere CMap.

    Voici les fonctions que j'utilise :
    Premiere CMap
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <>  void AFXAPI SerializeElements <CLcmTab> (CArchive& ar, CLcmTab * pItem, int nCount)
    {
        for ( int i = 0; i < nCount; i++, pItem++ )            
            pItem->Serialize( ar );    
    }
    Seconde(s) CMap
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <> void AFXAPI SerializeElements <CLcmWindow> (CArchive& ar, CLcmWindow * pItem, int nCount)
    {
        for ( int i = 0; i < nCount; i++, pItem++ )            
            pItem->Serialize(ar);    
    }
    Dans la methode Serialize de mon objet, je fais un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     m_mapTab.Serialize(ar);
    Puis dans la methode serialise de mon objet LcmTab je fais un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     m_mapWindow.Serialize(ar);
    Une idee ?

    Marie.

  4. #4
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    bonsoir,
    il me manque des infos : la declaration des classes en jeux .
    et des CMap.

  5. #5
    Membre averti
    Inscrit en
    Septembre 2005
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 47
    Par défaut
    Voici le .h de mon objet LCMWindow (debarassee des divers commentaires)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    // LcmWindow.h: interface for the CLcmWindow class.
    #if !defined(AFX_LCMWINDOW_H__E56875DF_4EE7_4220_9FDE_B70BEB2D0ECC__INCLUDED_)
    #define AFX_LCMWINDOW_H__E56875DF_4EE7_4220_9FDE_B70BEB2D0ECC__INCLUDED_
     
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
     
    class CLcmWindow : public CObject  
    {
     
    public:
    	DECLARE_SERIAL(CLcmWindow)
     
    	BOOL m_open;
    	CString m_typeClass;
    	WINDOWPLACEMENT m_sizePosition;
     
    	CLcmWindow();
    	CLcmWindow(CString, WINDOWPLACEMENT);
    	virtual ~CLcmWindow();
    	void Clear();
     
    	CLcmWindow(const CLcmWindow &);
     
    	const CLcmWindow& operator=(const CLcmWindow &);
    	void setSizePosition(WINDOWPLACEMENT);
    	void setOpen();
    	void setClose();
    	void Serialize(CArchive & ar);
    };
     
    template<> void AFXAPI SerializeElements<CLcmWindow> (CArchive& ar, CLcmWindow * pElements, int nCount);
     
    #endif // !defined(AFX_LCMWINDOW_H__E56875DF_4EE7_4220_9FDE_B70BEB2D0ECC__INCLUDED_)
    Voici le .h de l'objet LcmTab
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    // LcmTab.h: interface for the CLcmTab class.
    #if !defined(AFX_LCMTAB_H__D943494E_233B_4D99_8045_FAC72BADCB9B__INCLUDED_)
    #define AFX_LCMTAB_H__D943494E_233B_4D99_8045_FAC72BADCB9B__INCLUDED_
     
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
     
    class CLcmTab : public CObject  
    {
    public:
    	DECLARE_SERIAL(CLcmTab)
     
    	CString m_strName;
    	int m_intIcone;
    	CMap <CString, LPCSTR, CLcmWindow, CLcmWindow&> m_mapFrame;
    	CMap<CString, LPCSTR, CLcmWindow, CLcmWindow&> m_mapDefaultValuesFrame;
     
    	CString m_strActiveFrame;
    	CLcmTab(CString, int);
     
    	CLcmTab();
    	virtual ~CLcmTab();
    	void Clear();
     
    	CLcmTab(const CLcmTab &);
    	const CLcmTab& operator=(const CLcmTab &);
    	void AddLcmWindow(CLcmWindow);
    	void AddLcmWindow(CString, WINDOWPLACEMENT);
    	CLcmWindow * GetLcmWindow(CString);
    	CString GetActiveLcmWindow();
    	void SetActiveLcmWindow(CString);
    	void Serialize(CArchive &ar);
     
    };
     
    template<> void AFXAPI SerializeElements<CLcmTab> (CArchive& ar, CLcmTab * pElements, int nCount);
     
    #endif // !defined(AFX_LCMTAB_H__D943494E_233B_4D99_8045_FAC72BADCB9B__INCLUDED_)
    Voici la CMap de Lcmtab
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CMap < CString, LPCSTR, CLcmTab, CLcmTab & > m_mapTab;
    Marie.

  6. #6
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    Pour la serialisation d'une CMap il te faut serialiser la clef et la data ,sinon c'est normal que ta CMap soit vide ...
    pour bien comprendre voici un extrait MFC de la fonction serialize d'une CMap:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
    void CMap<KEY, ARG_KEY, VALUE, ARG_VALUE>::Serialize(CArchive& ar)
    {
    	ASSERT_VALID(this);
     
    	CObject::Serialize(ar);
     
    	if (ar.IsStoring())
    	{
    		ar.WriteCount(m_nCount);
    		if (m_nCount == 0)
    			return;  // nothing more to do
     
    		ASSERT(m_pHashTable != NULL);
    		for (UINT nHash = 0; nHash < m_nHashTableSize; nHash++)
    		{
    			CAssoc* pAssoc;
    			for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL;
    			  pAssoc = pAssoc->pNext)
    			{
    				KEY* pKey;
    				VALUE* pValue;
    				/* 
    				 * in some cases the & operator might be overloaded, and we cannot use it to 
    				 * obtain the address of a given object.  We then use the following trick to 
    				 * get the address
    				 */
    				pKey = reinterpret_cast< KEY* >( &reinterpret_cast< int& >( const_cast< KEY& > ( static_cast< const KEY& >( pAssoc->key ) ) ) );
    				pValue = reinterpret_cast< VALUE* >( &reinterpret_cast< int& >( static_cast< VALUE& >( pAssoc->value ) ) );
    				SerializeElements<KEY>(ar, pKey, 1);
    				SerializeElements<VALUE>(ar, pValue, 1);
    			}
    		}
    	}
    	else
    	{
    		DWORD_PTR nNewCount = ar.ReadCount();
    		while (nNewCount--)
    		{
    			KEY newKey[1];
    			VALUE newValue[1];
    			SerializeElements<KEY>(ar, newKey, 1);
    			SerializeElements<VALUE>(ar, newValue, 1);
    			SetAt(newKey[0], newValue[0]);
    		}
    	}
    }
    on voit bien que lors de la sauvegarde (isStoring()) SerializeElements est appelée deux une pour la clef et la data .
    pareil pour la lecture suivie d'un SetAt pour remplir la CMap...


  7. #7
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    bon precision ,les types de bases comme les CString sont traités donc pas besoin de spécialisation pour ce type .
    le code devrait fonctionner ...
    on est d'accord sur le fait que tu as implementé correctement le constructeur de copie et l'operateur d'affectation?
    fait voir ce que tu as mis dans la fonction serialize de la classe CLcmTab.

    j'ai fait un essai rapide avec l'exemple de la faq ça fonctionne.


  8. #8
    Membre averti
    Inscrit en
    Septembre 2005
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 47
    Par défaut
    Je n'utilise pas de methode CopyFrom, ni pour l'un ni pour l'autre et voici comment j'ai implemente mes methodes pour CLcmWindow (celui dont la serialisation de la map ne fonctionne pas)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    CLcmWindow::CLcmWindow(const CLcmWindow &_newWind)
    {
         *this = _newWind;
     
    }
    //------------------------------------------------------------------------------------------
    const CLcmWindow& CLcmWindow::operator=(const CLcmWindow &_newWind)
    {
    	m_sizePosition = _newWind.m_sizePosition;
    	m_typeClass = _newWind.m_typeClass;
    	m_open = _newWind.m_open;
     
        return *this;
    }
    //-----------------------------------------------------------------------------------
    void CLcmWindow::Serialize(CArchive & ar) {
     
    	if (ar.IsStoring()) {
    // Attention, n'archive pas la structure WINDOWPOS
    		ar<<m_typeClass<<m_open;
     
    	}
    	else {
    		ar>>m_typeClass>>m_open;
    	}
    }

  9. #9
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    ok (meme si tu aurais pu tester que &_newWind!=this) mais c'est l'implémentation dans la classe CLcmTab que je voulais voir ..

  10. #10
    Membre averti
    Inscrit en
    Septembre 2005
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 47
    Par défaut
    Voila ma methode de serialisation dans LcmTab
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    void CLcmTab::Serialize(CArchive &ar) {
     
    	if (ar.IsStoring()) {
     
    		ar<<m_strName<<m_intIcone<<m_strActiveFrame;
     
    		m_mapFrame.Serialize(ar);
     
    	}
    	else {
     
    		ar>>m_strName>>m_intIcone>>m_strActiveFrame;
     
    		m_mapFrame.Serialize(ar);
     
    	}
     
    }
    Marie.

  11. #11
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    pourquoi m_mapDefaultValuesFrame n'est pas serialisée ?
    et montre moi l'operateur d'affection et le constructeur de copie de cette classe ...
    (je crois que la ça devrait etre bon lol)

  12. #12
    Membre averti
    Inscrit en
    Septembre 2005
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 47
    Par défaut
    mapDefaultValuesFrame est une map des valeurs par defaut des fenetres (taille et position). Ca ne necessite pas l'archivage (ici j'archive l'espace de travail pour chaque document) , on peut les assimiler a des constantes que l'on recupere d'un fichier ini par ex.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    const CLcmTab& CLcmTab::operator=(const CLcmTab &_newTab)
    {
        m_strName = _newTab.m_strName;
    	m_intIcone = _newTab.m_intIcone;
     
        return *this;
     
    }
    CLcmTab::CLcmTab(CString _strName, int _intIcone)
    {
    	m_strName = _strName;
    	m_intIcone = _intIcone;
    }
    Je crois que j'ai compris mon erreur, je dois egalement affecter ma map ?

    Marie.

  13. #13
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    Citation Envoyé par MarieMtl
    mapDefaultValuesFrame est une map des valeurs par defaut des fenetres (taille et position). Ca ne necessite pas l'archivage (ici j'archive l'espace de travail pour chaque document) , on peut les assimiler a des constantes que l'on recupere d'un fichier ini par ex.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    const CLcmTab& CLcmTab::operator=(const CLcmTab &_newTab)
    {
        m_strName = _newTab.m_strName;
    	m_intIcone = _newTab.m_intIcone;
     
        return *this;
     
    }
    CLcmTab::CLcmTab(CString _strName, int _intIcone)
    {
    	m_strName = _strName;
    	m_intIcone = _intIcone;
    }
    Je crois que j'ai compris mon erreur, je dois egalement affecter ma map ?

    Marie.
    oui ,(il faudra itera sur la map d'origine pas de copie en direct)le mieux etant de faire une fonction comme dans la faq pour ecrire le code qu'une seule fois ...

  14. #14
    Membre averti
    Inscrit en
    Septembre 2005
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 47
    Par défaut
    Impec' !!! Ca fonctionne ...

    Merci,
    Marie.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [debutant][serialisation ][jtable]pb de sauvegarde
    Par ould dans le forum Composants
    Réponses: 19
    Dernier message: 20/07/2004, 09h09
  2. [Concept][Sérialisation] XML ou serializable
    Par christopheJ dans le forum Format d'échange (XML, JSON...)
    Réponses: 7
    Dernier message: 03/06/2004, 13h11
  3. est il possible de serialiser un composant visuel ?
    Par uliss dans le forum C++Builder
    Réponses: 12
    Dernier message: 15/04/2004, 10h22
  4. [VB6]Sérialiser un objet
    Par HPJ dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 11/10/2003, 10h05
  5. Serialiser de gros documents XML
    Par philemon_siclone dans le forum XML/XSL et SOAP
    Réponses: 6
    Dernier message: 17/09/2003, 15h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo