FAQ VC++ et MFCConsultez toutes les FAQ

Nombre d'auteurs : 20, nombre de questions : 546, dernière mise à jour : 5 avril 2013  Ajouter une question

 

Cette faq a été réalisée pour répondre aux questions les plus fréquement posées sur le forum Développement Visual C++

Je tiens à souligner que cette faq ne garantit en aucun cas que les informations qu'elle contient sont correctes ; Les auteurs font le maximum, mais l'erreur est humaine. Si vous trouvez une erreur, ou si vous souhaitez devenir redacteur, lisez ceci.

Sur ce, je vous souhaite une bonne lecture. Farscape


SommaireContrôlesColorisations (3)
précédent sommaire suivant
 

La gestion de la couleur d'ecriture et de fond s'obtient en mappant le message reflect :
voir note msdn:TN062: Message Reflection for Windows Controls

Code c++ : Sélectionner tout
1
2
  
HBRUSH CtlColor(CDC* pDC, UINT nCtlColor)
Exemple d'implémentation simple (à stocker dans un .h ) :.

Code c++ : Sélectionner tout
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
  
// include 
///////////////////////////////////////////////////////////////////////////// 
// Classe Template attributs couleurs  
template <class GENERIC_CTRLCOLOR> 
class CTplCtrl : public GENERIC_CTRLCOLOR 
{ 
// Construction 
public: 
    CTplCtrl() 
    { 
        m_arClrCtlText[0]=::GetSysColor(COLOR_WINDOWTEXT);  
        m_arClrCtlText[1]=RGB(0  ,0  ,255); // LtBlue 
        m_arClrCtlText[2]=RGB(128,0,0);    // Red. 
        m_arClrCtlBkText[0]=::GetSysColor(COLOR_WINDOW);  
        m_arClrCtlBkText[1]=::GetSysColor(COLOR_WINDOW);  
        m_arClrCtlBkText[2]=::GetSysColor(COLOR_WINDOW);  
        for(int i=0;i<3;i++)  
        m_arHbrClrCtlBk[i]=::CreateSolidBrush(m_arClrCtlBkText[i]); 
    } 
  
   enum ModeColor 
   { 
    Normal, 
    Disable, 
    ReadOnly 
   }; 
  
    void SetBkColor(COLORREF clrCtlBk = RGB(192, 192, 192), // couleur de fond 
                    COLORREF clrCtlText = RGB(0, 0, 0),     // couleur d'écriture. 
                    ModeColor eMode=Normal)                 // mode actif/Inactif/lecture seule. 
    { 
        m_arClrCtlText[eMode]=clrCtlText; 
        m_arClrCtlBkText[eMode]=clrCtlBk; 
        if(m_arHbrClrCtlBk[eMode]) 
            ::DeleteObject(m_arHbrClrCtlBk[eMode]);  
        m_arHbrClrCtlBk[eMode] = ::CreateSolidBrush(clrCtlBk);         
        if(m_hWnd) Invalidate(); 
    } 
  
// Attributes 
public: 
  
    HBRUSH    m_arHbrClrCtlBk[3]; // brush de fond 
    COLORREF  m_arClrCtlBkText[3];// couleur du fond. 
    COLORREF  m_arClrCtlText[3];  // couleurs d'ecriture.   
  
// Operations 
public: 
  
    virtual ~CTplCtrl() 
    { 
        for(int i=0;i<3;i++)  
        if(m_arHbrClrCtlBk[i]) ::DeleteObject(m_arHbrClrCtlBk[i]); 
    }; 
  
    HBRUSH CtlColor(CDC* pDC, UINT nCtlColor) 
    { 
        bool bCEdit=(IsKindOf(RUNTIME_CLASS(CEdit))?true:false); 
        HBRUSH hbr=NULL; 
        ModeColor eMode=Normal; 
        if(GetStyle() & ES_READONLY) eMode=ReadOnly; 
        if(!IsWindowEnabled()) eMode=Disable; 
  
        // TODO: Change any attributes of the DC here 
        pDC->SetTextColor(m_arClrCtlText[eMode]); 
  
        // Fixe le fond en transparent  pour le texte 
        if(!bCEdit) pDC->SetBkMode(TRANSPARENT); 
        else pDC->SetBkColor(m_arClrCtlBkText[eMode]); 
  
        // retourne le handle de la brush pour le fond si il existe. 
        if(m_arHbrClrCtlBk[eMode]) hbr = m_arHbrClrCtlBk[eMode];  
  
        // TODO: Return a different brush if the default is not desired 
        return hbr; 
    } 
  
    virtual BOOL OnChildNotify( UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult ) 
    {        
        // interception du message reflect 
        if(message >= WM_CTLCOLORMSGBOX && message <= WM_CTLCOLORSTATIC) 
        {             
            UINT nCtlType = message - WM_CTLCOLORMSGBOX; 
            ASSERT(nCtlType >= CTLCOLOR_MSGBOX); 
            ASSERT(nCtlType <= CTLCOLOR_STATIC); 
  
            CDC dcTemp; dcTemp.m_hDC = (HDC)wParam; 
  
            HBRUSH hbr = CtlColor(&dcTemp, nCtlType); 
            // fast detach of temporary objects 
            dcTemp.m_hDC = NULL; 
            *pLResult = (LRESULT)hbr; 
            return TRUE; 
        } 
        return GENERIC_CTRLCOLOR::OnChildNotify( message,wParam, lParam,pLResult ); 
    }  
};
Principe: j'ai fait une classe template autonome pour la gestion des couleurs d'écritures et de fond .
celle ci intercepte le message à destination des contrôles pour la gestion de la couleur.
si on ne veut pas utiliser ce principe on pourra toujours intercepter manuellement le message reflect au niveau du contrôle et s'inspirer du traitement effectué dans la fonction CtlColor de la classe template proposée.
On pourra utiliser cette classe directement de cette manière:

Code c++ : Sélectionner tout
1
2
3
  
CTplCtrl<CEdit>  m_EditNom; 
CTplCtrl<CStatic> m_StaticNom;
Classwizard n'appréciant pas ce genre de déclaration dans un .h on pourra écrire la chose suivante :

Code c++ : Sélectionner tout
1
2
  
typedef CTplCtrl<CEdit> CEditEx
Et utiliser CEditEx comme nouvelle classe à la place de CEdit.
On pourra faire de même pour un CStatic.
Pour changer la couleur il suffira d'appeler la fonction SetBkColor dans la fonction OnInitialUpdate pour une CFormView ou OnInitDialog pour une CDialog, par exemple.

Mis à jour le 20 mai 2006 farscape

Il existe une fonction au niveau de la classe d'application permettant de gérer pour toute l'application la couleur de fond et la couleur d'écriture du texte des contrôles :

Code c++ : Sélectionner tout
1
2
3
  
CWinApp::SetDialogBkColor 
void SetDialogBkColor( COLORREF clrCtlBk = RGB(192, 192, 192), COLORREF clrCtlText = RGB(0, 0, 0) );
Mais cette méthode ne permet pas un changement dynamique par boîte de dialogue, donc voici une autre méthode.
Il faut implémenter le message WM_CTLCOLOR sur la CDialog

Code c++ : Sélectionner tout
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
  
CTestsDiversDlg:: CTestsDiversDlg () : CDialog(CTestsDiversDlg::IDD) 
{ 
  //{{AFX_DATA_INIT(CTestsDiversDlg) 
  //}}AFX_DATA_INIT 
  
/* HBRUSH   */  m_HbrClrCtlBk=NULL ; 
/* COLORREF */  m_ClrCtlText= RGB(0, 0, 0) ; 
} 
  
CTestsDiversDlg:: ~CTestsDiversDlg () 
{ 
   if(m_HbrClrCtlBk) ::DeleteObject(m_HbrClrCtlBk); 
} 
void CTestsDiversDlg::SetDialogBkColor(COLORREF clrCtlBk /*= RGB(192, 192, 192)*/, 
                                       COLORREF clrCtlText /*= RGB(0, 0, 0) */) 
{  
    //m_HbrClrCtlBk est à null dans le constructeur 
    if(m_HbrClrCtlBk) ::DeleteObject(m_HbrClrCtlBk);  
    m_HbrClrCtlBk = ::CreateSolidBrush(clrCtlBk);   
    m_ClrCtlText    = clrCtlText; 
    /* COLORREF */m_ClrCtlBk= clrCtlBk; 
} 
HBRUSH CTestsDiversDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)  
{ 
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); 
/* CTLCOLOR_BTN         button control 
   CTLCOLOR_DLG         dialog box 
   CTLCOLOR_EDIT        edit control 
   CTLCOLOR_LISTBOX     list box 
   CTLCOLOR_MSGBOX      message box 
   CTLCOLOR_SCROLLBAR   scroll bar 
   CTLCOLOR_STATIC      static text, frame, or rectangle  
*/ 
  
// TODO: Change any attributes of the DC here 
  
// par exemple en fonction de nCtlColor voir doc. 
    switch(nCtlColor) 
    { 
        // Intercepte le message pour la dialogue et les statics.  
        case CTLCOLOR_DLG: 
        case CTLCOLOR_STATIC  : 
                //  Fixe la couleur d'ecriture du texte 
                pDC->SetTextColor(m_ClrCtlText); 
                // enventuellement suivant les cas 
                // pDC->pDC->SetBkColor(m_ClrCtlBk); 
                // Fixe le fond en transparent  pour le texte  
                // à ne pas faire pour un edit. 
                pDC->SetBkMode(TRANSPARENT); 
                // retourne le handle de la brush pour le fond si il existe. 
                If(m_HbrClrCtlBk ) hbr = m_HbrClrCtlBk; 
                break; 
     } 
    // TODO: Return a different brush if the default is not desired 
    return hbr; 
}
le même code fonctionne avec une CFormView :

Mis à jour le 16 juillet 2004 farscape

Si l'image est dans les ressources on peut utiliser le contrôle Picture et dans les propriétés du contrôle sélectionner le type Bitmap ainsi que l'id de la ressource dans la combobox .
Pour un affichage d'une image externe il vaudra mieux passer par une classe CButton dérivée pour gérer l'affichage.
Pour les besoins de l'exemple j'ai fait simple je m'appuie sur un exemple de lecture d'image à partir de l'objet IPicture.
Le lien pour la classe CPicture :

Code c++ : Sélectionner tout
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
  
#include "Picture.h" 
class CBtPicture : public CButton 
{ 
// Construction 
public: 
   CBtPicture(); 
  
    // Attributes 
public: 
CPicture m_Picture; 
CString m_sFilePathName; 
  
// Operations 
public: 
    bool LoadImg(CString sFilePathName) 
    { 
        m_sFilePathName=sFilePathName; 
        return (m_Picture.Load(sFilePathName)?true:false); 
    } 
  
    CString GetPictureName(){return m_sFilePathName;} 
// Overrides 
   // ClassWizard generated virtual function overrides 
   //{{AFX_VIRTUAL(CBtPicture) 
   public: 
   virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);   
   //}}AFX_VIRTUAL 
  
// Implementation 
public: 
  
   virtual ~CBtPicture(); 
  
   // Generated message map functions 
protected: 
   //{{AFX_MSG(CBtPicture) 
      // NOTE - the ClassWizard will add and remove member functions here. 
   //}}AFX_MSG 
  
   DECLARE_MESSAGE_MAP() 
}; 
  
// source 
  
CBtPicture::CBtPicture() 
{ 
} 
  
CBtPicture::~CBtPicture() 
{ 
} 
  
BEGIN_MESSAGE_MAP(CBtPicture, CButton) 
  
   //{{AFX_MSG_MAP(CBtPicture) 
   // NOTE - the ClassWizard will add and remove mapping macros here. 
   //}}AFX_MSG_MAP 
  
END_MESSAGE_MAP() 
///////////////////////////////////////////////////////////////////////////// 
// CBtPicture message handlers 
void CBtPicture::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{ 
   // TODO: Add your code to draw the specified item 
   ASSERT(lpDrawItemStruct != NULL); 
   CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); 
   //UINT nState = lpDrawItemStruct->itemState; 
   CRect itemRect = lpDrawItemStruct->rcItem; 
   if(m_Picture.m_IPicture)    
   { 
       // Get Picture Dimentions In Pixels 
        m_Picture.UpdateSizeOnDC(pDC);  
        m_Picture.Show(pDC, CPoint(0,0), 
                        CPoint(m_Picture.m_Width, 
                               m_Picture.m_Height), 0,0); 
        // Change Original Dimentions   
        m_Picture.Show(pDC,itemRect);  
   } 
}
Le dessin de l'image est réalisé dans la fonction Drawitem .
Note : il faut mettre dans les propriétés du contrôle l'option OWner Draw sinon ça ne fonctionne pas.
Il reste plus qu'à attacher une variable de type contrôle bouton avec class wizard et de remplacer la classe Cbutton par CBtPicture et le tour est joué.
Utilisation :

Code c++ : Sélectionner tout
1
2
3
  
m_BtPicture.LoadImg("artemis.bmp"); 
m_BtPicture.Invalidate();

Mis à jour le 5 avril 2013 farscape

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Contacter le responsable de la rubrique C++