domingo, 6 de febrero de 2011

Creando un Boton personalizado

Aburrido de que los botones siempre luzcan iguales me puse a investigar un poco... Mi idea era que el boton luzca de una manera cuando el cursor del mouse esta posicionado sobre el botón y de otra manera cuando el cursor este fuera del botón. Mirando la infinidad de mensajes que tiene el windows, di con WM_MOUSEHOVER y WM_MOUSELEAVE, ¡exactamente lo que estaba buscando!, pero no todo es color de rosas, por defecto los botones en MFC tienen pocos menajes, y justamente estos dos que necesito ¡no están! así que luego de investigar 3 minutos (gracias google) di con cómo hacer para que el botón capture estos mensajes.

Como dije antes la idea es que el botón se vea de una forma cuando el cursor esta arriba él y de otra cuando el cursor esta fuera, para ello le pasamos dos HBITMAP que previamente cargamos a la función Crear() . Como se van a mostrar imágenes no es necesario pasarle texto ni los estilos, estos los predefino yo.

Para lograr que el botón tenga los mensajes WM_MOUSEHOVER y WM_MOUSELEAVE es necesario:
  • Agregar ON_WM_MOUSEMOVE() al mapa de mensajes
  • Llamar a la función TrackMouseEvent() en la funcion OnMouseMove(). 
  • Agregar ON_MESSAGE(WM_MOUSEHOVER,OnMouseHover) y ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave) al mapa de mensajes.
  • Implementar las funciones OnMouseLeave() y OnMouseHover().
  • nada más, por ahora...
Bien la parte "complicada" ya está, ahora ¿cómo joraca hago que muestre una imagen cuando el mouse esta sobre el botón y que muestre otra imagen cuando sale?, bien esta es la forma que se me ocurrió a mi, quizás existan formas mas "elegantes" de hacerlo

#define MIBOTON
#ifdef MIBOTON

class CMiBoton : public CButton{
private:
HBITMAP m_MouseSobre, m_MouseFuera;
TRACKMOUSEEVENT m_tme;
public:
void Crear(HBITMAP Sobre,HBITMAP Fuera ,CRect &r, CWnd *VentanaPadre, UINT nID){
this->Create(NULL, WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_BITMAP, r,VentanaPadre, nID);
m_tme.cbSize = sizeof(m_tme);
m_tme.hwndTrack = m_hWnd;
m_tme.dwFlags = TME_LEAVE|TME_HOVER;
m_tme.dwHoverTime = 1;
m_MouseSobre = Sobre;
m_MouseFuera = Fuera;
this->SetBitmap(m_MouseFuera);
}
protected:
void OnMouseMove(UINT nFlag, CPoint Point){
TrackMouseEvent(&m_tme);
}
LRESULT OnMouseHover(WPARAM wparam, LPARAM lparam){
this->SetBitmap(m_MouseSobre);
return 0;
}
LRESULT OnMouseLeave(WPARAM wparam, LPARAM lparam){
this->SetBitmap(m_MouseFuera);
return 0;
}
DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(CMiBoton, CButton)
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSEHOVER,OnMouseHover)
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
END_MESSAGE_MAP()
#endif

No hay comentarios:

Publicar un comentario