You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
799 lines
18 KiB
C++
799 lines
18 KiB
C++
// XTPSkinObjectButton.cpp: implementation of the CXTPSkinObjectButton class.
|
|
//
|
|
// This file is a part of the XTREME SKINFRAMEWORK MFC class library.
|
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
#include "stdafx.h"
|
|
|
|
#include "Common/Uxtheme.h"
|
|
#include "Common/Tmschema.h"
|
|
#include "Common/XTPColorManager.h"
|
|
#include "Common/XTPDrawHelpers.h"
|
|
|
|
#include "XTPSkinObject.h"
|
|
#include "XTPSkinObjectFrame.h"
|
|
#include "XTPSkinObjectButton.h"
|
|
#include "XTPSkinDrawTools.h"
|
|
#include "XTPSkinManager.h"
|
|
|
|
#define DT_HIDEPREFIX 0x00100000
|
|
|
|
#define CBR_CLIENTRECT 0
|
|
#define CBR_CHECKBOX 1
|
|
#define CBR_RADIOBOX 2
|
|
#define CBR_CHECKTEXT 3
|
|
#define CBR_RADIOTEXT 4
|
|
#define CBR_GROUPTEXT 5
|
|
#define CBR_GROUPFRAME 6
|
|
#define CBR_PUSHBUTTON 7
|
|
|
|
#ifndef BS_SPLITBUTTON
|
|
#define BS_SPLITBUTTON 0x0000000CL
|
|
#define BS_DEFSPLITBUTTON 0x0000000DL
|
|
#endif
|
|
|
|
|
|
#define BS_HORZMASK (BS_LEFT | BS_RIGHT | BS_CENTER)
|
|
#define BS_VERTMASK (BS_TOP | BS_BOTTOM | BS_VCENTER)
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
IMPLEMENT_DYNCREATE(CXTPSkinObjectButton, CXTPSkinObjectFrame)
|
|
|
|
CXTPSkinObjectButton::CXTPSkinObjectButton()
|
|
{
|
|
m_bHot = FALSE;
|
|
m_bPushed = FALSE;
|
|
|
|
m_bStyle = (BYTE)0xFF;
|
|
|
|
m_strClassName = _T("BUTTON");
|
|
m_nCtlColorMessage = WM_CTLCOLORBTN;
|
|
}
|
|
|
|
CXTPSkinObjectButton::~CXTPSkinObjectButton()
|
|
{
|
|
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CXTPSkinObjectButton, CXTPSkinObjectFrame)
|
|
//{{AFX_MSG_MAP(CXTPSkinObjectButton)
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_CREATE()
|
|
ON_WM_SETFOCUS()
|
|
ON_WM_KILLFOCUS()
|
|
ON_WM_PAINT()
|
|
ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
|
|
//}}AFX_MSG_MAP
|
|
ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
|
|
ON_MESSAGE_VOID(BM_SETSTYLE, OnDefaultAndInvalidate)
|
|
ON_MESSAGE_VOID(BM_SETCHECK, OnDefaultAndInvalidate)
|
|
ON_MESSAGE_VOID(WM_CAPTURECHANGED, OnDefaultAndInvalidate)
|
|
ON_MESSAGE_VOID(WM_ENABLE, OnInvalidate)
|
|
ON_MESSAGE(WM_UPDATEUISTATE, OnUpdateUIState)
|
|
ON_MESSAGE(BM_SETSTATE, OnSetState)
|
|
ON_MESSAGE(WM_SETTEXT, OnSetText)
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPSkinObjectButton message handlers
|
|
|
|
int CXTPSkinObjectButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (CXTPSkinObjectFrame::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
Invalidate(FALSE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CXTPSkinObjectButton::OnSkinChanged(BOOL bPrevState, BOOL bNewState)
|
|
{
|
|
CXTPSkinObjectFrame::OnSkinChanged(bPrevState, bNewState);
|
|
|
|
m_bHot = FALSE;
|
|
m_bPushed = FALSE;
|
|
|
|
if (!bPrevState)
|
|
{
|
|
m_bPushed = FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
BOOL CXTPSkinObjectButton::OnEraseBkgnd(CDC* /*pDC*/)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPSkinObjectButton::OnMouseLeave()
|
|
{
|
|
OnMouseMove(0, CPoint(-1, -1));
|
|
}
|
|
|
|
void CXTPSkinObjectButton::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
if (GetButtonStyle() == BS_GROUPBOX)
|
|
return;
|
|
|
|
CXTPSkinObjectFrame::OnMouseMove(nFlags, point);
|
|
|
|
CRect rc;
|
|
GetClientRect(&rc);
|
|
|
|
BOOL bHot = rc.PtInRect(point);
|
|
if (bHot != m_bHot)
|
|
{
|
|
m_bHot = bHot;
|
|
Invalidate(FALSE);
|
|
|
|
if (m_bHot)
|
|
{
|
|
TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd, HOVER_DEFAULT};
|
|
_TrackMouseEvent(&tme);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSkinObjectButton::IsDefWindowProcAvail(int nMessage) const
|
|
{
|
|
if (m_bWindowsForms && (nMessage < WM_CTLCOLORMSGBOX || nMessage > WM_CTLCOLORSTATIC))
|
|
return FALSE;
|
|
|
|
if (nMessage == WM_TIMER)
|
|
return FALSE;
|
|
|
|
if (m_bActiveX)
|
|
return TRUE;
|
|
|
|
return CXTPSkinObjectFrame::IsDefWindowProcAvail(nMessage);
|
|
}
|
|
|
|
LRESULT CXTPSkinObjectButton::OnSetState(WPARAM wParam, LPARAM /*lParam*/)
|
|
{
|
|
BOOL bVisible = GetStyle() & WS_VISIBLE;
|
|
if (bVisible) ModifyStyle(WS_VISIBLE, 0);
|
|
Default();
|
|
if (bVisible) ModifyStyle(0, WS_VISIBLE);
|
|
|
|
m_bPushed = (wParam != 0);
|
|
|
|
Invalidate(FALSE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CXTPSkinObjectButton::OnSetFocus(CWnd* pOldWnd)
|
|
{
|
|
CXTPSkinObjectFrame::OnSetFocus(pOldWnd);
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
void CXTPSkinObjectButton::OnKillFocus(CWnd* pNewWnd)
|
|
{
|
|
CXTPSkinObjectFrame::OnKillFocus(pNewWnd);
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
void CXTPSkinObjectButton::OnDefaultAndInvalidate()
|
|
{
|
|
Default();
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
void CXTPSkinObjectButton::OnInvalidate()
|
|
{
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
|
|
LRESULT CXTPSkinObjectButton::OnPrintClient(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if ((lParam & PRF_CLIENT) == 0)
|
|
return Default();
|
|
|
|
CDC* pDC = CDC::FromHandle((HDC)wParam);
|
|
if (pDC) OnDraw(pDC);
|
|
return 1;
|
|
}
|
|
|
|
void CXTPSkinObjectButton::OnPaint()
|
|
{
|
|
CXTPSkinObjectPaintDC dc(this); // device context for painting
|
|
OnDraw(&dc);
|
|
}
|
|
|
|
void CXTPSkinObjectButton::OnDraw(CDC* pDC)
|
|
{
|
|
CRect rc;
|
|
GetClientRect(&rc);
|
|
|
|
if ((GetButtonStyle() == BS_GROUPBOX) && !m_bActiveX && !m_bWindowsForms)
|
|
{
|
|
CFont* pOldFont = pDC->SelectObject(GetFont());
|
|
pDC->SetBkColor(GetColor(COLOR_3DFACE));
|
|
|
|
OnDraw(pDC, rc);
|
|
|
|
pDC->SelectObject(pOldFont);
|
|
}
|
|
else
|
|
{
|
|
CXTPBufferDC memDC(*pDC, rc);
|
|
|
|
if (FillBackground(&memDC, rc, WM_CTLCOLORBTN) == GetStockObject(HOLLOW_BRUSH))
|
|
{
|
|
memDC.Discard();
|
|
|
|
CFont* pOldFont = pDC->SelectObject(GetFont());
|
|
pDC->SetBkColor(GetColor(COLOR_3DFACE));
|
|
|
|
OnDraw(pDC, rc);
|
|
|
|
pDC->SelectObject(pOldFont);
|
|
}
|
|
else
|
|
{
|
|
CFont* pOldFont = memDC.SelectObject(GetFont());
|
|
memDC.SetBkMode(TRANSPARENT);
|
|
|
|
OnDraw(&memDC, rc);
|
|
|
|
memDC.SelectObject(pOldFont);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CXTPSkinObjectButton::IsPushButton()
|
|
{
|
|
DWORD dwStyle = GetStyle();
|
|
|
|
switch (GetButtonStyle())
|
|
{
|
|
case LOBYTE(BS_PUSHBUTTON):
|
|
case LOBYTE(BS_DEFPUSHBUTTON):
|
|
case LOBYTE(BS_OWNERDRAW):
|
|
case LOBYTE(BS_SPLITBUTTON):
|
|
case LOBYTE(BS_DEFSPLITBUTTON):
|
|
return TRUE;
|
|
|
|
default:
|
|
if ((dwStyle & BS_PUSHLIKE) == BS_PUSHLIKE)
|
|
return TRUE;
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
DWORD CXTPSkinObjectButton::GetAlignment()
|
|
{
|
|
DWORD bHorz;
|
|
DWORD bVert;
|
|
|
|
DWORD dwStyle = GetStyle();
|
|
|
|
bHorz = dwStyle & (BS_LEFT | BS_RIGHT | BS_CENTER);
|
|
bVert = dwStyle & (BS_TOP | BS_BOTTOM | BS_VCENTER);
|
|
|
|
if (!bHorz || !bVert)
|
|
{
|
|
if (IsPushButton())
|
|
{
|
|
if (!bHorz)
|
|
bHorz = BS_CENTER;
|
|
}
|
|
else
|
|
{
|
|
if (!bHorz)
|
|
bHorz = BS_LEFT;
|
|
}
|
|
|
|
if (!bVert)
|
|
bVert = BS_VCENTER;
|
|
}
|
|
|
|
if (m_bActiveX)
|
|
bVert = BS_VCENTER;
|
|
|
|
return bHorz | bVert;
|
|
}
|
|
|
|
|
|
CSize CXTPSkinObjectButton::GetGlyphSize(BOOL bCheckBox)
|
|
{
|
|
CXTPSkinManagerClass* pClassButton = GetSkinClass();
|
|
CRect rcButton(0, 0, 13, 13);
|
|
CSize sz(13, 13);
|
|
|
|
pClassButton->GetThemePartSize(bCheckBox ? BP_CHECKBOX : BP_RADIOBUTTON,
|
|
1, rcButton, TS_DRAW, &sz);
|
|
|
|
return sz;
|
|
}
|
|
|
|
void CXTPSkinObjectButton::CalcRect(CDC* pDC, LPRECT lprc, int code)
|
|
{
|
|
CString strText;
|
|
GetWindowText(strText);
|
|
int dy;
|
|
UINT align;
|
|
CSize extent;
|
|
|
|
GetClientRect(lprc);
|
|
|
|
align = GetAlignment();
|
|
|
|
switch (code)
|
|
{
|
|
case CBR_PUSHBUTTON:
|
|
// Subtract out raised edge all around
|
|
InflateRect(lprc, -GetMetrics()->m_cxEdge, -GetMetrics()->m_cyEdge);
|
|
break;
|
|
|
|
case CBR_CHECKBOX:
|
|
case CBR_RADIOBOX:
|
|
{
|
|
CSize szGlyph = GetGlyphSize(code == CBR_CHECKBOX);
|
|
|
|
switch (align & BS_VERTMASK)
|
|
{
|
|
case BS_VCENTER:
|
|
lprc->top = (lprc->top + lprc->bottom - szGlyph.cy) / 2;
|
|
break;
|
|
|
|
case BS_TOP:
|
|
case BS_BOTTOM:
|
|
{
|
|
extent = pDC->GetTextExtent(_T(" "), 1);
|
|
dy = extent.cy + extent.cy/4;
|
|
|
|
// Save vertical extent
|
|
extent.cx = dy;
|
|
|
|
// Get centered amount
|
|
|
|
dy = (dy - szGlyph.cy) / 2;
|
|
if ((align & BS_VERTMASK) == BS_TOP)
|
|
lprc->top += dy;
|
|
else
|
|
lprc->top = lprc->bottom - extent.cx + dy;
|
|
break;
|
|
}
|
|
}
|
|
lprc->bottom = lprc->top + szGlyph.cy;
|
|
|
|
if (GetStyle() & BS_RIGHTBUTTON)
|
|
lprc->left = lprc->right - szGlyph.cx;
|
|
else
|
|
lprc->right = lprc->left + szGlyph.cx;
|
|
}
|
|
break;
|
|
|
|
case CBR_CHECKTEXT:
|
|
case CBR_RADIOTEXT:
|
|
{
|
|
int nOffset = GetGlyphSize(code == CBR_CHECKBOX).cx + 3;
|
|
if (GetStyle() & BS_RIGHTBUTTON)
|
|
{
|
|
lprc->right -= nOffset;
|
|
}
|
|
else
|
|
{
|
|
lprc->left += nOffset;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CBR_GROUPTEXT:
|
|
if (strText.IsEmpty())
|
|
{
|
|
lprc->left = lprc->right = 0;
|
|
lprc->bottom = lprc->top + pDC->GetTextExtent(_T("x"), 1).cy;
|
|
break;
|
|
}
|
|
|
|
extent = pDC->GetTextExtent(strText);
|
|
extent.cx += GetMetrics()->m_cxEdge * 2;
|
|
|
|
switch (align & BS_HORZMASK)
|
|
{
|
|
case BS_RIGHT:
|
|
lprc->right -= 6 + GetMetrics()->m_cxBorder;
|
|
lprc->left += lprc->right - (int)(extent.cx);
|
|
break;
|
|
|
|
case BS_CENTER:
|
|
lprc->left += GetMetrics()->m_cxBorder + (lprc->left + lprc->right - extent.cx) / 2;
|
|
lprc->right = lprc->left + (int)(extent.cx);
|
|
break;
|
|
|
|
default:
|
|
lprc->left += 8 + GetMetrics()->m_cxBorder;
|
|
lprc->right = lprc->left + (int)(extent.cx);
|
|
}
|
|
|
|
lprc->bottom = lprc->top + extent.cy;
|
|
break;
|
|
|
|
case CBR_GROUPFRAME:
|
|
extent = pDC->GetTextExtent(_T(" "), 1);
|
|
lprc->top += extent.cy / 2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CXTPSkinObjectButton::DrawButtonText(CDC* pDC, int nPart, int nState)
|
|
{
|
|
static const BYTE buttonsStyles[] =
|
|
{
|
|
CBR_PUSHBUTTON,
|
|
CBR_PUSHBUTTON,
|
|
CBR_CHECKTEXT,
|
|
CBR_CHECKTEXT,
|
|
CBR_RADIOTEXT,
|
|
CBR_CHECKTEXT,
|
|
CBR_CHECKTEXT,
|
|
CBR_GROUPTEXT,
|
|
CBR_CLIENTRECT,
|
|
CBR_RADIOTEXT,
|
|
CBR_CLIENTRECT,
|
|
CBR_PUSHBUTTON,
|
|
};
|
|
|
|
CXTPSkinManagerClass* pClass = GetSkinClass();
|
|
|
|
RECT rc;
|
|
int x, y, cx = 0, cy = 0;
|
|
|
|
CString strText;
|
|
UINT dsFlags = DT_SINGLELINE | DT_LEFT | DT_TOP | DT_NOCLIP;
|
|
BYTE bStyle = GetButtonStyle();
|
|
|
|
BOOL pbfPush = IsPushButton();
|
|
if (pbfPush)
|
|
{
|
|
CalcRect(pDC, &rc, CBR_PUSHBUTTON);
|
|
}
|
|
else
|
|
{
|
|
CalcRect(pDC, &rc, buttonsStyles[bStyle]);
|
|
}
|
|
|
|
if (bStyle == BS_SPLITBUTTON || bStyle == BS_DEFSPLITBUTTON)
|
|
{
|
|
rc.right -= 12;
|
|
}
|
|
|
|
// Alignment
|
|
GetWindowText(strText);
|
|
UINT wAlignment = GetAlignment();
|
|
|
|
HGDIOBJ hImage = 0;
|
|
|
|
if (GetStyle() & BS_BITMAP)
|
|
{
|
|
hImage = (HGDIOBJ)SendMessage(BM_GETIMAGE, IMAGE_BITMAP);
|
|
if (!hImage)
|
|
return;
|
|
|
|
BITMAP bmp;
|
|
GetObject(hImage, sizeof(BITMAP), &bmp);
|
|
cx = bmp.bmWidth;
|
|
cy = bmp.bmHeight;
|
|
}
|
|
else if (GetStyle() & BS_ICON)
|
|
{
|
|
hImage = (HGDIOBJ)SendMessage(BM_GETIMAGE, IMAGE_ICON);
|
|
if (!hImage)
|
|
return;
|
|
|
|
XTPSkinFrameworkGetIconSize((HICON)hImage, &cx, &cy);
|
|
}
|
|
else
|
|
{
|
|
// Text button
|
|
if (strText.IsEmpty())
|
|
return;
|
|
|
|
if (GetStyle() & BS_MULTILINE)
|
|
{
|
|
dsFlags |= DT_WORDBREAK | DT_EDITCONTROL;
|
|
dsFlags &= ~DT_SINGLELINE;
|
|
}
|
|
|
|
|
|
CRect rcText(0, 0, rc.right - rc.left, 0);
|
|
pDC->DrawText(strText, rcText, dsFlags | DT_CALCRECT);
|
|
|
|
cx = rcText.Width();
|
|
cy = rcText.Height();
|
|
}
|
|
|
|
CRect rcText(rc);
|
|
if (pbfPush && ((GetStyle() & BS_MULTILINE) == 0)) rcText.DeflateRect(GetMetrics()->m_cxBorder, GetMetrics()->m_cyBorder);
|
|
|
|
// Horizontal
|
|
switch (wAlignment & BS_HORZMASK)
|
|
{
|
|
case BS_LEFT:
|
|
x = rc.left + (pbfPush ? GetMetrics()->m_cxBorder : 0);
|
|
break;
|
|
|
|
case BS_RIGHT:
|
|
x = rc.right - cx - (pbfPush ? GetMetrics()->m_cxBorder : 0);
|
|
dsFlags |= DT_RIGHT;
|
|
break;
|
|
|
|
default:
|
|
x = (rc.left + rc.right - cx) / 2;
|
|
dsFlags |= DT_CENTER;
|
|
break;
|
|
}
|
|
|
|
// Vertical
|
|
switch (wAlignment & BS_VERTMASK)
|
|
{
|
|
case BS_TOP:
|
|
y = rc.top + (pbfPush ? GetMetrics()->m_cyBorder : 0);
|
|
break;
|
|
|
|
case BS_BOTTOM:
|
|
y = rc.bottom - cy - (pbfPush ? GetMetrics()->m_cyBorder : 0);
|
|
dsFlags |= DT_BOTTOM;
|
|
break;
|
|
|
|
default:
|
|
y = (rc.top + rc.bottom - cy) / 2;
|
|
dsFlags |= DT_VCENTER;
|
|
break;
|
|
}
|
|
|
|
if (GetStyle() & BS_BITMAP)
|
|
{
|
|
pDC->DrawState(CPoint(x, y), CSize(cx, cy), (HBITMAP)hImage, DSS_NORMAL, 0);
|
|
}
|
|
else if (GetStyle() & BS_ICON)
|
|
{
|
|
pDC->DrawState(CPoint(x, y), CSize(cx, cy), (HICON)hImage, DSS_NORMAL, (HBRUSH)0);
|
|
}
|
|
else if (bStyle != LOBYTE(BS_USERBUTTON))
|
|
{
|
|
if (SendMessage(WM_QUERYUISTATE) & UISF_HIDEACCEL)
|
|
{
|
|
dsFlags |= DT_HIDEPREFIX;
|
|
}
|
|
|
|
if (GetExStyle() & WS_EX_RTLREADING)
|
|
dsFlags |= DT_RTLREADING;
|
|
|
|
pDC->SetTextColor(GetColor(COLOR_BTNTEXT));
|
|
|
|
if (GetStyle() & BS_MULTILINE)
|
|
{
|
|
pClass->DrawThemeText(pDC, nPart, nState, strText, dsFlags | DT_NOCLIP, CRect(x, y, x + cx, y + cy));
|
|
}
|
|
else
|
|
{
|
|
pClass->DrawThemeText(pDC, nPart, nState, strText, dsFlags, &rcText);
|
|
}
|
|
}
|
|
|
|
if (::GetFocus() == m_hWnd)
|
|
{
|
|
if ((SendMessage(WM_QUERYUISTATE) & UISF_HIDEFOCUS) == 0)
|
|
{
|
|
if (!pbfPush)
|
|
{
|
|
|
|
RECT rcClient;
|
|
GetClientRect(&rcClient);
|
|
|
|
if (bStyle == LOBYTE(BS_USERBUTTON))
|
|
CopyRect(&rc, &rcClient);
|
|
else
|
|
{
|
|
// Try to leave a border all around text. That causes
|
|
// focus to hug text.
|
|
rc.top = max(rcClient.top, y - GetMetrics()->m_cyBorder);
|
|
rc.bottom = min(rcClient.bottom, rc.top + GetMetrics()->m_cyEdge + cy);
|
|
|
|
rc.left = max(rcClient.left, x-GetMetrics()->m_cxBorder);
|
|
rc.right = min(rcClient.right, rc.left + GetMetrics()->m_cxEdge + cx);
|
|
}
|
|
}
|
|
else
|
|
InflateRect(&rc, -GetMetrics()->m_cxBorder, -GetMetrics()->m_cyBorder);
|
|
|
|
pDC->SetTextColor(0);
|
|
pDC->SetBkColor(0xFFFFFF);
|
|
// Are back & fore colors set properly?
|
|
::DrawFocusRect(pDC->GetSafeHdc(), &rc);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CXTPSkinObjectButton message handlers
|
|
|
|
BYTE CXTPSkinObjectButton::GetButtonStyle()
|
|
{
|
|
if (m_bStyle != 0xFF)
|
|
return m_bStyle;
|
|
|
|
BYTE bStyle = BYTE(GetStyle() & 0xF);
|
|
return bStyle;
|
|
}
|
|
|
|
void CXTPSkinObjectButton::OnDraw(CDC* pDC, CRect rc)
|
|
{
|
|
BOOL bPressed = m_bPushed;
|
|
BOOL bHot = m_bHot || (::GetCapture() == m_hWnd);
|
|
BYTE bStyle = GetButtonStyle();
|
|
BOOL bDefault = bStyle == BS_DEFPUSHBUTTON || bStyle == BS_DEFSPLITBUTTON;
|
|
BOOL bEnabled = IsWindowEnabled();
|
|
BOOL bChecked = (BOOL)SendMessage(BM_GETCHECK);
|
|
|
|
CXTPSkinManagerClass* pClassButton = GetSkinClass();
|
|
int nPart = 0;
|
|
int nState = 0;
|
|
|
|
if (IsPushButton())
|
|
{
|
|
nState = !bEnabled? PBS_DISABLED: bPressed? PBS_PRESSED: bHot? PBS_HOT: bChecked ? PBS_PRESSED : bDefault? PBS_DEFAULTED: PBS_NORMAL;
|
|
nPart = BP_PUSHBUTTON;
|
|
|
|
pClassButton->DrawThemeBackground(pDC, nPart, nState, rc);
|
|
|
|
if (bStyle == BS_SPLITBUTTON || bStyle == BS_DEFSPLITBUTTON)
|
|
{
|
|
CRect rcItem(rc);
|
|
rcItem.DeflateRect(4, 4);
|
|
rcItem.left = rcItem.right - 12;
|
|
CPoint ptCenter = rcItem.CenterPoint();
|
|
ptCenter.x += 1;
|
|
|
|
XTPDrawHelpers()->Triangle(pDC, CPoint(ptCenter.x - 3, ptCenter.y - 2),
|
|
CPoint(ptCenter.x + 3, ptCenter.y - 2), CPoint(ptCenter.x, ptCenter.y + 1), GetColor(!bEnabled ? COLOR_GRAYTEXT : COLOR_BTNTEXT));
|
|
|
|
pDC->FillSolidRect(rcItem.left, rcItem.top, 1, rcItem.Height(), GetColor(!bEnabled ? COLOR_GRAYTEXT : COLOR_BTNSHADOW));
|
|
pDC->FillSolidRect(rcItem.left + 1, rcItem.top, 1, rcItem.Height(), GetColor(COLOR_BTNHIGHLIGHT));
|
|
}
|
|
}
|
|
else if (bStyle == BS_RADIOBUTTON || bStyle == BS_AUTORADIOBUTTON)
|
|
{
|
|
nState = !bEnabled? RBS_UNCHECKEDDISABLED: bPressed? RBS_UNCHECKEDPRESSED: bHot? RBS_UNCHECKEDHOT: RBS_UNCHECKEDNORMAL;
|
|
if (bChecked) nState += 4;
|
|
nPart = BP_RADIOBUTTON;
|
|
|
|
CRect rcRadio;
|
|
CalcRect(pDC, &rcRadio, CBR_RADIOBOX);
|
|
pClassButton->DrawThemeBackground(pDC, nPart, nState, rcRadio);
|
|
}
|
|
else if (bStyle == BS_CHECKBOX || bStyle == BS_AUTOCHECKBOX || bStyle == BS_AUTO3STATE || bStyle == BS_3STATE)
|
|
{
|
|
nState = !bEnabled? RBS_UNCHECKEDDISABLED: bPressed? RBS_UNCHECKEDPRESSED: bHot? RBS_UNCHECKEDHOT: RBS_UNCHECKEDNORMAL;
|
|
if (bChecked)
|
|
nState += 4;
|
|
if ((bChecked == BST_INDETERMINATE) && (bStyle == BS_AUTO3STATE || bStyle == BS_3STATE))
|
|
nState += 4;
|
|
|
|
nPart = BP_CHECKBOX;
|
|
|
|
CRect rcRadio;
|
|
CalcRect(pDC, &rcRadio, CBR_CHECKBOX);
|
|
|
|
pClassButton->DrawThemeBackground(pDC, nPart, nState, rcRadio);
|
|
|
|
pDC->SetTextColor(pClassButton->GetThemeColor(BP_CHECKBOX, nState, TMT_TEXTCOLOR, GetColor(COLOR_BTNTEXT)));
|
|
}
|
|
else if (bStyle == BS_GROUPBOX)
|
|
{
|
|
nState = !bEnabled? GBS_DISABLED: GBS_NORMAL;
|
|
nPart = BP_GROUPBOX;
|
|
|
|
CRect rcGroupBox;
|
|
CalcRect(pDC, &rcGroupBox, CBR_GROUPFRAME);
|
|
|
|
pClassButton->DrawThemeBackground(pDC, nPart, nState, rcGroupBox);
|
|
|
|
CRect rcGrouText;
|
|
CalcRect(pDC, &rcGrouText, CBR_GROUPTEXT);
|
|
|
|
rcGrouText.left -= GetMetrics()->m_cxEdge;
|
|
|
|
FillBackground(pDC, rcGrouText, WM_CTLCOLORBTN);
|
|
}
|
|
else
|
|
{
|
|
}
|
|
|
|
DrawButtonText(pDC, nPart, nState);
|
|
}
|
|
|
|
LRESULT CXTPSkinObjectButton::OnSetText(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
BOOL bVisible = GetStyle() & WS_VISIBLE;
|
|
if (bVisible) ModifyStyle(WS_VISIBLE, 0);
|
|
|
|
LRESULT lResult = CXTPSkinObjectFrame::OnSetText(wParam, lParam);
|
|
|
|
if (bVisible) ModifyStyle(0, WS_VISIBLE);
|
|
|
|
if (GetButtonStyle() == BS_GROUPBOX) // Special clean for Group Box.
|
|
{
|
|
CXTPClientRect rc(this);
|
|
CClientDC dc(this);
|
|
|
|
CRect rcGrouText;
|
|
CalcRect(&dc, &rcGrouText, CBR_GROUPTEXT);
|
|
|
|
rcGrouText.left = 0;
|
|
rcGrouText.right = rc.right;
|
|
|
|
FillBackground(&dc, rcGrouText, WM_CTLCOLORBTN);
|
|
}
|
|
|
|
Invalidate(FALSE);
|
|
|
|
return lResult;
|
|
}
|
|
|
|
BOOL CXTPSkinObjectButton::OnHookMessage(UINT nMessage, WPARAM& wParam, LPARAM& lParam, LRESULT& lResult)
|
|
{
|
|
int bStyle = GetButtonStyle();
|
|
if (bStyle >= BS_OWNERDRAW && bStyle != BS_SPLITBUTTON && bStyle != BS_DEFSPLITBUTTON)
|
|
{
|
|
return FALSE;
|
|
}
|
|
return CXTPSkinObjectFrame::OnHookMessage(nMessage, wParam, lParam, lResult);
|
|
}
|
|
|
|
BOOL CXTPSkinObjectButton::OnHookDefWindowProc(UINT nMessage, WPARAM& wParam, LPARAM& lParam, LRESULT& lResult)
|
|
{
|
|
int bStyle = GetButtonStyle();
|
|
if (bStyle >= BS_OWNERDRAW && bStyle != BS_SPLITBUTTON && bStyle != BS_DEFSPLITBUTTON)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (!m_bActiveX && wParam && (nMessage == WM_PAINT || nMessage == WM_PRINTCLIENT))
|
|
{
|
|
OnDraw(CDC::FromHandle((HDC)wParam));
|
|
return TRUE;
|
|
}
|
|
|
|
return CXTPSkinObjectFrame::OnHookDefWindowProc(nMessage, wParam, lParam, lResult);
|
|
}
|
|
|
|
LRESULT CXTPSkinObjectButton::OnUpdateUIState(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LRESULT lResult = ::DefWindowProc(m_hWnd, WM_UPDATEUISTATE, wParam, lParam);
|
|
Invalidate(FALSE);
|
|
|
|
return lResult;
|
|
}
|