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 :

CComboBox Read only [FAQ]


Sujet :

MFC

  1. #1
    Membre éclairé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Par défaut CComboBox Read only
    Bonjour,

    Je cherche un moyen simple de faire de metre en read only une ComboBox en drop list. J'ai lu le FAQ mais ce n'est que pour les dropdwn ou simple ComboBox.

    J'ai trouver se code http://www.codeguru.com/cpp/controls...cle.php/c1809/ mais bon c'est pas trop ce que j'appel simple.

    merci d'avance.

  2. #2
    Membre chevronné
    Avatar de PetitPapaNoël
    Développeur informatique
    Inscrit en
    Septembre 2006
    Messages
    559
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 559
    Par défaut
    Bonjour,

    J'ai eu cette même problématique il y a quelques temps. Es-tu allé voir ma discussion d'alors ? Je pense que ça pourrait t'aider...

  3. #3
    Membre éclairé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Par défaut
    Effectivement c'est pas bête comme idée et c'est simple à réaliser.

    Par contre j'ai une question par rapport au code. Si j'ai un manifeste permettant d'avoir les couleurs du thème appliquer sur le poste. Est ce que ce sont les couleur de base de windows thème 98 (gris pour le fond) ou le thème courant ?

  4. #4
    Membre chevronné
    Avatar de PetitPapaNoël
    Développeur informatique
    Inscrit en
    Septembre 2006
    Messages
    559
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 559
    Par défaut
    Oui, mais attention : ça ne suffit pas ! Ca ne règle que le problème de la couleur. Il faut aussi gérer le reste en créant une méthode SetReadOnly (comparable à celle de CEdit) et en redéfinissant un certain nombre de méthodes...

    Si tu as besoin d'aide, je pourrai te donner ce que j'ai fait.

    Pour ta question sur les couleurs, je ne suis pas au top dans ce domaine...

  5. #5
    Membre éclairé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Par défaut
    Je me doutai qu'il falait surcharger ces méthodes pour vérouillé la ComboBox. Par pas exactement lesquel puisque sa ne fait que 2 moi que j'utilise les MFC pour l'interface.

    oki merci de ton aide.

  6. #6
    Membre chevronné
    Avatar de PetitPapaNoël
    Développeur informatique
    Inscrit en
    Septembre 2006
    Messages
    559
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 559
    Par défaut
    Il ne s'agit pas de surcharges, mais de redéfinitions (le vocabulaire de la programmation objet est subtile)...

    Voici donc un extrait de ma classe.
    Dans le .h :
    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    class CMaCombo : public CComboBox
    {
    #pragma region Attributs
    protected :
    	/// <summary>Index de la sélection dans la liste.</summary>
    	int m_posSel;
     
    	/// <summary>Indique si la combobox est en lecture seule ou non.</summary>
    	bool m_lectureSeule;
     
    	/// <summary>Indique si la combobox a l'aspect grisé de la lecture seule ou non.</summary>
    	bool m_grise;
    #pragma endregion
     
    #pragma region Constructeurs & destructeur
    public :
    	/// <summary>Construit une instance de combobox.</summary>
    	CMaCombo()
    	{
    		m_posSel = -1;
    		m_lectureSeule = m_grise = false;
    	};
     
    	/// <summary>Libère la mémoire occupée par l'objet.</summary>
    	virtual ~CMaCombo() {};
    #pragma endregion
     
    #pragma region Accesseurs
    public :
    	/// <summary>Indique si la combobox est en lecture seule ou non.</summary>
    	/// <returns><c>TRUE</c> si la combobox est en lecture seule, <c>FALSE</c> sinon.</returns>
    	BOOL GetReadOnly() { return m_lectureSeule; };
     
    	/// <summary>Change le mode d'accès à la combobox : lecture seule ou mode normal.</summary>
    	/// <param name='valeur'><c>TRUE</c> pour passer en lecture seule, <c>FALSE</c> pour passer en mode normal.</param>
    	/// <returns><c>TRUE</c> si la modification s'est correctement effectuée, <c>FALSE</c> si une erreur
    	/// est intervenue.</returns>
    	BOOL SetReadOnly(BOOL valeur = TRUE);
    #pragma endregion
     
    #pragma region Méthodes
    public :
    	/// <summary>Ajoute un élément à la fin de la liste déroulable.</summary>
    	/// <param name='texte'>Libellé de l'élément à ajouter.</param>
    	/// <returns>Position dans la liste de l'élément ajouté, ou <c>CB_ERR</c> en cas d'échec de l'ajout,
    	/// ou <c>CB_ERRSPACE</c> si l'espace est insuffisant dans la liste pour ajouter l'élément.</returns>
    	int AddString(LPCTSTR texte);
     
    	/// <summary>Ajoute un élément à la liste déroulable à une position donnée.</summary>
    	/// <param name='index'>Index (en base 0) de l'élément à insérer, ou <c>-1</c> pour l'ajouter en fin de liste.</param>
    	/// <param name='texte'>Libellé de l'élément à ajouter.</param>
    	/// <returns>Position dans la liste de l'élément inséré, ou <c>CB_ERR</c> en cas d'échec de l'insertion,
    	/// ou <c>CB_ERRSPACE</c> si l'espace est insuffisant dans la liste pour ajouter l'élément.</returns>
    	int InsertString(int index, LPCTSTR texte);
     
    	/// <summary>Change la sélection de la combobox en fonction de l'index passé en paramètre.</summary>
    	/// <param name='index'>Index (en base 0) de l'élément à sélectionner, ou <c>-1</c> pour ne rien
    	/// sélectionner.</param>
    	/// <returns>Index (en base 0) de la nouvelle sélection, ou <c>CB_ERR</c> si la sélection a échoué
    	/// ou si aucun élément n'a été sélectionné.</returns>
    	int SetCurSel(int index)
    	{
    		m_posSel = CComboBox::SetCurSel(index);
    		return m_posSel;
    	};
     
    	/// <summary>Recherche dans la liste un libellé commençant par la chaîne de caractères passée en paramètre.
    	/// Si un libellé est ainsi trouvé, l'élément correspondant dans la liste est sélectionné.</summary>
    	/// <param name='posDepart'>Index de départ de la recherche (en base 0). <c>-1</c> pour une recherche
    	/// dans toute la liste.</param>
    	/// <param name='texte'>Chaîne de caractères devant correspondre au moins au début du libellé recherché.</param>
    	/// <returns>Index de l'élément sélectionné si le libellé a été trouvé, ou <c>CB_ERR</c> en cas d'échec
    	/// de la recherche.</returns>
    	int SelectString(int posDepart, LPCTSTR texte);
     
    	/// <summary>Supprime un élément de la liste en fonction de sa position.</summary>
    	/// <param name='index'>Index (en base 0) de l'élément à supprimer.</param>
    	/// <returns>Nombre d'éléments restant dans la liste (si <c>>= 0</c>), ou <c>CB_ERR</c> si l'élément
    	/// recherché n'a pas été trouvé.</returns>
    	int DeleteString(UINT index);
     
    	/// <summary>Vide la liste déroulable de tous ses éléments.</summary>
    	void ResetContent()
    	{
    		CComboBox::ResetContent();
    		SetLectureSeule();
    	};
     
    protected :
    	DECLARE_MESSAGE_MAP()
     
    	/// <summary>Change le mode d'accès à la combobox : lecture seule ou mode normal.</summary>
    	/// <param name='valeur'><c>true</c> pour passer en lecture seule, <c>false</c> pour passer en mode normal.</param>
    	/// <returns><c>true</c> si la modification s'est correctement effectuée, <c>false</c> si une erreur
    	/// est intervenue.</returns>
    	/// <remarks>Cette méthode est utilisée entre autres par <c>SetReadOnly</c>, qui, en plus, garde en mémoire
    	/// l'état de la combobox, ce qui n'est pas le cas de cette méthode.</remarks>
    	bool SetLectureSeule(bool valeur = true);
     
    	virtual void PreSubclassWindow()
    	{
    		CComboBox::PreSubclassWindow();
    		SetLectureSeule();
    	};
     
    	afx_msg HBRUSH CtlColor(CDC *pDC, UINT /*nCtlColor*/);
    	virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
    #pragma endregion
    Et dans le .cpp :
    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    #include "StdAfx.h"
    #include "MaCombo.h"
     
     
     
    #pragma region Accesseurs
     
    BOOL CMaCombo::SetReadOnly(BOOL valeur /*= TRUE*/)
    {
    	bool val = (valeur == TRUE);
     
    	if (val == m_lectureSeule)
    		return TRUE;
     
    	BOOL resu = SetLectureSeule(val);
     
    	if (resu)
    		m_lectureSeule = val;
     
    	return resu;
    }
     
    #pragma endregion
     
    #pragma region Méthodes
     
    BEGIN_MESSAGE_MAP(CMaCombo, CComboBox)
    	ON_WM_CTLCOLOR_REFLECT()
    END_MESSAGE_MAP()
     
     
    int CMaCombo::AddString(LPCTSTR texte)
    {
    	int resu = CComboBox::AddString(texte);
     
    	if ((resu != CB_ERR) && (resu != CB_ERRSPACE) && !m_lectureSeule && GetCount())
    		SetLectureSeule(false);
     
    	return resu;
    }
     
     
    int CMaCombo::InsertString(int index, LPCTSTR texte)
    {
    	int resu = CComboBox::InsertString(index, texte);
     
    	if ((resu != CB_ERR) && (resu != CB_ERRSPACE) && !m_lectureSeule && GetCount())
    		SetLectureSeule(false);
     
    	return resu;
    }
     
     
    int CMaCombo::SelectString(int posDepart, LPCTSTR texte)
    {
    	int resu = CComboBox::SelectString(posDepart, texte);
     
    	if (resu != CB_ERR)
    		m_posSel = resu;
     
    	return resu;
    }
     
     
    int CMaCombo::DeleteString(UINT index)
    {
    	int resu = CComboBox::DeleteString(index);
     
    	if ((resu != CB_ERR) && !GetCount())
    		SetLectureSeule();
     
    	return resu;
    }
     
     
    bool CMaCombo::SetLectureSeule(bool valeur /*= true*/)
    {
    	if (m_grise == valeur)
    		return true;
     
    	CEdit* pEdit	= (CEdit*) GetWindow(GW_CHILD);
    	bool resu	= true;
     
    	if (pEdit)
    		resu = pEdit->SetReadOnly(valeur)? true : false;
     
    	if (resu)
    	{
    		if (IsWindow(m_hWnd))
    			if (valeur)
    			{
    				m_tabStop = (GetStyle() & WS_TABSTOP)? true : false;
    				ModifyStyle(WS_TABSTOP, 0);
    			}
    			else if (m_tabStop)
    				ModifyStyle(0, WS_TABSTOP);
     
    		m_grise = valeur;
    		Invalidate();	// Déclenche la méthode CtlColor.
    	}
     
    	return resu;
    }
     
     
    HBRUSH CMaCombo::CtlColor(CDC *pDC, UINT /*nCtlColor*/)
    {
    	// Réglage de la couleur de fond en fonction du mode d'accès.
    	if (IsWindowEnabled() && !m_grise)
    	{
    		pDC->SetBkColor(GetSysColor(COLOR_WINDOW));
    		return GetSysColorBrush(COLOR_WINDOW);
    	}
    	else
    	{
    		pDC->SetBkColor(GetSysColor(COLOR_BTNFACE));
    		return GetSysColorBrush(COLOR_BTNFACE);
    	}
    }
     
     
    BOOL CMaCombo::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
    {
    	if (nCode == CBN_SELCHANGE)
    	{
    		// La notification CBN_SELCHANGE (changement de sélection dans la liste de la combobox)
    		// ne doit être envoyée à la fenêtre parent que dans le cas où la sélection a changé et où
    		// la combobox n'est pas en lecture seule.
    		int pos = GetCurSel();
     
    		if (pos == m_posSel)
    		{
    			// La sélection n'a pas changé ; on n'envoie pas la notification.
    			ShowDropDown(FALSE);
    			return TRUE;
    		}
     
    		if (m_lectureSeule)
    		{
    			// La combobox est en lecture seule ;
    			// on annule la modification et on n'envoie pas la notification.
    			ShowDropDown(FALSE);
    			CComboBox::SetCurSel(m_posSel);
    			return TRUE;
    		}
    		else
    			// La combobox n'est pas en lecture seule ;
    			// on enregistre la nouvelle sélection, puis on envoie la notification.
    			m_posSel = pos;
    	}
     
    	// Transmission de la notification.
    	return CComboBox::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
    }
     
    #pragma endregion
    Il ne s'agit que d'un extrait de ma classe, donc je ne garanti pas que ça compile...

  7. #7
    Membre éclairé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Par défaut
    Merci beacoup. Et les abut de langage sont une vraie plaie

    (Et pour ceux qui ne connaisse pas la différence entre surcharger et redéfinir aller voir un cours de programmation)

  8. #8
    Membre chevronné
    Avatar de PetitPapaNoël
    Développeur informatique
    Inscrit en
    Septembre 2006
    Messages
    559
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 559
    Par défaut
    Le code que j'ai donné dans mon précédent message est incomplet. Pour ceux que ça intéresse, une version corrigée de ce code a été ajouté à la FAQ.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Cle usb en read only
    Par elekis dans le forum Administration système
    Réponses: 2
    Dernier message: 14/03/2005, 08h29
  2. Ouvrir un document Excel en READ ONLY (avec VBA)
    Par beegees dans le forum Access
    Réponses: 2
    Dernier message: 29/12/2004, 20h48
  3. Rendre ma BD standby disponible en read only?
    Par learn dans le forum Administration
    Réponses: 2
    Dernier message: 30/03/2004, 11h31
  4. [controle] propriété read only
    Par Fizgig dans le forum Composants VCL
    Réponses: 6
    Dernier message: 28/08/2002, 10h30
  5. CheckBox en Read Only
    Par MrJéjé dans le forum C++Builder
    Réponses: 7
    Dernier message: 23/06/2002, 15h00

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