UTILISATION CTABCONTROL (MFC)

Messages postés
34
Date d'inscription
mercredi 19 novembre 2003
Statut
Membre
Dernière intervention
12 mai 2004
-
Messages postés
1
Date d'inscription
lundi 18 juin 2007
Statut
Membre
Dernière intervention
18 juin 2007
-
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/20735-utilisation-ctabcontrol-mfc

Messages postés
1
Date d'inscription
lundi 18 juin 2007
Statut
Membre
Dernière intervention
18 juin 2007

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.

:-(
Messages postés
8
Date d'inscription
mercredi 24 mai 2006
Statut
Membre
Dernière intervention
27 mars 2007

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?
Messages postés
1
Date d'inscription
jeudi 13 octobre 2005
Statut
Membre
Dernière intervention
13 octobre 2005

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
Messages postés
10
Date d'inscription
mardi 22 mars 2005
Statut
Membre
Dernière intervention
28 avril 2005

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.
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
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.
Messages postés
10
Date d'inscription
mardi 22 mars 2005
Statut
Membre
Dernière intervention
28 avril 2005

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 ;-)
Messages postés
10
Date d'inscription
mardi 22 mars 2005
Statut
Membre
Dernière intervention
28 avril 2005

Bon j'ai trouvé mon prblème, je n'avais pas associé la classe CDlgx au Dialog Box, j'avais créé une nouvelle classe ...
Messages postés
10
Date d'inscription
mardi 22 mars 2005
Statut
Membre
Dernière intervention
28 avril 2005

Salut,

Alors j'ai un gros souci :
je n'arrive pas à "travailler" (envoyer des MessageBox, initialiser des radios...) sur les onglets ?
Messages postés
10
Date d'inscription
mardi 22 mars 2005
Statut
Membre
Dernière intervention
28 avril 2005

Il a suffit de supprimer le .clw !
Merci grâce à toi mon projet avance bien... ;-)
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
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).
Messages postés
10
Date d'inscription
mardi 22 mars 2005
Statut
Membre
Dernière intervention
28 avril 2005

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 ?!
Messages postés
10
Date d'inscription
mardi 22 mars 2005
Statut
Membre
Dernière intervention
28 avril 2005

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

A+
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
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)
Messages postés
10
Date d'inscription
mardi 22 mars 2005
Statut
Membre
Dernière intervention
28 avril 2005

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.
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
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
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
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.
Messages postés
10
Date d'inscription
mardi 22 mars 2005
Statut
Membre
Dernière intervention
28 avril 2005

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 :-)
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
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.
Messages postés
10
Date d'inscription
mardi 22 mars 2005
Statut
Membre
Dernière intervention
28 avril 2005

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 ?
Messages postés
4
Date d'inscription
mardi 16 novembre 2004
Statut
Membre
Dernière intervention
2 juin 2005

1000 mercis pour ce code
Messages postés
20
Date d'inscription
vendredi 27 février 2004
Statut
Membre
Dernière intervention
7 avril 2005

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!
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
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.
Messages postés
20
Date d'inscription
vendredi 27 février 2004
Statut
Membre
Dernière intervention
7 avril 2005

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!
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
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.
Messages postés
20
Date d'inscription
vendredi 27 février 2004
Statut
Membre
Dernière intervention
7 avril 2005

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 ;-/
Messages postés
20
Date d'inscription
vendredi 27 février 2004
Statut
Membre
Dernière intervention
7 avril 2005

Merci ça marche nikel!!!
Milles merci tu ma bien débloqué
:) :) :)
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
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.
Messages postés
20
Date d'inscription
vendredi 27 février 2004
Statut
Membre
Dernière intervention
7 avril 2005

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?
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
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))
Messages postés
20
Date d'inscription
vendredi 27 février 2004
Statut
Membre
Dernière intervention
7 avril 2005

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!
Messages postés
20
Date d'inscription
vendredi 27 février 2004
Statut
Membre
Dernière intervention
7 avril 2005

merci aussi pour ce code qui va me servir de base pour un travail de projet! :)
Messages postés
34
Date d'inscription
mercredi 19 novembre 2003
Statut
Membre
Dernière intervention
12 mai 2004

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