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.

541 lines
14 KiB
C++

2 years ago
// XTPSkinObjectComboBox.cpp: implementation of the CXTPSkinObjectComboBox 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/XTPDrawHelpers.h"
#include "Common/XTPSystemHelpers.h"
#include "XTPSkinObject.h"
#include "XTPSkinObjectFrame.h"
#include "XTPSkinObjectComboBox.h"
#include "XTPSkinManager.h"
#include "XTPSkinDrawTools.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CXTPSkinObjectComboBox, CXTPSkinObjectFrame)
CXTPSkinObjectComboBox::CXTPSkinObjectComboBox()
{
m_bHot = FALSE;
m_bPushed = FALSE;
m_strClassName = _T("COMBOBOX");
m_nCtlColorMessage = WM_CTLCOLORLISTBOX;
m_bPaint = FALSE;
}
CXTPSkinObjectComboBox::~CXTPSkinObjectComboBox()
{
}
BEGIN_MESSAGE_MAP(CXTPSkinObjectComboBox, CXTPSkinObjectFrame)
//{{AFX_MSG_MAP(CXTPSkinObjectComboBox)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_MOUSEMOVE()
ON_WM_CREATE()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_WM_CAPTURECHANGED()
//}}AFX_MSG_MAP
ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE_VOID(BM_SETSTYLE, OnStyleChanged)
ON_MESSAGE_VOID(WM_ENABLE, OnStyleChanged)
ON_MESSAGE_VOID(WM_UPDATEUISTATE, OnStyleChanged)
ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
ON_MESSAGE_VOID(WM_LBUTTONUP, OnStyleChanged)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CXTPSkinObjectComboBox message handlers
int CXTPSkinObjectComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CXTPSkinObject::OnCreate(lpCreateStruct) == -1)
return -1;
Invalidate(FALSE);
ModifyStyle(WS_BORDER, 0);
ModifyStyleEx(WS_EX_CLIENTEDGE|WS_EX_STATICEDGE, 0, SWP_FRAMECHANGED);
return 0;
}
HWND AFX_CDECL CXTPSkinObjectComboBox::GetComboListBox(HWND hWnd)
{
struct XTP_COMBOBOXINFO
{
DWORD cbSize;
RECT rcItem;
RECT rcButton;
DWORD stateButton;
HWND hwndCombo;
HWND hwndItem;
HWND hwndList;
};
HMODULE hLib = GetModuleHandle(_T("USER32"));
if (!hLib)
return 0;
typedef BOOL (WINAPI *PFNGETCOMBOBOXINFO) (HWND hwndCombo, XTP_COMBOBOXINFO* pcbi);
PFNGETCOMBOBOXINFO pfnGetComboBoxInfo = (PFNGETCOMBOBOXINFO)::GetProcAddress(hLib, "GetComboBoxInfo");
if (!pfnGetComboBoxInfo)
return 0;
XTP_COMBOBOXINFO ci;
ZeroMemory(&ci, sizeof(ci));
ci.cbSize = sizeof(ci);
if (!(*pfnGetComboBoxInfo)(hWnd, &ci))
return 0;
return ci.hwndList;
}
LRESULT CXTPSkinObjectComboBox::OnPrintClient(WPARAM wParam, LPARAM lParam)
{
if (((lParam & PRF_CLIENT) == 0) || m_bPaint)
return Default();
CDC* pDC = CDC::FromHandle((HDC)wParam);
if (pDC) OnDraw(pDC);
return 1;
}
void CXTPSkinObjectComboBox::OnPaint()
{
CXTPSkinObjectPaintDC dc(this); // device context for painting
OnDraw(&dc);
}
void CXTPSkinObjectComboBox::OnDraw(CDC* pDC)
{
if ((GetStyle() & 0x3) == CBS_SIMPLE || (GetStyle() & 0x3) == 0)
{
CXTPClientRect rcEdit(this);
rcEdit.bottom = rcEdit.top + (int)SendMessage(CB_GETITEMHEIGHT, (WPARAM)-1) + 2 * GetSystemMetrics(SM_CYFIXEDFRAME);
CXTPSkinManagerClass* pClass = m_pManager->GetSkinClass(this, _T("EDIT"));
CXTPSkinManagerMetrics* pMetrics = GetMetrics();
HBRUSH hBrush = GetClientBrush(pDC);
if (pClass->GetThemeEnumValue(0, 0, TMT_BGTYPE) == BT_BORDERFILL)
{
COLORREF clrBorderColor = pClass->GetThemeColor(0, 0, TMT_BORDERCOLOR);
pDC->Draw3dRect(rcEdit, clrBorderColor, clrBorderColor);
rcEdit.DeflateRect(1, 1);
XTPSkinFrameworkDrawFrame(pDC->GetSafeHdc(), &rcEdit, 1, hBrush);
}
else
{
pDC->Draw3dRect(rcEdit, pMetrics->m_clrEdgeShadow, pMetrics->m_clrEdgeHighLight);
rcEdit.DeflateRect(1, 1);
pDC->Draw3dRect(rcEdit, pMetrics->m_clrEdgeDkShadow, pMetrics->m_clrEdgeLight);
}
rcEdit.DeflateRect(1, 1);
XTPSkinFrameworkDrawFrame(pDC->GetSafeHdc(), &rcEdit, 1, hBrush);
return;
}
CRect rc;
GetClientRect(&rc);
BOOL bPressed = (GetKeyState(VK_LBUTTON) < 0) && SendMessage(CB_GETDROPPEDSTATE);
BOOL bHot = m_bHot || (::GetCapture() == m_hWnd);
BOOL bEnabled = IsWindowEnabled();
BOOL bRightAlign = GetExStyle() & WS_EX_RIGHT;
CXTPBufferDC memDC(*pDC, rc);
int nMessage = GetClientBrushMessage();
HBRUSH hBrush = FillBackground(&memDC, rc, nMessage);
m_bPaint = TRUE;
DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 );
m_bPaint = FALSE;
CXTPSkinManagerClass* pClassComboBox = GetSkinManager()->GetSkinClass(this, _T("COMBOBOX"));
memDC.SelectClipRgn(NULL);
int nState = !bEnabled? CBXS_DISABLED: bPressed? CBXS_PRESSED: bHot? CBXS_HOT: CBXS_NORMAL;
int nBGType = pClassComboBox->GetThemeEnumValue(0, nState, TMT_BGTYPE);
if (bRightAlign)
::FillRect(memDC.GetSafeHdc(), CRect(rc.left, rc.top, rc.left + max(GetMetrics()->m_cxVScroll + 1, GetMetrics()->m_cxOsVScroll + 3), rc.bottom), hBrush);
else
::FillRect(memDC.GetSafeHdc(), CRect(rc.right - max(GetMetrics()->m_cxVScroll + 1, GetMetrics()->m_cxOsVScroll + 3), rc.top, rc.right, rc.bottom), hBrush);
int nThumbWidth = GetMetrics()->m_cxVScroll;
if (nBGType == BT_IMAGEFILE)
{
CRect rectClient(rc.left + 3, rc.top + 3, rc.right - nThumbWidth - 3, rc.bottom - 3);
if (bRightAlign)
rectClient.OffsetRect(nThumbWidth, 0);
memDC.ExcludeClipRect(rectClient);
pClassComboBox->DrawThemeBackground(&memDC, 0, nState, rc);
}
else if (nBGType == BT_BORDERFILL)
{
COLORREF clrBorderColor = pClassComboBox->GetThemeColor(0, nState, TMT_BORDERCOLOR);
memDC.Draw3dRect(rc, clrBorderColor, clrBorderColor);
rc.DeflateRect(1, 1);
CRect rcClient(rc);
if (bRightAlign) rcClient.left += nThumbWidth; else rcClient.right -= nThumbWidth;
XTPSkinFrameworkDrawFrame(memDC, &rcClient, 2, hBrush);
}
CRect rcDropDownButton(rc);
if (bRightAlign) rcDropDownButton.right = rcDropDownButton.left + nThumbWidth;
else rcDropDownButton.left = rcDropDownButton.right - nThumbWidth;
pClassComboBox->DrawThemeBackground(&memDC, CP_DROPDOWNBUTTON, nState, rcDropDownButton);
}
BOOL CXTPSkinObjectComboBox::OnEraseBkgnd(CDC* /*pDC*/)
{
return TRUE;
}
void CXTPSkinObjectComboBox::OnMouseLeave()
{
OnMouseMove(0,CPoint(-1, -1));
}
void CXTPSkinObjectComboBox::OnMouseMove(UINT /*nFlags*/, CPoint point)
{
Default();
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);
}
}
}
void CXTPSkinObjectComboBox::OnSetFocus(CWnd* pOldWnd)
{
CXTPSkinObject::OnSetFocus(pOldWnd);
Invalidate(FALSE);
}
void CXTPSkinObjectComboBox::OnKillFocus(CWnd* pNewWnd)
{
CXTPSkinObject::OnKillFocus(pNewWnd);
Invalidate(FALSE);
}
void CXTPSkinObjectComboBox::OnStyleChanged()
{
Default();
Invalidate(FALSE);
}
void CXTPSkinObjectComboBox::OnCaptureChanged(CWnd* pWnd)
{
CXTPSkinObject::OnCaptureChanged(pWnd);
Invalidate(FALSE);
}
int CXTPSkinObjectComboBox::GetClientBrushMessage()
{
CWnd* pwndEdit = GetWindow(GW_CHILD);
int nMessage = !IsWindowEnabled() || (pwndEdit && pwndEdit->GetStyle() & ES_READONLY) ?
WM_CTLCOLORSTATIC : WM_CTLCOLOREDIT;
return nMessage;
}
//////////////////////////////////////////////////////////////////////////
// CXTPSkinObjectDateTime
IMPLEMENT_DYNCREATE(CXTPSkinObjectDateTime, CXTPSkinObjectComboBox)
CXTPSkinObjectDateTime::CXTPSkinObjectDateTime()
{
}
BEGIN_MESSAGE_MAP(CXTPSkinObjectDateTime, CXTPSkinObjectComboBox)
//{{AFX_MSG_MAP(CXTPSkinObjectDateTime)
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP(CXTPSkinObjectDateTime)
END_MESSAGE_MAP()
int CXTPSkinObjectDateTime::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CXTPSkinObject::OnCreate(lpCreateStruct) == -1)
return -1;
Invalidate(FALSE);
return 0;
}
void CXTPSkinObjectDateTime::OnSkinChanged(BOOL bPrevState, BOOL bNewState)
{
CXTPSkinObjectFrame::OnSkinChanged(bPrevState, bNewState);
}
CRect CXTPSkinObjectDateTime::GetButtonRect()
{
CXTPClientRect rc(this);
rc.left = rc.right - GetSystemMetrics(SM_CXVSCROLL);
return rc;
}
BOOL CXTPSkinObjectDateTime::IsVistaStyle() const
{
DWORD dwVersion = XTPSystemVersion()->GetComCtlVersion();
if (dwVersion >= MAKELONG(10, 6) || (HIWORD(dwVersion) == 5 && LOWORD(dwVersion) >= 52))
{
return (GetExStyle() & WS_EX_CLIENTEDGE) == 0;
}
return FALSE;
}
void CXTPSkinObjectDateTime::OnDraw(CDC* pDC)
{
CRect rc;
GetClientRect(&rc);
BOOL bHot = m_bHot || (::GetCapture() == m_hWnd);
BOOL bEnabled = IsWindowEnabled();
CXTPBufferDC memDC(*pDC, rc);
COLORREF clr = GetColor(IsWindowEnabled() ? COLOR_WINDOW : COLOR_3DFACE);
memDC.FillSolidRect(rc, clr);
if (m_bActiveX)
{
m_bPaint = TRUE;
CXTPBufferDC dcMem2(*pDC, rc);
DefWindowProc(WM_PAINT, (WPARAM)dcMem2.GetSafeHdc(), 0);
dcMem2.Discard();
m_bPaint = FALSE;
}
DefWindowProc( WM_PRINTCLIENT, (WPARAM)memDC.m_hDC, 0 );
CXTPSkinManagerClass* pClassComboBox = GetSkinManager()->GetSkinClass(this, _T("COMBOBOX"));
int nState = !bEnabled? CBXS_DISABLED: bHot? CBXS_HOT: CBXS_NORMAL;
int nBGType = pClassComboBox->GetThemeEnumValue(0, nState, TMT_BGTYPE);
int nThumbWidth = GetSystemMetrics(SM_CXVSCROLL);
BOOL bVistaStyle = IsVistaStyle();
if (!bVistaStyle)
{
memDC.FillSolidRect(CRect(rc.right - nThumbWidth - 3, rc.top, rc.right, rc.bottom), clr);
}
if (bVistaStyle)
{
if (nBGType == BT_IMAGEFILE)
{
CRect rectClient(rc.left + 2, rc.top + 2, rc.right - 2, rc.bottom - 2);
memDC.ExcludeClipRect(rectClient);
pClassComboBox->DrawThemeBackground(&memDC, 0, nState, rc);
}
else if (nBGType == BT_BORDERFILL)
{
COLORREF clrBorderColor = pClassComboBox->GetThemeColor(0, nState, TMT_BORDERCOLOR);
memDC.Draw3dRect(rc, clrBorderColor, clrBorderColor);
rc.DeflateRect(1, 1);
CRect rcClient(rc);
memDC.Draw3dRect(&rcClient,clr, clr);
}
}
memDC.SelectClipRgn(NULL);
if (GetStyle() & DTS_SHOWNONE)
{
CRect rcCheck(rc);
rcCheck.DeflateRect(1, 1);
rcCheck.right = rcCheck.left + rcCheck.Height();
memDC.FillSolidRect(rcCheck, clr);
CXTPSkinManagerClass* pClassButton = GetSkinManager()->GetSkinClass(this, _T("BUTTON"));
CSize size(13, 13);
pClassButton->GetThemePartSize(BP_CHECKBOX, 0, NULL, TS_TRUE, &size);
CRect rcMark(CPoint((rcCheck.left + rcCheck.right - size.cx) / 2,
(rcCheck.top + rcCheck.bottom - size.cy) / 2), size);
int nStateButton = !bEnabled ? CBS_UNCHECKEDDISABLED : CBS_UNCHECKEDNORMAL;
SYSTEMTIME st;
BOOL bChecked = SendMessage(DTM_GETSYSTEMTIME, 0, (LPARAM)&st) != GDT_NONE;
if (bChecked)
nStateButton += 4;
pClassButton->DrawThemeBackground(&memDC, BP_CHECKBOX, nStateButton, &rcMark);
}
if (((GetStyle() & DTS_UPDOWN) == 0) && !bVistaStyle)
{
CRect rcButton = rc;
rcButton.left = rcButton.right - GetSystemMetrics(SM_CXVSCROLL);
memDC.FillSolidRect(rcButton.left, rcButton.top, rcButton.Width(), rcButton.Height(), clr);
pClassComboBox->DrawThemeBackground(&memDC, CP_DROPDOWNBUTTON, nState, rcButton);
}
}
int CXTPSkinObjectDateTime::GetClientBrushMessage()
{
return CXTPSkinObjectComboBox::GetClientBrushMessage();
}
void CXTPSkinObjectDateTime::OnLButtonDown(UINT nFlags, CPoint point)
{
if (IsWindowEnabled() && ((GetStyle() & DTS_UPDOWN) == 0) && GetButtonRect().PtInRect(point))
{
SetFocus();
DefWindowProc(WM_SYSKEYDOWN, VK_DOWN, 0);
return;
}
CXTPSkinObjectComboBox::OnLButtonDown(nFlags, point);
}
void CXTPSkinObjectDateTime::RefreshMetrics()
{
CXTPSkinObjectComboBox::RefreshMetrics();
SendMessage(DTM_SETMCCOLOR, MCSC_BACKGROUND, (LPARAM)GetColor(COLOR_WINDOW));
SendMessage(DTM_SETMCCOLOR, MCSC_MONTHBK, (LPARAM)GetColor(COLOR_WINDOW));
SendMessage(DTM_SETMCCOLOR, MCSC_TEXT, (LPARAM)GetColor(COLOR_WINDOWTEXT));
SendMessage(DTM_SETMCCOLOR, MCSC_TITLEBK, (LPARAM)GetColor(COLOR_ACTIVECAPTION));
SendMessage(DTM_SETMCCOLOR, MCSC_TITLETEXT, (LPARAM)GetColor(COLOR_CAPTIONTEXT));
SendMessage(DTM_SETMCCOLOR, MCSC_TRAILINGTEXT, (LPARAM)GetColor(COLOR_GRAYTEXT));
}
void CXTPSkinObjectDateTime::DrawFrame(CDC* pDC)
{
if (GetExStyle() & WS_EX_CLIENTEDGE)
{
BOOL bHot = m_bHot || (::GetCapture() == m_hWnd);
BOOL bEnabled = IsWindowEnabled();
CXTPSkinManagerClass* pClassComboBox = GetSkinManager()->GetSkinClass(this, _T("COMBOBOX"));
int nState = !bEnabled? CBXS_DISABLED: bHot? CBXS_HOT: CBXS_NORMAL;
int nBGType = pClassComboBox->GetThemeEnumValue(0, nState, TMT_BGTYPE);
if (nBGType == BT_IMAGEFILE)
{
CXTPWindowRect rc(this);
rc.OffsetRect(-rc.TopLeft());
CRect rectClient(rc.left + 2, rc.top + 2, rc.right - 2, rc.bottom - 2);
pDC->ExcludeClipRect(rectClient);
pClassComboBox->DrawThemeBackground(pDC, 0, nState, rc);
pDC->SelectClipRgn(NULL);
return;
}
}
CXTPSkinObjectComboBox::DrawFrame(pDC);
}
//////////////////////////////////////////////////////////////////////////
// CXTPSkinObjectMonthCal
IMPLEMENT_DYNCREATE(CXTPSkinObjectMonthCal, CXTPSkinObjectFrame)
CXTPSkinObjectMonthCal::CXTPSkinObjectMonthCal()
{
}
void CXTPSkinObjectMonthCal::RefreshMetrics()
{
CXTPSkinObjectFrame::RefreshMetrics();
SendMessage(MCM_SETCOLOR, MCSC_BACKGROUND, (LPARAM)GetColor(COLOR_WINDOW));
SendMessage(MCM_SETCOLOR, MCSC_MONTHBK, (LPARAM)GetColor(COLOR_WINDOW));
SendMessage(MCM_SETCOLOR, MCSC_TEXT, (LPARAM)GetColor(COLOR_WINDOWTEXT));
SendMessage(MCM_SETCOLOR, MCSC_TITLEBK, (LPARAM)GetColor(COLOR_ACTIVECAPTION));
SendMessage(MCM_SETCOLOR, MCSC_TITLETEXT, (LPARAM)GetColor(COLOR_CAPTIONTEXT));
SendMessage(MCM_SETCOLOR, MCSC_TRAILINGTEXT, (LPARAM)GetColor(COLOR_GRAYTEXT));
}