/////////////////////////////////////////////////////////////////////////////
// AdvancedButton.cpp : implementation file for the CAdvancedButton class
//
// Written by Loic Brayat (dev@pileouface.org)
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "AdvancedButton.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// Classes used by the CAdvancedButton to draw itself
/////////////////////////////////////////////////////////////////////////////
class DrawnObject {
public:
virtual void Draw(CDC *DC, CRect R, UINT state, COLORREF color) = 0;
virtual void DrawText(CDC *DC,
CRect R,
const char *Buf,
COLORREF TextColor);
protected:
virtual void DrawFrame(CDC *DC, CRect R, int Inset) = 0;
virtual void DrawFilled(CDC *DC, CRect EndPoints, COLORREF color) = 0;
virtual void DrawFocus(CDC *DC, CRect EndPoints, COLORREF bkcolor) = 0;
};
/////////////////////////////////////////////////////////////////////////////
class DrawnRect : public DrawnObject {
public:
virtual void Draw(CDC *DC, CRect R, UINT state, COLORREF color);
protected:
virtual void DrawFilled(CDC *DC, CRect EndPoints, COLORREF color);
virtual void DrawFocus(CDC *DC, CRect EndPoints, COLORREF bkcolor);
virtual void DrawFrame(CDC *DC, CRect R, int Inset);
};
/////////////////////////////////////////////////////////////////////////////
class DrawnEllipse : public DrawnObject {
public:
virtual void Draw(CDC *DC, CRect R, UINT state, COLORREF color);
protected:
virtual void DrawFilled(CDC *DC, CRect EndPoints, COLORREF color);
virtual void DrawFocus(CDC *DC, CRect EndPoints, COLORREF bkcolor);
virtual void DrawFrame(CDC *DC, CRect R, int Inset);
};
/////////////////////////////////////////////////////////////////////////////
// CAdvancedButton's implementation
/////////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CAdvancedButton, CButton)
CAdvancedButton::CAdvancedButton()
{
// initialize hwndOwner for GetOwner() and SetOwner() support in MFC < 2.5
#if (_MFC_VER < 0x0250)
hwndOwner = NULL;
#endif
drawType = DRAW_RECT;
}
CAdvancedButton::~CAdvancedButton()
{
}
BEGIN_MESSAGE_MAP(CAdvancedButton, CButton)
ON_WM_LBUTTONUP()
END_MESSAGE_MAP()
void CAdvancedButton::PreSubclassWindow()
{
ModifyStyle(0,BS_OWNERDRAW);
}
bool CAdvancedButton::SubclassDlgItem(const UINT nID,
CWnd* pParent,
const COLORREF BGColor,
const COLORREF FGColor,
const COLORREF DisabledColor)
{
if (!CButton::SubclassDlgItem(nID, pParent))
return false;
m_BGColor = BGColor;
m_FGColor = FGColor;
m_disabled = DisabledColor;
drawType = DRAW_RECT;
return true;
}
bool CAdvancedButton::SetColors(const COLORREF BGColor,
const COLORREF FGColor,
const COLORREF DisabledColor)
{
m_BGColor = BGColor;
m_FGColor = FGColor;
m_disabled = DisabledColor;
this->RedrawWindow();
return true;
}
void CAdvancedButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
UINT state = lpDIS->itemState;
CRect btnRect;
btnRect.CopyRect(&lpDIS->rcItem);
DrawnObject * pDrawnObj;
switch(drawType) {
case DRAW_ELLIPSE : pDrawnObj = new DrawnEllipse();
break;
default /* RECT */: pDrawnObj = new DrawnRect();
break;
}
const int bufSize = 512;
TCHAR buffer[bufSize];
GetWindowText(buffer, bufSize);
pDrawnObj->Draw(pDC, btnRect, state, GetBackGroundColor());
if (state & ODS_DISABLED)
pDrawnObj->DrawText(pDC, btnRect, buffer, GetDisabledColor());
else
pDrawnObj->DrawText(pDC, btnRect, buffer, GetForeGroundColor());
delete pDrawnObj;
}
/////////////////////////////////////////////////////////////////////////////
// DrawnObjects's implementation
/////////////////////////////////////////////////////////////////////////////
void DrawnObject::DrawText(CDC *DC,
CRect R,
const char *Buf,
COLORREF TextColor)
{
COLORREF prevColor = DC->SetTextColor(TextColor);
DC->SetBkMode(TRANSPARENT);
DC->DrawText(Buf, strlen(Buf), R, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
DC->SetTextColor(prevColor);
}
/////////////////////////////////////////////////////////////////////////////
void DrawnRect::DrawFrame(CDC *DC, CRect R, int Inset)
{
COLORREF dark, light, tlColor, brColor;
int i, m, width;
width = (Inset < 0)? -Inset : Inset;
for (i = 0; i < width; i += 1) {
if ( width == 1 ) {
light = WHITE;
dark = DKGRAY;
}
else {
m = 255 / (i + 2);
dark = PALETTERGB(m, m, m);
m = 192 + (63 / (i + 1));
light = PALETTERGB(m, m, m);
}
if ( Inset < 0 ) {
tlColor = dark;
brColor = light;
}
else {
tlColor = light;
brColor = dark;
}
DC->Draw3dRect(R, tlColor, brColor);
R.DeflateRect(1, 1);
}
}
void DrawnRect::DrawFilled(CDC *DC, CRect R, COLORREF color)
{
CBrush B;
B.CreateSolidBrush(color);
DC->FillRect(R, &B);
B.DeleteObject();
}
void DrawnRect::DrawFocus(CDC *DC, CRect EndPoints, COLORREF bkcolor)
{
DrawFocusRect(DC->GetSafeHdc(), EndPoints);
}
void DrawnRect::Draw(CDC *DC, CRect R, UINT state, COLORREF color)
{
DrawFilled(DC, R, color);
DrawFrame(DC, R, 2);
if (state & ODS_FOCUS) {
if (state & ODS_SELECTED)
DrawFrame(DC, R, -1);
R.DeflateRect(2, 2);
DrawFocus(DC, (LPRECT)&R, color);
}
}
/////////////////////////////////////////////////////////////////////////////
void DrawnEllipse::DrawFilled(CDC *DC, CRect EndPoints, COLORREF color)
{
CPen newPen;
newPen.CreatePen(PS_SOLID, 3, color);
CPen *oldPen = DC->SelectObject(&newPen);
CRect aera = EndPoints;
while (!aera.IsRectEmpty()) {
aera.DeflateRect(1, 1);
DC->Ellipse(aera);
}
DC->SelectObject(oldPen);
newPen.DeleteObject();
}
void DrawnEllipse::DrawFrame(CDC *DC, CRect EndPoints, int Inset)
{
COLORREF color = (Inset<0)?BLACK:DKGRAY;
CPen newPen;
newPen.CreatePen(PS_SOLID, 2, color);
CPen *oldPen = DC->SelectObject(&newPen);
DC->Ellipse(EndPoints);
DC->SelectObject(oldPen);
newPen.DeleteObject();
}
void DrawnEllipse::DrawFocus(CDC *DC, CRect EndPoints, COLORREF bkcolor)
{
CPen newPen;
newPen.CreatePen(PS_DOT, 1, BLACK);
CPen *oldPen = DC->SelectObject(&newPen);
DC->SetBkMode(OPAQUE);
DC->SetBkColor(bkcolor);
DC->Ellipse(EndPoints);
DC->SelectObject(oldPen);
newPen.DeleteObject();
}
void DrawnEllipse::Draw(CDC *DC, CRect R, UINT state, COLORREF color)
{
CRect rect;
rect.CopyRect(R);
rect.DeflateRect(1, 1);
DrawFrame(DC, rect, 2);
rect.DeflateRect(1, 1);
DrawFilled(DC, rect, color);
if (state & ODS_FOCUS) {
if (state & ODS_SELECTED) {
rect.InflateRect(1, 1);
DrawFrame(DC, rect, -1);
rect.DeflateRect(1, 1);
DrawFrame(DC, rect, -1);
}
DrawFilled(DC, rect, color);
rect.DeflateRect(2, 2);
DrawFocus(DC, rect, color);
rect.DeflateRect(1, 1);
DrawFilled(DC, rect, color);
}
}