| 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 ) :.
template < class GENERIC_CTRLCOLOR>
class CTplCtrl : public GENERIC_CTRLCOLOR
{
public :
CTplCtrl ()
{
m_arClrCtlText[0 ]= :: GetSysColor (COLOR_WINDOWTEXT);
m_arClrCtlText[1 ]= RGB (0 ,0 ,255 );
m_arClrCtlText[2 ]= RGB (128 ,0 ,0 );
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 ),
COLORREF clrCtlText = RGB (0 , 0 , 0 ),
ModeColor eMode= Normal)
{
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 ();
}
public :
HBRUSH m_arHbrClrCtlBk[3 ];
COLORREF m_arClrCtlBkText[3 ];
COLORREF m_arClrCtlText[3 ];
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;
pDC- > SetTextColor (m_arClrCtlText[eMode]);
if (! bCEdit) pDC- > SetBkMode (TRANSPARENT);
else pDC- > SetBkColor (m_arClrCtlBkText[eMode]);
if (m_arHbrClrCtlBk[eMode]) hbr = m_arHbrClrCtlBk[eMode];
return hbr;
}
virtual BOOL OnChildNotify ( UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult )
{
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);
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.
|
| 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)
{
m_HbrClrCtlBk= NULL ;
m_ClrCtlText= RGB (0 , 0 , 0 ) ;
}
CTestsDiversDlg:: ~ CTestsDiversDlg ()
{
if (m_HbrClrCtlBk) :: DeleteObject (m_HbrClrCtlBk);
}
void CTestsDiversDlg:: SetDialogBkColor (COLORREF clrCtlBk ,
COLORREF clrCtlText )
{
if (m_HbrClrCtlBk) :: DeleteObject (m_HbrClrCtlBk);
m_HbrClrCtlBk = :: CreateSolidBrush (clrCtlBk);
m_ClrCtlText = clrCtlText;
m_ClrCtlBk= clrCtlBk;
}
HBRUSH CTestsDiversDlg:: OnCtlColor (CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog:: OnCtlColor (pDC, pWnd, nCtlColor);
switch (nCtlColor)
{
case CTLCOLOR_DLG:
case CTLCOLOR_STATIC :
pDC- > SetTextColor (m_ClrCtlText);
pDC- > SetBkMode (TRANSPARENT);
If (m_HbrClrCtlBk ) hbr = m_HbrClrCtlBk;
break ;
}
return hbr;
}
|
|
| 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
{
public :
CBtPicture ();
public :
CPicture m_Picture;
CString m_sFilePathName;
public :
bool LoadImg (CString sFilePathName)
{
m_sFilePathName= sFilePathName;
return (m_Picture.Load (sFilePathName)?true :false );
}
CString GetPictureName (){ return m_sFilePathName;}
public :
virtual void DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct);
public :
virtual ~ CBtPicture ();
protected :
DECLARE_MESSAGE_MAP ()
} ;
CBtPicture:: CBtPicture ()
{
}
CBtPicture:: ~ CBtPicture ()
{
}
BEGIN_MESSAGE_MAP (CBtPicture, CButton)
END_MESSAGE_MAP ()
void CBtPicture:: DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT (lpDrawItemStruct ! = NULL );
CDC* pDC = CDC:: FromHandle (lpDrawItemStruct- > hDC);
CRect itemRect = lpDrawItemStruct- > rcItem;
if (m_Picture.m_IPicture)
{
m_Picture.UpdateSizeOnDC (pDC);
m_Picture.Show (pDC, CPoint (0 ,0 ),
CPoint (m_Picture.m_Width,
m_Picture.m_Height), 0 ,0 );
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.
|
|