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.

1018 lines
24 KiB
C++

// XTPSkinManager.cpp: implementation of the CXTPSkinManager 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/Tmschema.h"
#include "Common/Uxtheme.h"
#include "Common/XTPColorManager.h"
#include "Common/XTPSystemHelpers.h"
#include "XTPSkinObject.h"
#include "XTPSkinManagerColorFilter.h"
#include "XTPSkinManager.h"
#include "XTPSkinManagerSchema.h"
#include "XTPSkinImage.h"
#include "XTPSkinManagerResource.h"
#include "XTPSkinObject.h"
#include "XTPSkinObjectFrame.h"
#include "XTPSkinManagerSchema.h"
#include "XTPSkinManagerApiHook.h"
#include "XTPSkinManagerModuleList.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define EVENT_OBJECT_REORDER 0x8004
CXTPSkinManagerMetrics::CXTPSkinManagerMetrics(CXTPSkinManagerSchema* pSchema)
{
m_pSchema = pSchema;
m_brushDialog = NULL;
m_brushTabControl = NULL;
m_brushWindow = NULL;
ZeroMemory(m_brTheme, sizeof(m_brTheme));
memset(m_clrTheme, -1, sizeof(m_clrTheme));
m_cyCaption = m_cySmallCaption = m_cyOsCaption = m_cyOsSmallCaption = 0;
m_bRefreshMetrics = FALSE;
}
CXTPSkinManagerMetrics::~CXTPSkinManagerMetrics()
{
DestroyMetrics();
}
COLORREF CXTPSkinManagerMetrics::GetColor(int nIndex) const
{
return nIndex < XTP_SKINMETRICS_COLORTABLESIZE ? m_clrTheme[nIndex] : 0;
}
BOOL CXTPSkinManagerMetrics::IsMetricObject(HGDIOBJ hObject) const
{
if (hObject == 0)
return FALSE;
if (GetObjectType(hObject) != OBJ_BRUSH)
return FALSE;
if (hObject == m_brushWindow || hObject == m_brushDialog || hObject == m_brushTabControl)
return TRUE;
for (int i = 0; i < XTP_SKINMETRICS_COLORTABLESIZE; i++)
{
if (hObject == m_brTheme[i])
return TRUE;
}
return FALSE;
}
void CXTPSkinManagerMetrics::DeleteSysBrush(HBRUSH* pBrush)
{
if (pBrush && *pBrush)
{
HBRUSH hBrush = *pBrush;
*pBrush = NULL;
DeleteObject(hBrush);
}
}
void CXTPSkinManagerMetrics::DestroyMetrics()
{
m_fntCaption.DeleteObject();
m_fntSmCaption.DeleteObject();
m_fntMenu.DeleteObject();
for (int iColorId = 0; iColorId < XTP_SKINMETRICS_COLORTABLESIZE; iColorId++)
{
DeleteSysBrush(&m_brTheme[iColorId]);
}
DeleteSysBrush(&m_brushDialog);
DeleteSysBrush(&m_brushTabControl);
DeleteSysBrush(&m_brushWindow);
}
void CXTPSkinManagerMetrics::RefreshMetrics()
{
static const COLORREF defColors[XTP_SKINMETRICS_COLORTABLESIZE] =
{
RGB(192, 192, 192),
RGB( 58, 110, 165),
RGB( 0, 0, 128),
RGB(128, 128, 128),
RGB(192, 192, 192),
RGB(255, 255, 255),
RGB( 0, 0, 0),
RGB( 0, 0, 0),
RGB( 0, 0, 0),
RGB(255, 255, 255),
RGB(192, 192, 192),
RGB(192, 192, 192),
RGB(128, 128, 128),
RGB( 0, 0, 128),
RGB(255, 255, 255),
RGB(192, 192, 192),
RGB(128, 128, 128),
RGB(128, 128, 128),
RGB( 0, 0, 0),
RGB(192, 192, 192),
RGB(255, 255, 255),
RGB( 0, 0, 0),
RGB(223, 223, 223),
RGB( 0, 0, 0),
RGB(255, 255, 225),
RGB(180, 180, 180),
RGB( 0, 0, 255),
RGB( 16, 132, 208),
RGB(181, 181, 181),
RGB( 0, 0, 128),
RGB(192, 192, 192)
};
CXTPSkinManagerSchema* pSchema = m_pSchema;
if (!pSchema)
{
for (int iColorId = 0; iColorId < XTP_SKINMETRICS_COLORTABLESIZE; iColorId++)
{
m_clrTheme[iColorId] = GetSysColor(iColorId);
DeleteSysBrush(&m_brTheme[iColorId]);
}
return;
}
m_bRefreshMetrics = TRUE;
UINT nSysMetrics = pSchema->GetClassCode(_T("SYSMETRICS"));
NONCLIENTMETRICS ncm;
ZeroMemory(&ncm, sizeof(NONCLIENTMETRICS));
ncm.cbSize = sizeof(NONCLIENTMETRICS);
VERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0));
m_fntCaption.DeleteObject();
m_fntCaption.CreateFontIndirect(&ncm.lfCaptionFont);
m_fntSmCaption.DeleteObject();
m_fntSmCaption.CreateFontIndirect(&ncm.lfSmCaptionFont);
m_fntMenu.DeleteObject();
m_fntMenu.CreateFontIndirect(&ncm.lfMenuFont);
m_nBorderSize = 1;
SystemParametersInfo(SPI_GETBORDER, 0, &m_nBorderSize, FALSE);
m_cxBorder = GetSystemMetrics(SM_CXBORDER);
m_cyBorder = GetSystemMetrics(SM_CYBORDER);
m_cxEdge = GetSystemMetrics(SM_CXEDGE);
m_cyEdge = GetSystemMetrics(SM_CYEDGE);
m_cxHScroll = GetSystemMetrics(SM_CXHSCROLL);
m_cyHScroll = GetSystemMetrics(SM_CYHSCROLL);
m_cxOsVScroll = m_cxVScroll = GetSystemMetrics(SM_CXVSCROLL);
m_cyVScroll = GetSystemMetrics(SM_CYVSCROLL);
BOOL bApplyMetrics = pSchema->GetSkinManager()->GetApplyOptions() & xtpSkinApplyMetrics;
m_cyOsCaption = m_cyCaption = GetSystemMetrics(SM_CYCAPTION);
m_cyOsSmallCaption = m_cySmallCaption = GetSystemMetrics(SM_CYSMCAPTION);
if (bApplyMetrics)
{
pSchema->GetIntProperty(nSysMetrics, 0, 0, TMT_CAPTIONBARHEIGHT, m_cyCaption);
m_cyCaption++;
pSchema->GetIntProperty(nSysMetrics, 0, 0, TMT_SMCAPTIONBARHEIGHT, m_cySmallCaption);
m_cySmallCaption++;
int nScrollbarWidth = 0, nScrollbarHeight = 0;
if (SUCCEEDED(pSchema->GetIntProperty(nSysMetrics, 0, 0, TMT_SCROLLBARWIDTH, nScrollbarWidth)) && nScrollbarWidth > 0)
{
m_cxHScroll = m_cxVScroll = nScrollbarWidth;
}
if (SUCCEEDED(pSchema->GetIntProperty(nSysMetrics, 0, 0, TMT_SCROLLBARHEIGHT, nScrollbarHeight)) && nScrollbarHeight > 0)
{
m_cyHScroll = m_cyVScroll = nScrollbarHeight;
}
LOGFONT lfCaption, lfSmCaption, lfMenu;
if (SUCCEEDED(pSchema->GetFontProperty(nSysMetrics, 0, 0, TMT_CAPTIONFONT, lfCaption)))
{
m_fntCaption.DeleteObject();
m_fntCaption.CreateFontIndirect(&lfCaption);
}
if (SUCCEEDED(pSchema->GetFontProperty(nSysMetrics, 0, 0, TMT_SMALLCAPTIONFONT, lfSmCaption)))
{
m_fntSmCaption.DeleteObject();
m_fntSmCaption.CreateFontIndirect(&lfSmCaption);
}
if (SUCCEEDED(pSchema->GetFontProperty(nSysMetrics, 0, 0, TMT_MENUFONT, lfMenu)))
{
m_fntMenu.DeleteObject();
m_fntMenu.CreateFontIndirect(&lfMenu);
}
}
for (int iColorId = 0; iColorId < XTP_SKINMETRICS_COLORTABLESIZE; iColorId++)
{
COLORREF clrOld = m_clrTheme[iColorId];
m_clrTheme[iColorId] = (COLORREF)-1;
COLORREF clrVal;
if (FAILED(pSchema->GetColorProperty(nSysMetrics, 0, 0, iColorId + TMT_FIRSTCOLOR, clrVal)))
{
clrVal = defColors[iColorId];
pSchema->GetSkinManager()->ApplyColorFilter(clrVal);
}
m_clrTheme[iColorId] = clrVal;
if ((clrOld != clrVal) || (m_brTheme[iColorId] == NULL))
{
DeleteSysBrush(&m_brTheme[iColorId]);
m_brTheme[iColorId] = CreateSolidBrush(clrVal);
}
}
m_clrEdgeHighLight = m_clrTheme[COLOR_BTNHIGHLIGHT];
m_clrEdgeShadow = m_clrTheme[COLOR_BTNSHADOW];
m_clrEdgeLight = m_clrTheme[COLOR_3DLIGHT];
m_clrEdgeDkShadow = m_clrTheme[COLOR_3DDKSHADOW];
DeleteSysBrush(&m_brushDialog);
m_brushDialog = ::CreateSolidBrush(m_clrTheme[COLOR_3DFACE]);
DeleteSysBrush(&m_brushTabControl);
DeleteSysBrush(&m_brushWindow);
m_brushWindow = ::CreateSolidBrush(m_clrTheme[COLOR_WINDOW]);
m_bRefreshMetrics = FALSE;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// CXTPSkinManager
class XTP_SKINAMANGER_THREAD_STATE : public CNoTrackObject
{
public:
XTP_SKINAMANGER_THREAD_STATE();
virtual ~XTP_SKINAMANGER_THREAD_STATE();
public:
HHOOK m_hHookOldCbtFilter;
};
XTP_SKINAMANGER_THREAD_STATE::XTP_SKINAMANGER_THREAD_STATE()
{
m_hHookOldCbtFilter = 0;
}
XTP_SKINAMANGER_THREAD_STATE::~XTP_SKINAMANGER_THREAD_STATE()
{
if (m_hHookOldCbtFilter)
{
UnhookWindowsHookEx(m_hHookOldCbtFilter);
}
}
THREAD_LOCAL(XTP_SKINAMANGER_THREAD_STATE, _xtpSkinManagerThreadState)
CXTPSkinManager::CXTPSkinManager()
{
::InitializeCriticalSection(&m_csObjects);
m_pSchema = NULL;
m_bEnabled = FALSE;
m_pResourceFile = new CXTPSkinManagerResourceFile(this);
m_pClassMap = new CXTPSkinObjectClassMap();
m_pClassMap->AddStandardClasses();
m_mapObjects.InitHashTable(199, FALSE);
m_bAutoApplyWindows = TRUE;
m_bAutoApplyThreads = TRUE;
m_dwApplyOptions = xtpSkinApplyFrame | xtpSkinApplyColors | xtpSkinApplyMetrics | xtpSkinApplyMenus;
m_dwComCtrl = XTPSystemVersion()->GetComCtlVersion();
m_bWin9x = XTPSystemVersion()->IsWin9x();
m_hWinEventHook = NULL;
m_pSetWinEventHook = NULL;
m_pUnhookWinEvent = NULL;
CXTPSkinManagerApiHook* pApiHook = CXTPSkinManagerApiHook::GetInstance();
pApiHook;
HMODULE hLib = GetModuleHandle(_T("USER32"));
if (hLib)
{
m_pSetWinEventHook = (LPFNSETWINEVENTHOOK)GetProcAddress(hLib, "SetWinEventHook");
m_pUnhookWinEvent = (LPFNUNHOOKWINEVENT)GetProcAddress(hLib, "UnhookWinEvent");
if (m_pSetWinEventHook && m_pUnhookWinEvent)
{
m_hWinEventHook = m_pSetWinEventHook(EVENT_OBJECT_REORDER, EVENT_OBJECT_REORDER, NULL,
&CXTPSkinManager::WinEventProc, GetCurrentProcessId(), 0, 0);
}
}
EnableCurrentThread();
#ifdef _AFXDLL
m_pModuleState = AfxGetModuleState();
#endif
}
void CXTPSkinManager::EnableCurrentThread()
{
DWORD dwThread = ::GetCurrentThreadId();
XTP_SKINAMANGER_THREAD_STATE* pThreadState = _xtpSkinManagerThreadState.GetData();
if (pThreadState)
{
if (pThreadState->m_hHookOldCbtFilter == 0)
{
pThreadState->m_hHookOldCbtFilter = ::SetWindowsHookEx(WH_CBT, CbtFilterHook, NULL, dwThread);
}
}
}
CXTPSkinManager::~CXTPSkinManager()
{
FreeSkinData();
RemoveColorFilters();
CMDTARGET_RELEASE(m_pSchema);
CMDTARGET_RELEASE(m_pResourceFile);
SAFE_DELETE(m_pClassMap);
RemoveAll();
CXTPSkinManagerApiHook* pApiHook = CXTPSkinManagerApiHook::GetInstance();
pApiHook->FinalizeHookManagement();
HMODULE hLib = GetModuleHandle(_T("USER32"));
if (m_hWinEventHook && hLib && m_pUnhookWinEvent)
{
m_pUnhookWinEvent(m_hWinEventHook);
}
::DeleteCriticalSection(&m_csObjects);
}
BOOL CXTPSkinManager::IsColorFilterExists() const
{
return m_arrFilters.GetSize() > 0;
}
void CXTPSkinManager::RemoveColorFilters()
{
for (int i = 0; i < (int)m_arrFilters.GetSize(); i++)
{
delete m_arrFilters[i];
}
m_arrFilters.RemoveAll();
}
void CXTPSkinManager::AddColorFilter(CXTPSkinManagerColorFilter* pFilter)
{
m_arrFilters.Add(pFilter);
}
void CXTPSkinManager::RedrawAllControls()
{
if (!m_bEnabled)
return;
if (!m_pSchema)
return;
POSITION pos = m_pSchema->m_mapClasses.GetStartPosition();
CString strClassName;
CXTPSkinManagerClass* pClass;
while (pos != NULL)
{
m_pSchema->m_mapClasses.GetNextAssoc( pos, strClassName, (void*&)pClass);
pClass->GetImages()->RemoveAll();
}
m_pSchema->GetMetrics()->RefreshMetrics();
XTPColorManager()->RefreshColors();
OnSkinChanged(TRUE, TRUE);
}
void CXTPSkinManager::ApplyColorFilter(COLORREF& clr)
{
for (int i = 0; i < (int)m_arrFilters.GetSize(); i++)
{
m_arrFilters[i]->ApplyColorFilter(clr);
}
}
CXTPSkinManagerSchema* CXTPSkinManager::CreateSchema(LPCTSTR lpszResourcePath, LPCTSTR lpszIniFileName)
{
if (XTPColorManager()->IsLowResolution() || !CXTPSkinManagerModuleList::IsEnumeratorExists())
return NULL;
CXTPSkinManagerResourceFile* pResourceFile = new CXTPSkinManagerResourceFile(this);
if (!pResourceFile->Open(lpszResourcePath, lpszIniFileName))
{
CMDTARGET_RELEASE(pResourceFile);
return NULL;
}
CXTPSkinManagerSchema* pSchema = pResourceFile->CreateSchema();
if (!pSchema)
{
CMDTARGET_RELEASE(pResourceFile);
return NULL;
}
CMDTARGET_RELEASE(pResourceFile);
if (FAILED(pSchema->ReadProperties()))
{
CMDTARGET_RELEASE(pSchema);
return NULL;
}
pSchema->RefreshMetrcis();
return pSchema;
}
BOOL CXTPSkinManager::LoadSkin(LPCTSTR lpszResourcePath, LPCTSTR lpszIniFileName)
{
CMDTARGET_RELEASE(m_pSchema);
CXTPSkinManagerApiHook* pApiHook = CXTPSkinManagerApiHook::GetInstance();
pApiHook->FinalizeHookManagement();
XTPSoundManager()->StopThread();
BOOL bEnabled = m_bEnabled;
if (XTPColorManager()->IsLowResolution() ||
!CXTPSkinManagerModuleList::IsEnumeratorExists() ||
!ReadSkinData(lpszResourcePath, lpszIniFileName))
{
m_bEnabled = FALSE;
}
else
{
m_bEnabled = TRUE;
pApiHook->InitializeHookManagement();
m_pSchema->RefreshMetrcis();
}
XTPColorManager()->RefreshColors();
OnSkinChanged(bEnabled, m_bEnabled);
return m_bEnabled;
}
CXTPSkinManagerMetrics* CXTPSkinManager::GetMetrics() const
{
return m_pSchema ? m_pSchema->GetMetrics() : NULL;
}
CXTPSkinManagerClass* CXTPSkinManager::FromHandle(HTHEME hTheme)
{
if (!m_pSchema)
return NULL;
CMapStringToPtr& mapClasses = m_pSchema->m_mapClasses;
POSITION pos = mapClasses.GetStartPosition();
CString strClassName;
CXTPSkinManagerClass* pClass;
while (pos != NULL)
{
mapClasses.GetNextAssoc( pos, strClassName, (void*&)pClass);
if (pClass == (CXTPSkinManagerClass*)hTheme)
return pClass;
}
return NULL;
}
void CXTPSkinManager::ExcludeModule(LPCTSTR lpszModule)
{
CXTPSkinManagerApiHook* pApiHook = CXTPSkinManagerApiHook::GetInstance();
pApiHook->ExcludeModule(lpszModule, FALSE);
}
void CXTPSkinManager::SetApplyOptions(DWORD dwOptions)
{
m_dwApplyOptions = dwOptions;
if (!m_bEnabled)
return;
CXTPSkinManagerApiHook* pApiHook = CXTPSkinManagerApiHook::GetInstance();
pApiHook->FinalizeHookManagement();
pApiHook->InitializeHookManagement();
m_pSchema->RefreshMetrcis();
XTPColorManager()->RefreshColors();
OnSkinChanged(m_bEnabled, m_bEnabled);
}
void CXTPSkinManager::SetResourceFile(CXTPSkinManagerResourceFile* pResourceFile)
{
ASSERT(pResourceFile);
if (!pResourceFile)
return;
CMDTARGET_RELEASE(m_pResourceFile);
m_pResourceFile = pResourceFile;
m_pResourceFile->m_pManager = this;
}
void CXTPSkinManager::FreeSkinData()
{
m_pResourceFile->Close();
}
BOOL CXTPSkinManager::ReadSkinData(LPCTSTR strResourcePath, LPCTSTR strIniFileName)
{
FreeSkinData();
if (!m_pResourceFile->Open(strResourcePath, strIniFileName))
return FALSE;
m_pSchema = m_pResourceFile->CreateSchema();
if (!m_pSchema)
return FALSE;
if (FAILED(m_pSchema->ReadProperties()))
return FALSE;
return TRUE;
}
CXTPSkinManager* CXTPSkinManager::s_pInstance = NULL;
static class CXTPSkinManager::CDestructor
{
public:
~CDestructor()
{
if (s_pInstance != NULL)
delete s_pInstance;
}
} __xtpSkinManagerDestructor;
LRESULT CALLBACK CXTPSkinManager::CbtFilterHook(int code, WPARAM wParam, LPARAM lParam)
{
XTP_SKINAMANGER_THREAD_STATE* pThreadState = _xtpSkinManagerThreadState.GetData();
LRESULT lResult = CallNextHookEx(pThreadState->m_hHookOldCbtFilter, code,
wParam, lParam);
if (code == HCBT_CREATEWND && XTPSkinManager()->m_bAutoApplyWindows)
{
ASSERT(lParam != NULL);
LPCREATESTRUCT lpcs = ((LPCBT_CREATEWND)lParam)->lpcs;
ASSERT(lpcs != NULL);
ASSERT(wParam != NULL); // should be non-NULL HWND
HWND hWnd = (HWND)wParam;
TCHAR lpszClassName[50];
GetClassName(hWnd, lpszClassName, 50);
if (XTPSkinManager()->Lookup(hWnd) != NULL)
{
TRACE(_T("Warning: Window already attached\n"));
}
else
{
XTPSkinManager()->SetHook(hWnd, lpszClassName, lpcs, TRUE);
}
}
return lResult;
}
_XTP_EXT_CLASS CXTPSkinManager* AFX_CDECL XTPSkinManager()
{
if (CXTPSkinManager::s_pInstance == NULL)
CXTPSkinManager::s_pInstance = new CXTPSkinManager();
return CXTPSkinManager::s_pInstance;
}
CXTPSkinManager* CXTPSkinManager::SetSkinManager(CXTPSkinManager* pSkinManager, BOOL bDelete /*=TRUE*/)
{
ASSERT(pSkinManager != NULL);
if (pSkinManager != NULL)
{
CXTPSkinManager* pPrevInstance = NULL;
if (bDelete) {
SAFE_DELETE(s_pInstance);
}
else {
pPrevInstance = s_pInstance;
}
s_pInstance = pSkinManager;
return pPrevInstance;
}
return NULL;
}
CXTPSkinManagerClass* CXTPSkinManager::GetSkinClass(const CXTPSkinObject* pObject, CString strClassList)
{
CXTPSkinManagerSchema* pSchema = pObject && pObject->m_pSchema ? pObject->m_pSchema : m_pSchema;
CMapStringToPtr& mapClasses = pSchema->m_mapClasses;
strClassList.MakeUpper();
CXTPSkinManagerClass* pClass;
if (mapClasses.Lookup(strClassList, (void *&)pClass))
return pClass;
int nClassCode = pSchema->GetClassCode(strClassList);
if (nClassCode == 0)
return NULL; // Not supported;
pClass = new CXTPSkinManagerClass(pSchema);
pClass->m_strClass = strClassList;
pClass->m_nClassCode = nClassCode;
mapClasses.SetAt(strClassList, pClass);
return pClass;
}
void CXTPSkinManager::GetCurrentThemeName(CString& strThemeFileName, CString& strColorBuff)
{
if (m_pResourceFile)
{
strThemeFileName = m_pResourceFile->GetResourcePath();
strColorBuff = m_pResourceFile->GetIniFileName();
}
}
int CXTPSkinManager::GetThemeSysSize(int iSizeId)
{
int iVal = 0;
if (!SUCCEEDED(m_pSchema->GetIntProperty(m_pSchema->GetClassCode(_T("SYSMETRICS")), 0, 0, iSizeId, iVal)))
return 0;
return iVal;
}
BOOL CXTPSkinManager::GetThemeSysBool(int iBoolId)
{
BOOL bVal = FALSE;
if (!SUCCEEDED(m_pSchema->GetBoolProperty(m_pSchema->GetClassCode(_T("SYSMETRICS")), 0, 0, iBoolId, bVal)))
return FALSE;
return bVal;
}
COLORREF CXTPSkinManager::GetThemeSysColor(int iColorId)
{
if (!m_pSchema)
return GetSysColor(iColorId - TMT_FIRSTCOLOR);
return iColorId >= TMT_FIRSTCOLOR && iColorId <= TMT_LASTCOLOR ?
m_pSchema->GetMetrics()->m_clrTheme[iColorId - TMT_FIRSTCOLOR] : (COLORREF)-1;
}
HRESULT CXTPSkinManager::GetThemeSysFont(int iFontId, LOGFONT *plf)
{
HRESULT hr = m_pSchema->GetFontProperty(m_pSchema->GetClassCode(_T("SYSMETRICS")), 0, 0, iFontId, *plf);
return hr;
}
HRESULT CXTPSkinManager::EnableThemeDialogTexture(HWND hWnd, DWORD dwFlags)
{
CXTPSkinObjectFrame* pObject = (CXTPSkinObjectFrame*)Lookup(hWnd);
if (!pObject)
return E_INVALIDARG;
pObject->m_dwDialogTexture = dwFlags;
if (pObject->m_dwDialogTexture == ETDT_ENABLETAB)
{
pObject->SetWindowProc();
}
return S_OK;
}
void CXTPSkinManager::SetWindowTheme(HWND hWnd, CXTPSkinManagerSchema* pSchema)
{
CXTPSkinObject* pSkinObject = Lookup(hWnd);
if (pSkinObject)
{
CMDTARGET_RELEASE(pSkinObject->m_pSchema);
pSkinObject->m_pSchema = pSchema;
CMDTARGET_ADDREF(pSchema);
pSkinObject->OnSkinChanged(m_bEnabled, pSchema ? TRUE : m_bEnabled);
}
hWnd = ::GetWindow(hWnd, GW_CHILD);
while (hWnd)
{
SetWindowTheme(hWnd, pSchema);
hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
}
}
//////////////////////////////////////////////////////////////////////////
CXTPSkinManagerClass::CXTPSkinManagerClass(CXTPSkinManagerSchema* pSchema)
{
m_pImages = new CXTPSkinImages();
m_pSchema = pSchema;
m_mapCachedProperties.InitHashTable(199);
}
CXTPSkinManagerClass::~CXTPSkinManagerClass()
{
delete m_pImages;
}
BOOL CXTPSkinManagerClass::DrawThemeText(CDC* pDC, int iPartId, int iStateId, const CString& strText, DWORD dwFormat, const RECT *pRect)
{
pDC->SetBkMode(TRANSPARENT);
CRect rcCaptionMargins = GetThemeRect(iPartId, iStateId, TMT_CAPTIONMARGINS);
rcCaptionMargins.top = rcCaptionMargins.bottom = 0;
CRect rc(pRect);
rc.DeflateRect(rcCaptionMargins);
if (GetThemeEnumValue(iPartId, iStateId, TMT_CONTENTALIGNMENT) == CA_CENTER)
{
dwFormat |= DT_CENTER;
}
pDC->SetTextColor(GetThemeColor(iPartId, iStateId, TMT_TEXTCOLOR, pDC->GetTextColor()));
if (GetThemeEnumValue(iPartId, iStateId, TMT_TEXTSHADOWTYPE) == TST_SINGLE)
{
CSize sz = GetThemeSize(iPartId, iStateId, TMT_TEXTSHADOWOFFSET);
if (sz != CSize(0, 0))
{
COLORREF clrShadow = GetThemeColor(iPartId, iStateId, TMT_TEXTSHADOWCOLOR);
CRect rcShadow(rc);
rcShadow.OffsetRect(sz);
COLORREF clr = pDC->SetTextColor(clrShadow);
pDC->DrawText(strText, rcShadow, dwFormat);
pDC->SetTextColor(clr);
}
}
pDC->DrawText(strText, rc, dwFormat);
return TRUE;
}
CXTPSkinManagerSchemaProperty* CXTPSkinManagerClass::GetProperty(XTPSkinManagerProperty propType, int iPartId, int iStateId, int iPropId)
{
UINT nCachedProp = iPropId + ((iPartId + (iStateId << 6 )) << 14);
CXTPSkinManagerSchemaProperty* pProperty = NULL;
if (m_mapCachedProperties.Lookup(nCachedProp, pProperty))
return pProperty;
pProperty = m_pSchema->GetProperty(m_nClassCode, iPartId, iStateId, iPropId);
if (!pProperty)
{
m_mapCachedProperties.SetAt(nCachedProp, NULL);
return 0;
}
if (pProperty->propType != propType)
return 0;
m_mapCachedProperties.SetAt(nCachedProp , pProperty);
return pProperty;
}
CString CXTPSkinManagerClass::GetThemeString(int iPartId, int iStateId, int iPropId, LPCTSTR lpszDefault)
{
CXTPSkinManagerSchemaProperty* pProperty = GetProperty(XTP_SKINPROPERTY_STRING, iPartId, iStateId, iPropId);
if (!pProperty)
return lpszDefault;
return pProperty->lpszVal;
}
CRect CXTPSkinManagerClass::GetThemeRect(int iPartId, int iStateId, int iPropId, CRect rcDefault)
{
CXTPSkinManagerSchemaProperty* pProperty = GetProperty(XTP_SKINPROPERTY_RECT, iPartId, iStateId, iPropId);
if (!pProperty)
return rcDefault;
return pProperty->rcVal;
}
int CXTPSkinManagerClass::GetThemeInt(int iPartId, int iStateId, int iPropId, int nDefault)
{
CXTPSkinManagerSchemaProperty* pProperty = GetProperty(XTP_SKINPROPERTY_INT, iPartId, iStateId, iPropId);
if (!pProperty)
return nDefault;
return pProperty->iVal;
}
BOOL CXTPSkinManagerClass::GetThemeBool(int iPartId, int iStateId, int iPropId, BOOL bDefault)
{
CXTPSkinManagerSchemaProperty* pProperty = GetProperty(XTP_SKINPROPERTY_BOOL, iPartId, iStateId, iPropId);
if (!pProperty)
return bDefault;
return pProperty->bVal;
}
COLORREF CXTPSkinManagerClass::GetThemeColor(int iPartId, int iStateId, int iPropId, COLORREF clrDefault)
{
CXTPSkinManagerSchemaProperty* pProperty = GetProperty(XTP_SKINPROPERTY_COLOR, iPartId, iStateId, iPropId);
if (!pProperty)
return clrDefault;
COLORREF clrVal = pProperty->clrVal;
m_pSchema->GetSkinManager()->ApplyColorFilter(clrVal);
return clrVal;
}
int CXTPSkinManagerClass::GetThemeEnumValue(int iPartId, int iStateId, int iPropId, int nDefault)
{
CXTPSkinManagerSchemaProperty* pProperty = GetProperty(XTP_SKINPROPERTY_ENUM, iPartId, iStateId, iPropId);
if (!pProperty)
return nDefault;
return pProperty->iVal;
}
CSize CXTPSkinManagerClass::GetThemeSize(int iPartId, int iStateId, int iPropId, CSize szDefault)
{
CXTPSkinManagerSchemaProperty* pProperty = GetProperty(XTP_SKINPROPERTY_POSITION, iPartId, iStateId, iPropId);
if (!pProperty)
return szDefault;
return pProperty->szVal;
}
BOOL CXTPSkinManagerClass::DrawThemeBackground(CDC* pDC, int iPartId, int iStateId, const RECT *pRect)
{
return m_pSchema->DrawThemeBackground(pDC, this, iPartId, iStateId, pRect);
}
BOOL CXTPSkinManagerClass::GetThemePartSize(int iPartId, int iStateId, RECT *pRect, int eSize, SIZE* pSize)
{
if (GetThemeEnumValue(iPartId, iStateId, TMT_BGTYPE) != BT_IMAGEFILE)
return FALSE;
int nImageFile = (GetThemeEnumValue(iPartId, iStateId, TMT_IMAGESELECTTYPE) != IST_NONE) &&
(GetThemeEnumValue(iPartId, iStateId, TMT_GLYPHTYPE, GT_NONE) == GT_NONE) ?
TMT_IMAGEFILE1: TMT_IMAGEFILE;
CString strImageFile = GetThemeString(iPartId, iStateId, nImageFile);
if (strImageFile.IsEmpty())
{
if (nImageFile != TMT_IMAGEFILE1)
return FALSE;
strImageFile = GetThemeString(iPartId, iStateId, TMT_IMAGEFILE);
if (strImageFile.IsEmpty())
return FALSE;
}
CXTPSkinImage* pImage = GetImages()->LoadFile(m_pSchema->GetResourceFile(), strImageFile);
if (!pImage)
{
return FALSE;
}
int nImageCount = GetThemeInt(iPartId, iStateId, TMT_IMAGECOUNT, 1);
if (nImageCount < 1)
nImageCount = 1;
BOOL bHorizontalImageLayout = GetThemeEnumValue(iPartId, iStateId, TMT_IMAGELAYOUT, IL_HORIZONTAL) == IL_HORIZONTAL;
CSize sz(pImage->GetWidth(), pImage->GetHeight());
if (bHorizontalImageLayout) sz.cx /= nImageCount; else sz.cy /= nImageCount;
if (eSize == TS_TRUE)
{
*pSize = sz;
}
if (eSize == TS_DRAW)
{
if (GetThemeEnumValue(iPartId, iStateId, TMT_SIZINGTYPE, ST_STRETCH) == ST_TRUESIZE)
{
*pSize = sz;
return TRUE;
}
if (!pRect)
{
pSize->cy = 0;
pSize->cx = 0;
}
else
{
pSize->cy = pRect->bottom - pRect->top;
pSize->cx = pRect->right - pRect->left;
}
if (GetThemeBool(iPartId, iStateId, TMT_UNIFORMSIZING, FALSE))
{
pSize->cx = MulDiv(pSize->cy, sz.cx, sz.cy);
}
}
return TRUE;
}