Botones con iconos en Visual C++

Por:ivancp,enviado 14 Mar 2004
Muchas veces queremos agregarle color y vistosidad a la interfaz que estamos desarrollando. Como casi todo en Visual C++ tienen que ser implementado, ahora te muestro una clase derivada de CButton que pinta una imagen en una posición determinada.

imagebutton.gif
Vista previa los botones con imágenes en un dialogo 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);
}

Archivos Adjuntos

Otros Artículos en esta sección

  • NSChart - Visual C++
    Chart para visual c++, control que visualiza gráficos de barra y sectores en un dialogo MFC, puedes utilizarlo en tus aplicaciones para enriquecerlo mostrando histogramas y gráficos de sectores.
    Por: ivancp,2004-07-26
  • ImageCtrl.2 - Un Control Integrado para Pictures
    Es un control con el que puedes visualizar imágenes en formularios MFC, puede cargar Bitmaps de 16, 256 y 24 Bits.
    Por: MicroLogic©Software,2011-08-31
  • Shell para Simulación
    Shell para Simulación es una herramienta donde el usuario de manera interactiva puede modelar sistemas reales y definir sus características. La herramienta está orientada a la simulación de sistemas dinámicos y estocásticos que cambian de manera discreta.
    Por: nazg,2006-03-18
¿Alguna duda? Sientete libre de hacer tus pruntas en nuestro:
foro deVisual C++ »