//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "ColorButton.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TColorButton *)
{
new TColorButton(NULL);
}
//---------------------------------------------------------------------------
__fastcall TColorButton::TColorButton(TComponent* Owner)
: TButton(Owner), ColorLo_(clBtnShadow), ColorHi_(clBtnHighlight),
Canvas_(new TCanvas()),draw_as_default_(false)
{
} // end the declaration
//---------------------------------------------------------------------------
namespace Colorbutton
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TColorButton)};
RegisterComponents("Standard", classes, 0);
}
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::CreateParams(TCreateParams& Params)
{
TButton::CreateParams(Params);
Params.Style |= BS_OWNERDRAW;
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::SetButtonStyle(bool ADefault)
{
if (draw_as_default_ != ADefault)
{
draw_as_default_ = ADefault;
InvalidateRect(Handle, NULL, FALSE);
}
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::CNDrawItem(TMessage& Msg)
{
// grab pointer to the DRAWITEMSTRUCT
const DRAWITEMSTRUCT* pDrawItem =
reinterpret_cast<DRAWITEMSTRUCT*>
(Msg.LParam);
// store the current state of
// the target DC
SaveDC(pDrawItem->hDC);
// bind Canvas_ to the target DC
Canvas_->Handle = pDrawItem->hDC;
try
{
// extract the state flags...
TOwnerDrawState state;
// if the button has keyboard focus
if (pDrawItem->itemState & ODS_FOCUS)
{
state = state << odFocused;
}
// if the button is pushed
if (pDrawItem->itemState &
ODS_SELECTED)
{
state = state << odSelected;
}
// if the button is disabled
if (pDrawItem->itemState &
ODS_DISABLED)
{
state = state << odDisabled;
}
// draw the button's face
DoDrawButtonFace(state);
// draw the button's text
DoDrawButtonText(state);
}
catch (...)
{
// clean up
Canvas_->Handle = NULL;
RestoreDC(pDrawItem->hDC, -1);
}
// clean up
Canvas_->Handle = NULL;
RestoreDC(pDrawItem->hDC, -1);
// reply TRUE
Msg.Result = TRUE;
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::DoDrawButtonFace(const TOwnerDrawState& state)
{
// draw a colored button...
Canvas_->Brush = Brush;
TRect RClient = ClientRect;
// if the button is the default button
// or has keyboard focus...
if (draw_as_default_ ||
state.Contains(odFocused))
{
Canvas_->Pen->Color = clWindowFrame;
Canvas_->Rectangle(
RClient.Left, RClient.Top,
RClient.Right, RClient.Bottom
);
InflateRect(
reinterpret_cast<PRECT>(&RClient),
-1, -1
);
}
// if the button is pushed...
if (state.Contains(odSelected))
{
Canvas_->Pen->Color = ColorLo_;
Canvas_->Rectangle(
RClient.Left, RClient.Top,
RClient.Right, RClient.Bottom
);
}
// if the button isn't pushed...
else
{
Canvas_->FillRect(RClient);
Frame3D(
Canvas_.get(), RClient,
ColorHi_, clWindowFrame, 1
);
POINT P[] = {
{1, RClient.Bottom - 1},
{RClient.Right - 1,
RClient.Bottom - 1},
{RClient.Right - 1,
RClient.Top - 1}
};
Canvas_->Pen->Color = ColorLo_;
Canvas_->Polyline(
reinterpret_cast<TPoint*>(P), 2
);
}
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::DoDrawButtonText(const TOwnerDrawState& state)
{
if (Caption.Length() == 0) return;
RECT RText = {0, 0, Width, Height};
Canvas_->Font = Font;
Canvas_->Brush = Brush;
SetBkMode(
Canvas_->Handle, TRANSPARENT
);
// if the button is pushed...
if (state.Contains(odSelected))
{
// offset the caption
OffsetRect(&RText, 1, 1);
}
// if the button is disabled...
if (!Enabled ||
state.Contains(odDisabled))
{
// render the caption
// in a disabled fashion
OffsetRect(&RText, 1, 1);
Canvas_->Font->Color = ColorHi_;
DrawText(
Canvas_->Handle, Caption.c_str(),
-1, &RText, DT_CENTER |
DT_VCENTER | DT_SINGLELINE
);
OffsetRect(&RText, -1, -1);
Canvas_->Font->Color = ColorLo_;
}
// render the caption
DrawText(
Canvas_->Handle, Caption.c_str(), -1,
&RText, DT_CENTER | DT_VCENTER |
DT_SINGLELINE
);
// if the button has keyboard focus...
if (state.Contains(odFocused))
{
// render the selection rectangle
TRect RFocus = ClientRect;
InflateRect(
reinterpret_cast<PRECT>(&RFocus),
-4, -4
);
Canvas_->DrawFocusRect(RFocus);
}
}
//---------------------------------------------------------------------------
TColor __fastcall TColorButton::GetColor()
{
return Brush->Color;
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::SetColor(TColor Value)
{
if (Brush->Color != Value)
{
Brush->Color = Value;
InvalidateRect(Handle, NULL, TRUE);
}
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::SetColorLo(TColor Value)
{
if (ColorLo_ != Value)
{
ColorLo_ = Value;
InvalidateRect(Handle, NULL, TRUE);
}
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::SetColorHi(TColor Value)
{
if (ColorHi_ != Value)
{
ColorHi_ = Value;
InvalidateRect(Handle, NULL, TRUE);
}
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::CMFontChanged(TMessage& Msg)
{
TButton::Dispatch(&Msg);
InvalidateRect(Handle, NULL, TRUE);
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::CMEnabledChanged(TMessage& Msg)
{
TButton::Dispatch(&Msg);
InvalidateRect(Handle, NULL, TRUE);
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::WMLButtonDblClk(TMessage& Msg)
{
SNDMSG(
Handle, WM_LBUTTONDOWN,
Msg.WParam, Msg.LParam
);
}