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++
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;
|
|
}
|