IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > Contrôles > Colorisations
        Comment gérer la couleur sur un contrôle CStatic ou CEdit ?
        Comment changer la couleur de fond des contrôles dans une boîte de dialogue ?
        Comment afficher une image dans un contrôle dans une boîte de dialogue ?



Comment gérer la couleur sur un contrôle CStatic ou CEdit ?
Mise à jour le 20/05/2006[haut]
auteur : Farscape
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

HBRUSH CtlColor(CDC* pDC, UINT nCtlColor)
Exemple d'implémentation simple (à stocker dans un .h ) :.

// 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:

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 :

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.


Comment changer la couleur de fond des contrôles dans une boîte de dialogue ?
Mise à jour le 16/07/2004[haut]
auteur : 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 :

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

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 : http://farscape.developpez.com/Samples/MDIColorView.zip


Comment afficher une image dans un contrôle dans une boîte de dialogue ?
auteur : 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 :
http://www.codeguru.com/bitmap/CPicture.html

#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 :

m_BtPicture.LoadImg("artemis.bmp");
m_BtPicture.Invalidate();


Consultez les autres F.A.Q.


Valid XHTML 1.0 TransitionalValid CSS!

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 © 2004 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni 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.