El siguiente codigo han de agradecerselo a Cesar C. Salazar Gonzalez (Al Cesar lo que es del Cesar)
Esta es una forma de hacer un boton redondo....
saludos...
ARCHIVO BOTON.CPP
Código:
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "RoundButton.h"
//---------------------------------------------------------------------------
static inline TRoundButton *ValidCtrCheck()
{
return new TRoundButton(NULL);
}
//---------------------------------------------------------------------------
__fastcall TRoundButton::TRoundButton(TComponent* Owner)
: TButton(Owner)
{
FCanvas = new TCanvas; // creamos el objeto Canvas
}
__fastcall TRoundButton::~TRoundButton()
{
delete FCanvas; // Liberamos el Canvas
}
// Antes de crear el control se fijan una serie de parámetros,
// entre los cuales está el estilo del botón
void __fastcall TRoundButton::CreateParams(TCreateParams &Params)
{
TButton::CreateParams(Params); // La clase ascendiente se ocupará de establecer los parámetros generales
Params.Style = Params.Style | BS_OWNERDRAW; // Nosotros indicamos que el control va a ser no estándar
}
// Cada vez que Windows necesita dibujar un botón con el estilo
// BS_OWNERDRAW envía este mensaje, solicitando las dimensiones
void __fastcall TRoundButton::CNMeasureItem(TWMMeasureItem& Mensaje)
{
// Facilitamos la anchura y altura del control
Mensaje.MeasureItemStruct->itemWidth = Width;
Mensaje.MeasureItemStruct->itemHeight = Height;
}
// Cada vez que haya que dibujar el control se llamará a este método
void __fastcall TRoundButton::CNDrawItem(TWMDrawItem& Mensaje)
{
RECT Area;
char Texto[256];
strncpy(Texto, Caption.c_str(), 255); // Copiamos el título del botón
Area = ClientRect; // y obtenemos el área que tenemos de trabajo
// En el parámetro Mensaje existe una estructura DrawItemStruct, en
// cuyo interior encontraremos el campo ItemState, que nos permitirá
// conocer el estado del botón
if (Mensaje.DrawItemStruct->itemState & ODS_SELECTED) // El botón está pulsado
FCanvas->Pen->Color = clBtnHighlight; // Tomar el color destacado primero
else FCanvas->Pen->Color = clWindowFrame; // en caso contrario tomar el color normal de borde
// El Handle de FCanvas será el Hdc enviado en Mensaje.DrawItemStruct,
// lo que nos permitirá dibujar en la superficie del botón
FCanvas->Handle = Mensaje.DrawItemStruct->hDC;
FCanvas->Pen->Width = 1; // Anchura del lapiz
FCanvas->Pen->Style = psSolid; // estilo continuo
FCanvas->Brush->Style = bsSolid; // Relleno sólido
FCanvas->Brush->Color = clBtnFace; // con el color de los botones
// Dibujamos un contorno
FCanvas->RoundRect(Area.left, Area.top, Area.right, Area.bottom,
(Area.right-Area.left) * 2, (Area.bottom-Area.top) * 2);
// Intercambiar el color del lápiz
FCanvas->Pen->Color = FCanvas->Pen->Color == clWindowFrame ?
clBtnHighlight : clWindowFrame;
// Y dibujar la sombra interior
FCanvas->RoundRect(Area.left, Area.top, Area.right-1, Area.bottom-1,
(Area.right-Area.left) * 2 -2, (Area.bottom-Area.top) * 2 -2);
if (Mensaje.DrawItemStruct->itemState & ODS_FOCUS) { // Si el botón es el control actual
InflateRect(&Area, -4, -4); // En el interior del área
FCanvas->Pen->Color = // Y según que esté pulsado o no
Mensaje.DrawItemStruct->itemState & ODS_SELECTED ?
clBtnShadow : clWindowFrame;
FCanvas->Pen->Style = psDot; // Dibujaremos una línea punteada
FCanvas->Brush->Style = bsClear; // sin rellenar
// también con forma de elipse
FCanvas->RoundRect(Area.left, Area.top, Area.right, Area.bottom,
(Area.right-Area.left)*2, (Area.bottom-Area.top)*2);
InflateRect(&Area, 4, 4); // Devolvemos a área su valor original
}
// Si el botón está pulsado
if (Mensaje.DrawItemStruct->itemState & ODS_SELECTED)
OffsetRect(&Area, 1, 1); // Desplazar un punto el área
InflateRect(&Area, -5, -5); // Reducirla
FCanvas->Font = Font; // tomar el tipo de letra seleccionado en el botón
// Si el botón está desactivado y no éstá en modo de diseño
if (! Enabled && ! ComponentState.Contains(csDesigning))
FCanvas->Font->Color = clBtnShadow; // utilizar el color difuminado
// y escribir el título
DrawText(FCanvas->Handle, Texto, strlen(Texto),
&Area, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
FCanvas->Handle = 0; // Cuando hayamos terminado Handle debe ser cero
}
// Al cambiar el estado del botón
void __fastcall TRoundButton::SetButtonStyle(bool ADefault)
{
Refresh(); // simplemente redibujar
}
//---------------------------------------------------------------------------
namespace Roundbutton
{
void __fastcall Register()
{
TComponentClass classes[1] = {__classid(TRoundButton)};
RegisterComponents("Programacion C++ Builder", classes, 0);
}
}
//---------------------------------------------------------------------------
ARCHIVO BOTON.H
Código:
//---------------------------------------------------------------------------
#ifndef RoundButtonH
#define RoundButtonH
//---------------------------------------------------------------------------
#include <vcl\SysUtils.hpp>
#include <vcl\Controls.hpp>
#include <vcl\Classes.hpp>
#include <vcl\Forms.hpp>
#include <vcl\StdCtrls.hpp>
//---------------------------------------------------------------------------
class TRoundButton : public TButton
{
private:
TCanvas * FCanvas; // Para dibujar
// Mensaje de Windows solicitando el tamaño del control
void __fastcall CNMeasureItem(TWMMeasureItem& Mensaje);
// Mensaje de Windows solicitando que el control sea dibujado
void __fastcall CNDrawItem(TWMDrawItem& Mensaje);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(CN_MEASUREITEM, TWMMeasureItem, CNMeasureItem);
MESSAGE_HANDLER(CN_DRAWITEM, TWMDrawItem, CNDrawItem);
END_MESSAGE_MAP(TButton);
protected:
// Parámetros para la creación del control
void __fastcall CreateParams(TCreateParams &Params);
// Cambio del estado del botón
void __fastcall SetButtonStyle(bool ADefault);
public:
__fastcall TRoundButton(TComponent* Owner);
// Redefinimos también el el destructor
__fastcall ~TRoundButton();
__published:
};
//---------------------------------------------------------------------------
#endif