UTILISATION CTABCONTROL (MFC)

tanguy_laverdure Messages postés 34 Date d'inscription mercredi 19 novembre 2003 Statut Membre Dernière intervention 12 mai 2004 - 26 févr. 2004 à 13:14
cgod1 Messages postés 1 Date d'inscription lundi 18 juin 2007 Statut Membre Dernière intervention 18 juin 2007 - 18 juin 2007 à 17:45
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

cgod1 Messages postés 1 Date d'inscription lundi 18 juin 2007 Statut Membre Dernière intervention 18 juin 2007
18 juin 2007 à 17:45
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.

:-(
rayasahnoun Messages postés 8 Date d'inscription mercredi 24 mai 2006 Statut Membre Dernière intervention 27 mars 2007
5 avril 2007 à 11:52
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?
frenchmikey Messages postés 1 Date d'inscription jeudi 13 octobre 2005 Statut Membre Dernière intervention 13 octobre 2005
13 oct. 2005 à 02:34
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
BananaUltra Messages postés 10 Date d'inscription mardi 22 mars 2005 Statut Membre Dernière intervention 28 avril 2005
28 avril 2005 à 16:49
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.
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
14 avril 2005 à 19:28
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.
BananaUltra Messages postés 10 Date d'inscription mardi 22 mars 2005 Statut Membre Dernière intervention 28 avril 2005
12 avril 2005 à 11:22
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 ;-)
BananaUltra Messages postés 10 Date d'inscription mardi 22 mars 2005 Statut Membre Dernière intervention 28 avril 2005
31 mars 2005 à 11:43
Bon j'ai trouvé mon prblème, je n'avais pas associé la classe CDlgx au Dialog Box, j'avais créé une nouvelle classe ...
BananaUltra Messages postés 10 Date d'inscription mardi 22 mars 2005 Statut Membre Dernière intervention 28 avril 2005
31 mars 2005 à 11:20
Salut,

Alors j'ai un gros souci :
je n'arrive pas à "travailler" (envoyer des MessageBox, initialiser des radios...) sur les onglets ?
BananaUltra Messages postés 10 Date d'inscription mardi 22 mars 2005 Statut Membre Dernière intervention 28 avril 2005
29 mars 2005 à 17:43
Il a suffit de supprimer le .clw !
Merci grâce à toi mon projet avance bien... ;-)
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
29 mars 2005 à 17:36
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).
BananaUltra Messages postés 10 Date d'inscription mardi 22 mars 2005 Statut Membre Dernière intervention 28 avril 2005
29 mars 2005 à 17:24
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 ?!
BananaUltra Messages postés 10 Date d'inscription mardi 22 mars 2005 Statut Membre Dernière intervention 28 avril 2005
24 mars 2005 à 17:47
Merci pour tes renseignements, ça m'a été bien utile aujourd'hui...
Je pense que je te redemenderai des infos la semaine prochaine ;-)

A+
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
24 mars 2005 à 15:31
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)
BananaUltra Messages postés 10 Date d'inscription mardi 22 mars 2005 Statut Membre Dernière intervention 28 avril 2005
24 mars 2005 à 15:18
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.
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
24 mars 2005 à 12:29
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
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
24 mars 2005 à 12:27
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.
BananaUltra Messages postés 10 Date d'inscription mardi 22 mars 2005 Statut Membre Dernière intervention 28 avril 2005
24 mars 2005 à 12:11
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 :-)
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
24 mars 2005 à 11:31
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.
BananaUltra Messages postés 10 Date d'inscription mardi 22 mars 2005 Statut Membre Dernière intervention 28 avril 2005
24 mars 2005 à 11:27
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 ?
gabeuskadi Messages postés 4 Date d'inscription mardi 16 novembre 2004 Statut Membre Dernière intervention 2 juin 2005
17 mars 2005 à 19:19
1000 mercis pour ce code
leneo42 Messages postés 20 Date d'inscription vendredi 27 février 2004 Statut Membre Dernière intervention 7 avril 2005
3 mars 2005 à 17:21
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!
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
3 mars 2005 à 16:47
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.
leneo42 Messages postés 20 Date d'inscription vendredi 27 février 2004 Statut Membre Dernière intervention 7 avril 2005
3 mars 2005 à 16:43
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!
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
3 mars 2005 à 15:57
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.
leneo42 Messages postés 20 Date d'inscription vendredi 27 février 2004 Statut Membre Dernière intervention 7 avril 2005
3 mars 2005 à 15:43
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 ;-/
leneo42 Messages postés 20 Date d'inscription vendredi 27 février 2004 Statut Membre Dernière intervention 7 avril 2005
3 mars 2005 à 15:18
Merci ça marche nikel!!!
Milles merci tu ma bien débloqué
:) :) :)
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
3 mars 2005 à 14:43
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.
leneo42 Messages postés 20 Date d'inscription vendredi 27 février 2004 Statut Membre Dernière intervention 7 avril 2005
3 mars 2005 à 14:40
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?
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
3 mars 2005 à 12:39
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))
leneo42 Messages postés 20 Date d'inscription vendredi 27 février 2004 Statut Membre Dernière intervention 7 avril 2005
3 mars 2005 à 12:23
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!
leneo42 Messages postés 20 Date d'inscription vendredi 27 février 2004 Statut Membre Dernière intervention 7 avril 2005
6 janv. 2005 à 10:25
merci aussi pour ce code qui va me servir de base pour un travail de projet! :)
tanguy_laverdure Messages postés 34 Date d'inscription mercredi 19 novembre 2003 Statut Membre Dernière intervention 12 mai 2004
26 févr. 2004 à 13:14
Merci pour cet exemple de code dur les tab control qui devrait m'être tres utile.
Tanguy_Laverdure
Rejoignez-nous