Botones con iconos en Visual C++
Las imágenes tienen que estar preparadas en un CImageList fuera de la clase luego ser pasadas con la función SetImageList indicando la posicion de la imagen que se utilizará. Deben asignarse las imágenes en pares por que la segunda imagen se utiliza para pintarlo en el modo presionado.
- Code: Seleccionar todo
void CImageButton::SetImageList(CImageList *Images, INT imageIndex)
{
m_images = Images;
m_iImageIndex = imageIndex;
}
Antes de que nuestro control se instancie con la variable debemos asegurarnos que tenga la propiedad de pintado por el usuario (Owner Draw).
- Code: Seleccionar todo
void CImageButton::PreSubclassWindow()
{
CButton::PreSubclassWindow();
ModifyStyle(0, BS_OWNERDRAW);
}
La funcion siguiente es la que pinta el boton, le quité mucho codigo. En los archivos de descarga los encontrarás. El resto de las funciones esta intactas.
- Code: Seleccionar todo
void CImageButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct != NULL);
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rect = lpDrawItemStruct->rcItem;
UINT state = lpDrawItemStruct->itemState;
UINT nStyle = GetStyle();
int nSavedDC = pDC->SaveDC();
if (state & ODS_SELECTED){
::DrawFrameControl(lpDrawItemStruct->hDC,
&rect,DFC_BUTTON|DFCS_ADJUSTRECT,DFCS_PUSHED);
}else{
::DrawFrameControl(lpDrawItemStruct->hDC,
&rect,DFC_BUTTON|DFCS_ADJUSTRECT,DFCS_BUTTONPUSH);
}
CString strText;
GetWindowText(strText);
if (!strText.IsEmpty())
{
if(m_imagePos == ImageCenter){
goto WithImageCenter;
}
CSize Extent = pDC->GetTextExtent(strText);
CPont pt;
switch(m_imagePos){
case ImageLeft:
pt = CPont(
rect.right - Extent.cx - 10 ,
rect.CenterPont().y - Extent.cy / 2 );
break;
case ImageRight:
pt = CPont(
rect.left + 10 ,
rect.CenterPont().y - Extent.cy / 2 );
break;
case ImageTop:
pt = CPont(
rect.CenterPont().x - Extent.cx / 2,
rect.bottom - Extent.cy - 8);
break;
case ImageBottom:
pt = CPont(
rect.CenterPont().x - Extent.cx / 2,
rect.top + 8);
break;
}
if (state & ODS_SELECTED) {
pt.Offset(1,1);
}
pDC->SetBkMode(TRANSPARENT);
if (state & ODS_DISABLED){
pDC->DrawState(pt,Extent,strText,
DSS_DISABLED,TRUE, 0, (HBRUSH)NULL);
}else{
pDC->DrawState(pt,Extent,strText,
DSS_NORMAL,TRUE, 0, (HBRUSH)NULL);
}
}
WithImageCenter:
if(m_images != NULL){
CPont pt;
int cx,cy;
::ImageList_GetIconSize(m_images->m_hImageList,&cx,&cy);
switch(m_imagePos){
case ImageLeft:
pt = CPont( rect.left + 10,
rect.CenterPont().y - cy / 2 );
break;
case ImageRight:
pt = CPont( rect.right - cx -10,
rect.CenterPont().y - cy / 2 );
break;
case ImageTop:
pt = CPont( rect.CenterPont().x - cx / 2,
rect.top + 8);
break;
case ImageBottom:
pt = CPont( rect.CenterPont().x - cx / 2,
rect.bottom - cy - 8);
break;
case ImageCenter:
pt = CPont( rect.CenterPont().x - cx / 2,
rect.CenterPont().y - cy / 2 );
break;
}
if((state & ODS_SELECTED)){
pt.Offset(1,1);
m_images->Draw(pDC,m_iImageIndex+1,pt,ILD_TRANSPARENT);
}else{
m_images->Draw(pDC,m_iImageIndex ,pt,ILD_TRANSPARENT);
}
}
if(state & ODS_FOCUS){
rect.DeflateRect(4,4);
::DrawFocusRect(lpDrawItemStruct->hDC,&rect);
}
pDC->RestoreDC(nSavedDC);
}
Otros Artículos en esta sección
-
Un control para el manejo de números decimales en Visual C++, está basado en la clase CEdit, y ha sido modificada para poder manipular y visualizar números decimales en formularios MFC.Same Game es un juego tipo puzzle (rompecabezas) de un solo jugador. El juego consiste en eliminar la mayor cantidad de grupos de elementos de un tablero de N x M.Puedes usar este control en tus aplicaciones Visual C++ para visualizar imágenes dentro de un formulario MFC o también en entornos derivados de CWnd.¿Alguna duda? Sientete libre de hacer tus pruntas en nuestro:

foro deVisual C++ »
