begin process at 2008 07 06 02:27:26
1 205 433 membres
14 nouveaux aujourd'hui
14 119 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

UTILISATION CTABCONTROL (MFC)


Information sur la source

Catégorie :API Niveau : Débutant Date de création : 24/02/2004 Vu / téléchargé: 4 475 / 930

Note :
10 / 10 - par 3 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (32)
Ajouter un commentaire et/ou une note

Description

Equivalent MFC de mon exemple Win32 sur les TabControl:

une resource de boîte de dialogue pour chaque onglet, donc une classe pour chaque onglet (dérivée de CChildTab au lieu de CDialog).
un tableau permet de paramétrer les onglets (titre, classe gérant le dialogue et Id du dialogue).

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

  • signaler à un administrateur
    Commentaire de tanguy_laverdure le 26/02/2004 13:14:14

    Merci pour cet exemple de code dur les tab control qui devrait m'être tres utile.
    Tanguy_Laverdure

  • signaler à un administrateur
    Commentaire de leneo42 le 06/01/2005 10:25:06

    merci aussi pour ce code qui va me servir de base pour un travail de projet! :)

  • signaler à un administrateur
    Commentaire de leneo42 le 03/03/2005 12:23:44

    Tout marche très bien mais comment faire pour récupérer les objet instancié dans la classe principal pour chaque objet. Car je voudrais accéder a des variables qui sont dans mes onglets???
    merci!

  • signaler à un administrateur
    Commentaire de ymca2003 le 03/03/2005 12:39:15

    les onglets sont accessibles par le tableau m_apChildTabDlg qui est un tableau de pointeur sur des CChildTabDlg. POur récupérer un onglet particulier, il suffit de savoir son indice puis de caster dans la classe voulue. Par exemple pour récupérer l'onglet d'indice 1 (le 2ème donc) :
    CDlg1* pDlg1 = ((CDlg*)m_apChildTabDlg[1]);

    ensuite tu accède aux membre de cette classe. Tu peux également vérifier le nom de la classe à partir des éléments du tableau en appelant IsKindOf(RUNTIME_CLASS(CDlg1))

  • signaler à un administrateur
    Commentaire de leneo42 le 03/03/2005 14:40:38

    Bonjour!!
    Tout d'abord merci de ta réponse et j'ai essayé ton bout de code.
    Pour mon problème je veux récupérer les info du 1er onglet de la classe CDlg1!

         CDlg1* pDlg1 = ((CDlg1*)m_apChildTabDlg[0]);
         pDlg1->ValDrag=buffer;
        UpdateData(false);
    delete pDlg1;

    Mais ce bout de code me met en erreur mon application avec tout d'abord la suppression de tout ce qui est affiché puis le lancement du debugger!!
    J'ai fait une erreur quelque part?

  • signaler à un administrateur
    Commentaire de ymca2003 le 03/03/2005 14:43:09

    delete pDlg1;

    si tu détruit l'onglet c'est sur que ca va pas aller... Les pointeurs sur les onglets ne doivent pas être détruits, ils seront libérées à la fin.

  • signaler à un administrateur
    Commentaire de leneo42 le 03/03/2005 15:18:16

    Merci ça marche nikel!!!
    Milles merci tu ma bien débloqué
    :) :) :)

  • signaler à un administrateur
    Commentaire de leneo42 le 03/03/2005 15:43:06

    Je suis encore désolé de redemandé quelquechose mais j'ai réfléchi à une situation ou avec une autre classe X on veut accéder à des variables de CDlg1!!
    déja CChildTabDlg** m_apChildTabDlg; est en protected? peut on l'accéder de l'extèrieur.

    Car dans ce cas les lignes des messages d'avant ne marche po car le compilateur me dit que m_apChildTabDlg n'est pas connu. J'ai fait un include de #include "TabCtrlDlg.h"!!! rien n'y fait!!

    Merc beaucoup de votre patience ;-/

  • signaler à un administrateur
    Commentaire de ymca2003 le 03/03/2005 15:57:35

    Soit tu met la variable en public, soit tu fait une fonction da'ction aux éléments du tableau.

    Dans les 2 cas tu devra accéder aux onglets par la boîte de dialogue parente des onglets (celle qui contient le tableau).

    une solution plus simple mais moins jolie est de mettre le tableau en variable globale plutot que membre d'une classe.

  • signaler à un administrateur
    Commentaire de leneo42 le 03/03/2005 16:43:05

    Le problème c'est que pour accéder a ce fameux m_apChildTabDlg il faut encore utiliser un objet:
    objet:

    CTabCtrlDlg monobjet;

    CDlg1* pDlg1 = ((CDlg1*)monobjet.m_apChildTabDlg[0]);

    Mais ça marche pas.
    Une fonction d'action me parait difficile dans mon cas sachant que les variables que je vais manipulé non jamais le même prototypage.


    cite:"Soit tu met la variable en public"!!!!!
    si je la met en public je ne pourrais comme même pas y accéder!!!!

    enfin je ne veux pas faire de variable globale car pour le premier problème que j'ai exposé j'aurais aussi pu le faire par ce moyen!!

    Je suis donc un peu coincé car si je peux pas communiqué avec les autres fenêtres je vois pas à quoi peux me servir les onglets!

  • signaler à un administrateur
    Commentaire de ymca2003 le 03/03/2005 16:47:12

    Le truc que tu peut faire c'est de passer un pointeur sur la boîte de dialogue parente à toutes les classes qui auront besion d'accéder aux onglets.

    Sinon, pourrais-tu exposer ce que tu souhaite faire comme interface graphique et les interractions entre les onglets et autres éléments du programme.

  • signaler à un administrateur
    Commentaire de leneo42 le 03/03/2005 17:21:55

    Le projet que je fait est un banc de test!
    Je créer des fiches de test qui sont stockés sur Excel puis je vais executé une machine d'état qui lance tout les test en appellant d'autres fonctions de com MODBUS, USB, ethernet!
    Donc j'ai vraiement besoin de pouvoir controler les échanges enntre chaque onglet. Je peux pas te filer les fichiers du projet car il y a des dll constructeurs qui coute assez chère!


    Donc comme exemple d'échange.
    J'ouvre un scénario qui va se déroulé et a un moment il va faire appelle à une fonction ou à une variable de l'onglet de communication serie!
    voial j'ai résumé j'espere que tu a compri a peu pres!

  • signaler à un administrateur
    Commentaire de gabeuskadi le 17/03/2005 19:19:38

    1000 mercis pour ce code

  • signaler à un administrateur
    Commentaire de BananaUltra le 24/03/2005 11:27:07

    Merci beaucoup pour ce fabuleux code...

    J'ai une question à propos de ce bout de code :

    //***************************************************************************************
    // Classe ChildTabDlg.
    //***************************************************************************************
    class CChildTabDlg : public CDialog
    {
    //=======================================================================================
    // Membres publics.
    //=======================================================================================
    public :
    // constructeur
    CChildTabDlg();
    DECLARE_DYNCREATE(CChildTabDlg)
    [...]


    A quoi correspond DECLARE_....
    C'est une exécution dans un .h ?

  • signaler à un administrateur
    Commentaire de ymca2003 le 24/03/2005 11:31:23

    DECLARE_DYNCREATE est une macro MFC qui signale que des objets de cette classe pourront être créés dynamiquement à parir tu nom de la classe.
    dans le  .cpp il y a également IMPLEMENT_DYNCREATE qui est l'implémentation.

    Ainsi dans le code, je stocke dans une structure de données un membre pClass = RUNTIME_CLASS() pour chacun des onglets pour créer l'objet à partir de sa classe directement avec un pClass->CreateObject.

  • signaler à un administrateur
    Commentaire de BananaUltra le 24/03/2005 12:11:41

    Ne connaissant pas la gestion des onglets, je me demande pourquoi tu utilises cette syntaxe (DECLARE_..., IMPLEMENT_...), on ne peut pas simplement créer des objets dynamiques avec la syntaxe "normal" : new ?
    Je comprends le pourquoi de ce bout de code, mais pas son interêt.

    Merci pour ta réponse plus que rapide :-)

  • signaler à un administrateur
    Commentaire de ymca2003 le 24/03/2005 12:27:59

    je pourrais très bien faire un new mais le faire avec cette méthode me permet de faire une init + générique car un tableau stocke tout ce dont j'ai besoin (l'id, le titre, l'objet et sa classe).

    Ainsi pour créer l'onglet, il n'y a qu'a parcourir le tableau et crer les onglets avec la bonne classe.

    un onglet est une boîte de dialogue et est donc associé à une classe (différente pour chaque onglet). Toutes ces classes dérivent également d'une même classe pour avoir un comportement commun

    pour le faire avec un new, il faudrait faire des cas spéciaux pour chaque onglet car il ne sont pas associer à la même classe. il faut donc faire un new en fonction de la classe, ce que permet IMPLEMENT_DYNAMIC.

  • signaler à un administrateur
    Commentaire de ymca2003 le 24/03/2005 12:29:17

    Par ailleyrs cette technique est largement utilisée dans le framework MFC pour créer les fenêtre. On donne simplement la classe de la fenêtre et l'objet est automatiquemùent créée en fonction de la classe

  • signaler à un administrateur
    Commentaire de BananaUltra le 24/03/2005 15:18:07

    Alors on continue avec les questions :

    # Je ne vois pas quand sont créés tes onglets tu dis que les objets "onglets" sont créés dynamiquement mais moi je comprends ton programme comme ça :
    Le prog. crée des onglets à l'execution et les cachent ou les affichent suivant le clic de la souris avec ShowWindow.
    Il n'y a pas de dynamique dans la création ?!

    # Où sont créés tes Objets CDlgx, je ne vois pas le code associés ?

    # 4 attributs dans ton tableau : (l'id, le titre, l'objet et sa classe)
    Je n'en vois que trois :
    (_T("texte"), RUNTIME_CLASS(CDlg1), CDlg1::IDD)

    # Est ce qu'il est possible que je modifie ton code pour remplacer ton tableau static (d'ailleurs pas pigé pourquoi il est static  et dans TabCtrlDlg.cpp) avec des new, si oui peux tu me renseigner ?

    Merci d'avance pour ton aide qui m'est d'un grand secours.

    PS : petite présentation par politesse :
    William, je suis étudiant en BTS IRIS 2° année, ton code d'onglets me sert pour la création d'une interface (projet Traitement de Surface avec BUS CAN) homme-machine.


  • signaler à un administrateur
    Commentaire de ymca2003 le 24/03/2005 15:31:15

    création des onglets :
    dans CTabCtrlDlg::OnInitDialog il y a une boucle qui parcoure le tableau et fait
    m_apChildTabDlg[i] = (CChildTabDlg*) s_aChildTabDescr[i].m_pClass->CreateObject();

    récupère la desription de l'onglet i, sa classe et crée l'objet (qui dérive de CChildTabDlg donc on caste) et sauvegarde dans un tableau des onglets (un tableau de CChildTabDlg car c'est la base que j'ai choisi pour mes onglets)

    m_apChildTabDlg[i]->Create(s_aChildTabDescr[i].m_nId, this);

    crée la boîte de dialogue avec l'id de ressource et le parent.

    Les objets CDialog (dont dérive CChildTabDlg) associés c'est le tableau m_apChildTabDlg (je ne me souvenais plus d'avoir mis 2 tableaux).

    Le tableau s_aChildTabDescr est static et dans TabCtrlDlg.cpp car c'est le parent qui se charge de créer les onglets donc les autres fichiers n'ont pas besoin de savoir qu'il existe.

    si tu veux mettre des new :

    dans la boucle située plus haut met :

    m_apChildTabDlg[0] = new CDlg1();
    m_apChildTabDlg[0]->Create(IDD_TAB1, this);
    m_apChildTabDlg[1] = new CDlg2();
    m_apChildTabDlg[1]->Create(IDD_TAB2, this);
    m_apChildTabDlg[2] = new CDlg3();
    m_apChildTabDlg[2]->Create(IDD_TAB3, this);
    ...
    ça fera exactement la même chose sauf que c'est moins maintenable si tu veux modifier l'ordre ou rajoutre des onglets (avec ma méthode seul le tableau est à modifier)

  • signaler à un administrateur
    Commentaire de BananaUltra le 24/03/2005 17:47:34

    Merci pour tes renseignements, ça m'a été bien utile aujourd'hui...
    Je pense que je te redemenderai des infos la semaine prochaine ;-)

    A+

  • signaler à un administrateur
    Commentaire de BananaUltra le 29/03/2005 17:24:08

    Resalut,

    Alors une petite question pour ymca2003 :
    Lorsque je travaille sur un Dialog (onglet) je peux sans problèmes ajouter des boutons, radio... mais je ne peux pas double cliquer dessus et donc ajouter mon code ?

    Tu as une petite idée ?!

  • signaler à un administrateur
    Commentaire de ymca2003 le 29/03/2005 17:36:00

    Supprime le fichier .clw, retourne dans le classwizzard, pour le regénerer à partir des fichers sources.
    s'il y a des erreurs c'est qu'il faudra modifier à la main les pseudos commentaires AFX (si tu n'y arrive pas, demande).

  • signaler à un administrateur
    Commentaire de BananaUltra le 29/03/2005 17:43:45

    Il a suffit de supprimer le .clw !
    Merci grâce à toi mon projet avance bien... ;-)

  • signaler à un administrateur
    Commentaire de BananaUltra le 31/03/2005 11:20:39

    Salut,

    Alors j'ai un gros souci :
    je n'arrive pas à "travailler" (envoyer des MessageBox, initialiser des radios...) sur les onglets ?

  • signaler à un administrateur
    Commentaire de BananaUltra le 31/03/2005 11:43:10

    Bon j'ai trouvé mon prblème, je n'avais pas associé la classe CDlgx au Dialog Box, j'avais créé une nouvelle classe ...

  • signaler à un administrateur
    Commentaire de BananaUltra le 12/04/2005 11:22:53

    Salut ymca2003,

    Alors j'ai une petite question :
    Pourquoi lors de ta Structure pour les caractéristiques des onglets :

    //=======================================================================================
    // Structure pour les caractéristiques des onglets.
    //=======================================================================================
    struct CChildTabDescr
    {
    LPCTSTR m_lpszName; // nom de l'onglet
    CRuntimeClass* m_pClass; // classe de la boîte de dialogue fille associée
    int m_nId; // Id du dialogue

    // constructeur
    CChildTabDescr(LPCTSTR lpszName, CRuntimeClass* pClass, int nId)
    {
    m_lpszName = lpszName;
    m_pClass = pClass;
    m_nId = nId;
    }
    };

    Tu utilises une structure et non pas une classe ? (comme il ya un "constructeur", je me demande ??)

    Merci d'avance ;-)

  • signaler à un administrateur
    Commentaire de ymca2003 le 14/04/2005 19:28:04

    En fait le constructeur sert pas à grand chose c'est parceque au début j'avais mis CString au lieu de LPTSTR et l'init du tableau ne marchait pas. Mais bon en C++ struct et class font la même chose sauf que avec une struct tout est public.

  • signaler à un administrateur
    Commentaire de BananaUltra le 28/04/2005 16:49:42

    Salut,

    Alors je ne sais pas où poser cette question donc jte la pose à toi ;-)

    Voilà la feuille fille lié à l'onglet n°1 (Dlg1) est plus grande que la fenêtre principale (TabCtrl).
    J'ai donc placé un ScrollBar Vertical sur l'onglet 1 mais après ?
    Je ne sais même pas si j'ai bien fais de le placer sur Dlg1 ?
    En gros comment puis je faire pour utiliser la ScrollBar qui me ferais descendre - monter le contenu de l'onglet 1
    par rapport à la taille (qui ne dois plus bouger) du Tab Control ?

    Je te remercie d'avance

    Banana

    PS : si tu penses que ce message à plus sa place dans le forum ou ailleurs préviens moi.

  • signaler à un administrateur
    Commentaire de frenchmikey le 13/10/2005 02:34:16

    Salut a tous!!

    Merci pour ce code, c`est exactement ce que je cherchais pour un projet.
    Mais etant debutant j`ai une question "stupide":

    je veux integrer ce code ds un programme qui traite de fichiers de data et envoyer des valeurs ds les Dialog Box dlg1,dlg2 comme remplir une ComboBox ou une ListBox.
    ici mon code mais ca marche pas trop...
    /******************************************/

    CDlg3* pDlg3 = ((CDlg3*)m_apChildTabDlg[0]);
    / mise à jour affichage
    UpdateChildTab();
    pDlg3->m_combo1.AddString("hggd");
    UpdateData(false);

    j`obtiens un Debug Assertion failed message...

    merci pour votre aide !!

    Michael

  • signaler à un administrateur
    Commentaire de rayasahnoun le 05/04/2007 11:52:06

    Bonjour,
    j'ai une application  Win32 et j'ai besoin de faire l'equivalent.
    je sais pas grand chose sur les MFC (juste les principes de bases).
    Est ce que je dois refaire tout?

  • signaler à un administrateur
    Commentaire de cgod1 le 18/06/2007 17:45:11

    Bonjour a tous,

    Je viens de lire l'ensemble des commentaires super enrichissant sur ce code (qui m'a d'ailleur débloqué sur une appli que je crée) et j'ai une petite question surement toute bête.

    Aprés création de l'ensemble et avoir initialisé mes variables controles des Dlg filles (onglets) par l'équivalent de : CDlg1* pDlg1 = ((CDlg1*)m_apChildTabDlg[0]); dans le Dlg parent j'ai incorporer dans un Dlg fille une fonction style 'OnEditchange' pour une variable controle CComboBox d'un Dlg fille. Tout compile trés bien mais le soucie c'est que je ne rentre même pas dans la fonction à l'execution quand je modifie ce champ avec une autre valeur du CComboBox.

    Quelqu'un aurait il une réponse, car la je vois pas le pb surtout que ça compile link et que j'au aucune erreur d'execution.

    :-(

Ajouter un commentaire

Pub



Appels d'offres

Plugin Dialer outlook
Budget : 2 000€
Travail graphique- ill...
Budget : 1 000€
creation de marque et ...
Budget : 1 000€

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Boutique

Boutique de goodies CodeS-SourceS