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 :

MFC: création contenu onglet CTabCtrl dynamique


Sujet :

MFC

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 7
    Points : 2
    Points
    2
    Par défaut MFC: création contenu onglet CTabCtrl dynamique
    Bonjour,
    J'ai pour but de développer une fenêtre contenant plusieurs onglets qui vont se remplir dynamiquement : Combobox, Label... (nombre d'onglet dynamique aussi).
    Cette fenêtre a été crée avec l'outil graphique de Visual 6, mais le reste (CTabCtrl pour les onglets et tout ce qu'ils vont contenir) vont être créés par du code au chargement de la fenêtre.
    Je viens de me faire un petit programme de test afin de construire cette fenêtre.
    Pourriez vous m'aider pour spécifier à quel onglet va "appartenir" ma ComboBox ?

    ma classe correspondant a ma fenêtre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class CDlgFormDyn : public CDialog
    Voici une partie de mon code de l’implémentation de cette classe
    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    BOOL CDlgFormDyn::OnInitDialog() 
    {
    CDialog::OnInitDialog();
    	m_tab_ongl	= new CTabCtrl();
    	m_tab_ongl->Create(TCS_TABS,CRect(5,70,950,600),this,1);
    	m_tab_ongl->ShowWindow(SW_SHOW);
     
    	test() ;
    	UpdateData(FALSE);
    	return TRUE;
    }
     
    void CDlgFormDyn::test() 
    {
    CComboBox* cbBox;
    CButton* cbt = new CButton();
    CRect rect;
     
    TC_ITEM TabItem;
    TabItem.mask = TCIF_TEXT | TCIF_IMAGE;
    TabItem.pszText = "onglet3";
     
    // 2 facons de créer mes onglets
    m_tab_ongl->InsertItem(0, "onglet1");
    m_tab_ongl->InsertItem(1, "onglet2");
    m_tab_ongl->InsertItem(2, &TabItem);
     
    GetWindowRect(&rect);
    rect.left	= POS_X_DEB;			//20
    rect.right	= rect.left+TAILLE_X;		//20+80
    rect.top	= POS_Y_DEB;			//90
    rect.bottom = rect.top+TAILLE_Y;		//90+20	
     
     
    	for(int i=0; i<20; i++) {
    		cbBox = new CComboBox();
     
    		if(!cbBox->Create(CBS_DROPDOWNLIST | WS_VISIBLE,rect2,m_tab_ongl,1))
    			return;      // fail to create
    		cbBox->AddString("ma combobox");
    		cbBox->ShowWindow(SW_SHOW);
     
    		rect2.left += 100;
    		rect2.right = rect2.left+TAILLE_X;
    		maj_rect(rect2);
    	}
    }
     
    bool CDlgFormDyn::maj_rect(CRect& rect) 
    {
    	if(rect.left > SIZE_MAX_X) {
    		rect.left	= POS_X_DEB;
    		rect.right	= rect.left+TAILLE_X;
    		rect.top	+= INCR_Y;
    		rect.bottom = rect.top+TAILLE_Y;
    		return true;
    	}
    	return false;
    }
    Je n'utilise pas de "view" car je dois intégrer ceci dans un module déjà existant n’ayant pas cette spécificité.

    Quelqu'un a t il une idée ou a deja été confronté à ce problème ?

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 069
    Points : 12 113
    Points
    12 113
    Par défaut
    Pourquoi utiliser directement un CTabCtrl plutôt qu'une CPropertySheet ?

    Ci-dessous une référence VS2012 mais je suis quasi certain que cela existait déjà en VC++6.
    http://msdn.microsoft.com/en-us/library/614xe086.aspx

  3. #3
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Merci. Donc en gros, mon CTabCtrl devient CPropertySheet et mes différents onglets des CPropertyPage.
    Au lieu d'utiliser des "AddItem", j'utilise des "AddPage".
    Par contre j'ai un pointer null lors du create.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CPropertySheet*	m_tab_ongl	= new CPropertySheet();
     
    CPropertyPage* page1 = new CPropertyPage("onglet1");
    CPropertyPage* page2 = new CPropertyPage("onglet2");
     
    m_tab_ongl->AddPage(page1);
    m_tab_ongl->AddPage(page2);
     
    m_tab_ongl->Create(this,WS_CHILD | WS_VISIBLE);

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 069
    Points : 12 113
    Points
    12 113
    Par défaut
    Je pense qu'il faut fournir lID du template associé à chaque CPropertyPage avant de créer la PropertySheet.
    L'assert doit d'indiquer, directement ou indirectement la chose à initialiser avant d'utiliser la méthode où l'assert t'engueule.

  5. #5
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    oui le null pointer exception vient bien de cette fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void CPropertyPage::PreProcessPageTemplate(PROPSHEETPAGE& psp, BOOL bWizard)
    {
    	....
    	ASSERT(pTemplate != NULL);
    }
    Par contre je ne vois pas comment initialiser ce "template" afin qu'il ne soit plus null lors de l'appel du create


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CPropertyPage* page1 = new CPropertyPage();
    page1->Create("onglet1",m_tab_ongl);
    page2->Create("onglet2",m_tab_ongl);
    m_tab_ongl->AddPage(page1);
    m_tab_ongl->AddPage(page2);
    En tentant cette approche mais des le 1er create sur ma CPropertyPage j'ai un assert(false)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    BOOL CDialog::Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd) {
    ...
    if (!_AfxCheckDialogTemplate(lpszTemplateName, FALSE))
    		ASSERT(FALSE);          // invalid dialog template name
    }
     
    BOOL AFXAPI _AfxCheckDialogTemplate(LPCTSTR lpszResource, BOOL bInvisibleChild) {
    ...
    	HRSRC hResource = ::FindResource(hInst, lpszResource, RT_DIALOG);
    }
    hResource vaut NULL

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 069
    Points : 12 113
    Points
    12 113
    Par défaut
    Une propertypage, c'est un peu comme une boite de dialogue, vous devez donner un template pour créer correctement les contrôles qu'elle doit contenir.

  7. #7
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Je comprends tout a fait ce principe par contre je ne vois pas à quel moment doit ton lui fournir ce template. Comme je fais une construction dynamique, comment dois je lui de dire quel est son template ?

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 069
    Points : 12 113
    Points
    12 113
    Par défaut
    C'est le genre de question que je règle en lisant les sources des MFC puis en regardant la documentation pour vérifier que les moyens détectés dans les sources sont "documentés".
    Mais je n'ai pas vos MFC.

    Donc, en gros, le flag "PSP_DLGINDIRECT" devrait être un bon axe de recherche.

    http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx

  9. #9
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Merci pour tes conseils.
    Dans mon projet, j'utilise une CDialog que j'ai crée de facon "graphique" via Visual6.
    Voici sa definition dans le fichier .rc du projet associé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    IDD_FORM_DYN DIALOG DISCARDABLE  0, 0, 639, 373
    STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
    CAPTION "Dialog"
    FONT 8, "MS Sans Serif"
    BEGIN
        DEFPUSHBUTTON   "OK",IDOK,582,7,50,14
        PUSHBUTTON      "Cancel",IDCANCEL,582,24,50,14
        LTEXT           "Nom:",IDC_BANDEAU_FORM,7,26,566,8
        CTEXT           "Static",IDC_TIT_FDYN,7,9,568,8
    END
    Dans mon .h
    Ensuite j'ai une classe qui herite de CDialog qui correspond à la fenetre qui va contenir par la suite mon CPropertySheet

    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
    class CDlgFormDyn : public CDialog
    {
    // Construction
    public:
    	CDlgFormDyn(CWnd* pParent = NULL);
    	~CDlgFormDyn();
     
    // Dialog Data
    	//{{AFX_DATA(CDlgFormDyn)
    	enum { IDD = IDD_FORM_DYN };
    	CString			m_stit;
    	//}}AFX_DATA
     
    	...
    	CPropertySheet	*m_tab_ongl;
    	...
     
    // Generated message map functions
    protected:
    	//{{AFX_MSG(CDlgFormDyn)
    	virtual BOOL OnInitDialog();
    	virtual void DoDataExchange(CDataExchange* pDX);
    	//}}AFX_MSG
    	DECLARE_MESSAGE_MAP()
    };
    Dans mon .cpp:
    j'implemente cette classe

    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
    CDlgFormDyn::CDlgFormDyn(CWnd* pParent /*=NULL*/)
    	: CDialog(CDlgFormDyn::IDD, pParent)
    {
    	//{{AFX_DATA_INIT(CDlgFormDyn)
    	//}}AFX_DATA_INIT
    	m_tab_ongl	= new CPropertySheet();
    }		
     
     
    BOOL CDlgFormDyn::OnInitDialog() 
    {
    	CDialog::OnInitDialog();
    	test() ;
    	UpdateData(FALSE);
     
    	return TRUE;  // return TRUE unless you set the focus to a control
    	              // EXCEPTION: OCX Property Pages should return FALSE
    }
    J'aurais une question subsidiaire:
    faut il que je crée une classe héritant de CPropertyPage dont l'interface graphique sera vide et complétée dynamiquement par la suite ? Ou seulement un objet CPropertyPage crée a la volé sur lequel ensuite j'ajoute mes différents CStaic, Combobox... suffit ?

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 069
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 069
    Points : 12 113
    Points
    12 113
    Par défaut
    faut il que je crée une classe héritant de CPropertyPage dont l'interface graphique sera vide et complétée dynamiquement par la suite ? Ou seulement un objet CPropertyPage crée a la volé sur lequel ensuite j'ajoute mes différents CStaic, Combobox... suffit ?
    La première approche, bien que plus "lourde" a plus de potentiel car elle aura accès la "l'interface" protected de la classe CPropertySheet, la second ne peut utiliser que ce qui est public de cette classe.

Discussions similaires

  1. [XL-2007] Création d'onglet en fonction d'une colonne dynamique
    Par problemeaide dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 11/12/2012, 16h16
  2. Réponses: 1
    Dernier message: 08/03/2010, 14h01
  3. Création d'onglets dynamiquement
    Par nicolav dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 03/07/2009, 13h35
  4. [MFC] Création dynamique d'ocx
    Par tyarcaouen dans le forum Visual C++
    Réponses: 2
    Dernier message: 28/01/2008, 14h09
  5. [MFC] communication entre onglets d'une fenêtre
    Par bigboomshakala dans le forum MFC
    Réponses: 12
    Dernier message: 29/05/2004, 12h12

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