Vc/mfc - gestion de ctabctrl - gestion d'onglets

Soyez le premier à donner votre avis sur cette source.

Vue 13 518 fois - Téléchargée 1 113 fois

Description

j'ai plutot mis longtemps à gérer les onglets correctements
Le pb est d'avoir une table a onglets sur un dialog box
et cet table à onglet ne couvrant qu'une partie de la boite de dialogue

aujourd'hui, qqn me pose la question, voici la réponse que je lui est faite (explications orales en moins)

ci dessous figure un brouillon de source qui sera repris ultérieurement.

Un exemple concret est dans le fichier joint

la procédure donnée si dessous y a été simplifiée
En plus, il montre des choses amusantes comme le fait que l'on puisse y rendre cachées les sous boites.... avec IDOK et IDCANCEL

Bonne prog

Source / Exemple :


1 Créer nun obj graphiq tab CTRL

	lui associer une var de ctrl CTabCTRL

2 Créer une boite pr les sous fenetres
	style 		:	Child & NoBordered
	more style	:	control
	
3 Créer les classes associées aux sous fenetres
	sachant que leur constructeur doit initialiser un ptr sur la classe mere
		(simplification gestion des CTRL au sein de la sous classe)
		
						
				DChoixTraitement::DChoixTraitement(CWnd* pParent/*=NULL*/):CDialog(DChoixTraitement::IDD, pParent)
				{
				/// -----------------------------------------------------------------------------------
				/// ---------------- DChoixTraitement::DChoixTraitement(CWnd* pParent) ----------------
				/// -----------------------------------------------------------------------------------
				/// -----  Objectif	: Constructeur de la classe : DChoixTraitement
				/// -----  Auteur(s)	: Magic_Nono 07/07/04
				/// -----  PostCond	: Toutes les variables de la classe doivent être instanciées avec une valeur par défaut ou contextuelle
				/// -----------------------------------------------------------------------------------
				/// -----  CWnd* pParent(par défaut : 'NULL')	: pointeur sur la fenetre mère
				/// -----------------------------------------------------------------------------------
					//{{AFX_DATA_INIT(DChoixTraitement)
					m_cTraceCode=FALSE;
					m_cRepartitCode=FALSE;
					m_cMiseEnForme=FALSE;
					m_cCommenteCode=FALSE;
					m_bCommenterManuellement = FALSE;
					//}}AFX_DATA_INIT
					m_pFPrinc=(DMetaProgPrinc*)pParent;
				}
		
		Permettre aux fenetres de se détrure en fin de prog
			avec une fonction PostNcDestroy
			appellée ainsi
				avec le classwizard en méthode prédéfinie de la classe
			dont voici le détail
				void DChoixTraitement::PostNcDestroy()
				{
				/// -------------------------------------------------------------------
				/// ---------------- DChoixTraitement::PostNcDestroy() ----------------
				/// -------------------------------------------------------------------
				/// -----  Objectif	: Appelé à la destruction de la fenetre
				/// -----  Auteur(s)	: Magic_Nono 10/08/04
				/// -----  PreCond	: /
				/// -----  PostCond	: /
				/// -------------------------------------------------------------------
					//fonction appelée à la destruction de la fenetre mere
					// TODO: Add your specialized code here and/or call the base class
					CDialog::PostNcDestroy();
					delete(this);
				}

				

4 ds la cl princ
	mettre un pointeur par sous fenetre (var membre)
	
	ds OnInitDialog
			initialiser les onglets
			
					c_tabChoixTrtt.DeleteAllItems();
					/// Algo : init titres
					///nota : pb possible en mode release : soluce :
					///+	char titre[50]
					///+	strcpy(titre,"yyyyyyyy");
					///+	tabCtrlItem.pszText = titre;
					BString plomp;
					//	TC_ITEM tabCtrlItem;
					//	tabCtrlItem.mask=TCIF_TEXT;
					plomp=BLang::getTxtLangue("choixTraitement",false);
					//	tabCtrlItem.pszText=plomp;
					c_tabChoixTrtt.InsertItem( 0,plomp);
					plomp=BLang::getTxtLangue("choixNettoyage",false);
					
					//		tabCtrlItem.pszText=_T(plomp);
					c_tabChoixTrtt.InsertItem( 1,plomp );
					//		tabCtrlItem.pszText=_T(plomp);
					c_tabChoixTrtt.InsertItem( 2,BLang::getTxtLangue("choixInfo",false) );
					//		tabCtrlItem.pszText=_T(plomp);
					c_tabChoixTrtt.InsertItem( 3,BLang::getTxtLangue("choixAssistant",false) );
					//		tabCtrlItem.pszText=_T(plomp);
					c_tabChoixTrtt.InsertItem( 4,BLang::getTxtLangue("choixAide",false) );

		pour chaque sous fenetre, créer une instance
				m_pChoixDeveloppement=new DChoixDevel(this);
				m_pChoixDeveloppement->Create(IDD_DCHOIX_DEVELOPPEMENT,this);
				m_pChoixDeveloppement->ShowWindow(SW_HIDE);
		
		positionner la fenêtre
			/// Algo : init sous fenetres (positionnement)
			{
				//getSystemMetric
				CRect rectTab;
				c_tabChoixTrtt.GetWindowRect(&rectTab);
				ScreenToClient(&rectTab);
				rectTab.left+=5;
				rectTab.top+=25;
				unsigned int largeur=rectTab.Width()-10,hauteur=rectTab.Height()-10;
				m_pChoixDeveloppement->SetWindowPos(NULL, rectTab.left , rectTab.top, largeur, hauteur, SWP_NOZORDER);
				m_pChoixTraitement->SetWindowPos(NULL, rectTab.left , rectTab.top, largeur, hauteur, SWP_NOZORDER);
				m_pChoixInfo->SetWindowPos(NULL, rectTab.left , rectTab.top, largeur, hauteur, SWP_NOZORDER);
			}

		gérer les affichages
			m_pChoixDeveloppement->ShowWindow(iTraitement==3?SW_SHOW:SW_HIDE);

		initialiser l'onglet courent
			c_tabChoixTrtt.SetCurSel(tmp);

	récupérer l'evt sur modification ds le tabCTRL
			BOOL DMetaProgPrinc::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
			{
			/// ----------------------------------------------------------------------------------------------------------------
			/// ---------------- DMetaProgPrinc::OnNotify(WPARAM wParam ,LPARAM lParam ,LRESULT* pResult) -> BOOL ----------------
			/// ----------------------------------------------------------------------------------------------------------------
			/// -----  Objectif	: action... pour la récup de cht d'onglet
			/// -----  Auteur(s)	: Magic_Nono 10/08/04
			/// -----  PreCond	: 1 evt récupéré
			/// -----  PostCond	: /
			/// ----------------------------------------------------------------------------------------------------------------
			/// -----  WPARAM wParam	: TODO
			/// -----  LPARAM lParam	: paramètre complémentaire
			/// -----  LRESULT* pResult	: TODO
			/// ----------------------------------------------------------------------------------------------------------------
			/// -----  retour (BOOL)	: cf.obj
			/// ----------------------------------------------------------------------------------------------------------------
				//	UpdateData(true);
				if(wParam==IDC_TAB_SELECTION_TRAITEMENT)
				{
					NMHDR*plomp=(NMHDR*)lParam;
					if(plomp->code==TCN_SELCHANGE)
						majChoix();
				}
				return CDialog::OnNotify(wParam, lParam, pResult);
			}
		
		et le gérer
			
			void DMetaProgPrinc::majChoix()
			{
			/// ----------------------------------------------------------
			/// ---------------- DMetaProgPrinc::majChoix() ----------------
			/// ----------------------------------------------------------
			/// -----  Objectif	: cht de la sélection du tab CTRL
			/// -----  Auteur(s)	: Magic_Nono 10/08/04
			/// -----  PreCond	: /
			/// -----  PostCond	: /
			/// ----------------------------------------------------------
				int iTraitement=c_tabChoixTrtt.GetCurSel();
				m_pChoixTraitement->ShowWindow(iTraitement<=1?SW_SHOW:SW_HIDE);
				if(iTraitement<=1)
				{
					m_pChoixTraitement->active(iTraitement==0);
				}
				else
				{
					m_pChoixTraitement->ShowWindow(SW_HIDE);
				}
				m_pChoixInfo->ShowWindow(iTraitement==2?SW_SHOW:SW_HIDE);
				m_pChoixDeveloppement->ShowWindow(iTraitement==3?SW_SHOW:SW_HIDE);
				c_aide.ShowWindow(iTraitement==4?SW_SHOW:SW_HIDE);
				UpdateData(false);
				majAffichage();
			}

____
nota d mon prog, je gère les affichages ainsi... (fonction tronquée des élts ne concernant pas la gestion d'onglet : gestion menus....)

void DMetaProgPrinc::majAffichage()
{
/// --------------------------------------------------------------
/// ---------------- DMetaProgPrinc::majAffichage() ----------------
/// --------------------------------------------------------------
/// -----  Objectif	: Mise à jours des éléments de la fenêtre accessibles ou non
/// -----  Explic		: 1 check extention & 2 maj Affichage
/// -----  Auteur(s)	: Magic_Nono 05/09/03
/// -----  PreCond	: /
/// -----  PostCond	: /
/// --------------------------------------------------------------
	UpdateData(true);
	try
	{
		if(m_pChoixInfo==NULL ||m_pChoixDeveloppement==NULL ||m_pChoixTraitement==NULL)

			/// algo : sécu
			return;
		/// algo : MaJ ext-> int
		m_pChoixDeveloppement->UpdateData(true);
		m_pChoixInfo->UpdateData(true);
		m_pChoixTraitement->UpdateData(true);
		
		/// algo : SI un langage traité
		if(m_iLangage!=LANGAGE_AUCUN)
		{
			int iTraitement=c_tabChoixTrtt.GetCurSel();
					if(iTraitement!=2)
				m_pChoixInfo->desactive();
			if(iTraitement!=3)
				m_pChoixDeveloppement->desactive();
			if(iTraitement>1)
				m_pChoixTraitement->desactive();
			///algo : SI mode développement ss fichier & pas développement ni aide
			if(developpementSeuls && iTraitement!=3 && iTraitement!=4)	//pas aide ou dvt ...
			{
				///algo : warning puis (*)
				c_launch.EnableWindow(false);
				return;
			}
			switch(iTraitement)
			{
			case 0:	//traiter
			case 1:	//nettoyer
c_launch.EnableWindow(m_pChoixTraitement->active(iTraitement==0));
				break;
			case 2:	//information
				c_launch.EnableWindow(m_pChoixInfo->active());
				break;
			case 3:	//développer - wizards
				c_launch.EnableWindow(m_pChoixDeveloppement->active(developpementSeuls ,m_cAvecHeader==TRUE));
		}
	}
... 
/// algo : Mise à jour des fenetres
	m_pChoixDeveloppement->UpdateData(false);
	m_pChoixInfo->UpdateData(false);
	m_pChoixTraitement->UpdateData(false);
	}
	TRAITE_EXCEPTION_B;
	UpdateData(false);
}

Conclusion :


cette version fonctionne sans problème avec VC6

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

magic_Nono
Messages postés
1878
Date d'inscription
jeudi 16 octobre 2003
Statut
Membre
Dernière intervention
16 mars 2011
1 -
merci pour ton com jnduf

pour la libération, c'est le role du PostNcDestroy

Magicalement
++
Nono.
jnduf
Messages postés
6
Date d'inscription
vendredi 17 octobre 2003
Statut
Membre
Dernière intervention
28 mars 2006
-
Une dernière chose, pour éviter les fuites de mémoire, il faut absolument ajouter une libération des objets des class dialog.
Par exemple, dans la fonction DestroyWindows:
delete(m_pChoixDeveloppement)

A+
jnduf
Messages postés
6
Date d'inscription
vendredi 17 octobre 2003
Statut
Membre
Dernière intervention
28 mars 2006
-
Trop cool, c'est exactement ce que je cherchais !
Merci
vecchio56
Messages postés
6539
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7 -
Merci
magic_Nono
Messages postés
1878
Date d'inscription
jeudi 16 octobre 2003
Statut
Membre
Dernière intervention
16 mars 2011
1 -
cf zip

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.