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.

977 lines
23 KiB
C++

// XTPSkinObject.cpp: implementation of the CXTPSkinObject 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/XTPHookManager.h"
#include "Common/XTPSystemHelpers.h"
#include "Common/XTPColorManager.h"
#include "XTPSkinManager.h"
#include "XTPSkinManagerSchema.h"
#include "XTPSkinObject.h"
#include "XTPSkinManagerApiHook.h"
#include "XTPSkinObjectFrame.h"
#include "XTPSkinObjectButton.h"
#include "XTPSkinObjectEdit.h"
#include "XTPSkinObjectComboBox.h"
#include "XTPSkinObjectListView.h"
#include "XTPSkinObjectListBox.h"
#include "XTPSkinObjectTreeView.h"
#include "XTPSkinObjectScrollBar.h"
#include "XTPSkinObjectTab.h"
#include "XTPSkinObjectToolBar.h"
#include "XTPSkinObjectProgress.h"
#include "XTPSkinObjectSpin.h"
#include "XTPSkinObjectHeader.h"
#include "XTPSkinObjectTrackBar.h"
#include "XTPSkinObjectStatusBar.h"
#include "XTPSkinObjectMDI.h"
#include "XTPSkinObjectMenu.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CXTPSkinObjectPaintDC::CXTPSkinObjectPaintDC(CWnd* pWnd)
{
ASSERT_VALID(pWnd);
ASSERT(::IsWindow(pWnd->m_hWnd));
MSG& curMsg = AfxGetThreadState()->m_lastSentMsg;
m_ps.hdc = 0;
m_hWnd = pWnd->m_hWnd;
if (curMsg.wParam)
{
Attach((HDC)curMsg.wParam);
}
else
{
if (!Attach(::BeginPaint(m_hWnd, &m_ps)))
AfxThrowResourceException();
ASSERT(m_ps.hdc != NULL);
}
}
CXTPSkinObjectPaintDC::~CXTPSkinObjectPaintDC()
{
ASSERT(m_hDC != NULL);
ASSERT(::IsWindow(m_hWnd));
if (m_ps.hdc != NULL)
{
::EndPaint(m_hWnd, &m_ps);
}
Detach();
}
//////////////////////////////////////////////////////////////////////////
//
UINT CXTPSkinObject::m_nMsgUpdateSkinState = RegisterWindowMessage(_T("WM_SKINFRAMEWORK_UPDATESTATE"));
UINT CXTPSkinObject::m_nMsgQuerySkinState = RegisterWindowMessage(_T("WM_SKINFRAMEWORK_QUERYSTATE"));
CXTPSkinObject::CXTPSkinObject()
{
m_hWnd = 0;
m_pManager = NULL;
m_pOldWndProc = NULL;
m_bActiveX = FALSE;
m_bWindowsForms = FALSE;
m_bCustomDraw = FALSE;
m_bUnicode = FALSE;
m_bSystemWindowModule = FALSE;
m_bWindowProcAttached = FALSE;
m_bSetWindowProc = FALSE;
m_pSchema = NULL;
::InitializeCriticalSection(&m_csDescriptors);
}
CXTPSkinObject::~CXTPSkinObject()
{
m_hWnd = 0;
CMDTARGET_RELEASE(m_pSchema);
::DeleteCriticalSection(&m_csDescriptors);
}
#if (_MSC_VER <= 1200) && !defined(_WIN64)
#define GetWindowLongPtrW GetWindowLongW
#define GetWindowLongPtrA GetWindowLongA
#define SetWindowLongPtrW SetWindowLongW
#define SetWindowLongPtrA SetWindowLongA
#endif
void CXTPSkinObject::UnattachHook(BOOL bAuto)
{
if (m_bWindowProcAttached)
{
if (bAuto || !::SendMessage(m_hWnd, CXTPHookManager::m_nMsgSinkRemoved, (WPARAM)(LONG_PTR)CXTPSkinManager::HookWndProc, (LPARAM)(LONG_PTR)m_pOldWndProc))
{
if (m_bUnicode)
SetWindowLongPtrW(m_hWnd, GWLP_WNDPROC, (DWORD_PTR)m_pOldWndProc);
else
SetWindowLongPtrA(m_hWnd, GWLP_WNDPROC, (DWORD_PTR)m_pOldWndProc);
}
m_bWindowProcAttached = FALSE;
}
OnHookDetached(bAuto);
}
void CXTPSkinObject::OnFinalRelease()
{
delete this;
}
WNDPROC* CXTPSkinObject::GetSuperWndProcAddr()
{
return &m_pOldWndProc;
}
LRESULT CXTPSkinObject::DoDefWindowProc (UINT nMsg, WPARAM wParam, LPARAM lParam)
{
OnBeginHook(nMsg, xtpSkinDefaultHookMessage, 0, 0);
LRESULT lResult = ::DefWindowProc(m_hWnd, nMsg, wParam, lParam);
OnEndHook();
return lResult;
}
LRESULT CXTPSkinObject::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
if (m_arrDescriptors.IsEmpty())
return ::CallWindowProc(m_pOldWndProc, m_hWnd, nMsg, wParam, lParam);
DEFWINDOW_DESCRIPTIOR& des = m_arrDescriptors.GetHead();
if (des.defProc == xtpSkinDefaultHookMessage)
return ::CallWindowProc(m_pOldWndProc, m_hWnd, nMsg, wParam, lParam);
if (des.defProc == xtpSkinDefaultCallWindowProc)
{
ASSERT(des.lpPrev);
ASSERT(des.defProcAddr);
typedef LRESULT (WINAPI* LPFNCALLWINDOWPROC)(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
return ((LPFNCALLWINDOWPROC)des.defProcAddr)((WNDPROC)des.lpPrev, m_hWnd, nMsg, wParam, lParam);
}
if (des.defProc == xtpSkinDefaultDefWindowProc || des.defProc == xtpSkinDefaultDefMDIChildProc || des.defProc == xtpSkinDefaultDefDlgProc)
{
ASSERT(des.defProcAddr);
typedef LRESULT (WINAPI* LPFNDEFWINDOWPROC)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
return ((LPFNDEFWINDOWPROC)des.defProcAddr)(m_hWnd, nMsg, wParam, lParam);
}
if (des.defProc == xtpSkinDefaultDefFrameProc)
{
ASSERT(des.defProcAddr);
typedef LRESULT (WINAPI* LPFNDEFWINDOWPROC)(HWND hWnd, HWND hWndMDIClient, UINT Msg, WPARAM wParam, LPARAM lParam);
return ((LPFNDEFWINDOWPROC)des.defProcAddr)(m_hWnd, (HWND)des.lpPrev, nMsg, wParam, lParam);
}
return 0;
}
void CXTPSkinObject::SetWindowProc()
{
if (m_bWindowProcAttached)
return;
if (m_bUnicode)
{
m_pOldWndProc = (WNDPROC)GetWindowLongPtrW(m_hWnd, GWLP_WNDPROC);
}
else
{
m_pOldWndProc = (WNDPROC)GetWindowLongPtrA(m_hWnd, GWLP_WNDPROC);
}
if (m_bUnicode)
{
SetWindowLongPtrW(m_hWnd, GWLP_WNDPROC, (DWORD_PTR)CXTPSkinManager::HookWndProc);
}
else
{
SetWindowLongPtrA(m_hWnd, GWLP_WNDPROC, (DWORD_PTR)CXTPSkinManager::HookWndProc);
}
m_bWindowProcAttached = TRUE;
}
void CXTPSkinObject::AttachHook(HWND hWnd, LPCREATESTRUCT lpcs, BOOL bAuto)
{
m_hWnd = hWnd;
m_bUnicode = IsWindowUnicode(hWnd);
if (m_bUnicode)
{
m_pOldWndProc = (WNDPROC)GetWindowLongPtrW(hWnd, GWLP_WNDPROC);
}
else
{
m_pOldWndProc = (WNDPROC)GetWindowLongPtrA(hWnd, GWLP_WNDPROC);
}
if (CXTPSkinManagerApiHook::IsSystemWindowModule(m_pOldWndProc))
{
m_bSystemWindowModule = TRUE;
}
if (m_pManager->IsWin9x() && ((DWORD_PTR)m_pOldWndProc > (DWORD_PTR)0x70000000) && (m_pOldWndProc != CXTPSkinManagerApiFunction::sm_pfnAfxWndProc))
{
m_bSystemWindowModule = TRUE;
}
if (m_bSystemWindowModule || m_bSetWindowProc)
{
SetWindowProc();
}
OnHookAttached(lpcs, bAuto);
}
CXTPSkinManagerClass* CXTPSkinObject::GetSkinClass() const
{
return GetSkinManager()->GetSkinClass(this, m_strClassName);
}
CXTPSkinManagerMetrics* CXTPSkinObject::GetMetrics() const
{
CXTPSkinManagerSchema* pSchema = GetSchema();
return pSchema ? pSchema->GetMetrics() : NULL;
}
CXTPSkinManagerSchema* CXTPSkinObject::GetSchema() const
{
return m_pSchema ? m_pSchema : GetSkinManager()->GetSchema();
}
COLORREF CXTPSkinObject::GetColor(int nIndex) const
{
CXTPSkinManagerMetrics* pMetrics = GetMetrics();
return pMetrics ? pMetrics->GetColor(nIndex) : GetXtremeColor(nIndex);
}
void CXTPSkinObject::OnSkinChanged(BOOL /*bPrevState*/, BOOL /*bNewState*/)
{
RefreshMetrics();
}
void CXTPSkinObject::OnHookAttached(LPCREATESTRUCT /*lpcs*/, BOOL bAuto)
{
m_bCustomDraw = CWnd::FromHandlePermanent(m_hWnd) ? SendMessage(m_nMsgQuerySkinState) != 0 : FALSE;
if (!bAuto) RefreshMetrics();
}
void CXTPSkinObject::OnHookDetached(BOOL /*bAuto*/)
{
}
void CXTPSkinObject::RefreshMetrics()
{
}
BOOL CXTPSkinObject::IsDefWindowProcAvail(int nMessage) const
{
if (nMessage == WM_TIMER)
return FALSE;
if (m_bSystemWindowModule)
return FALSE;
if (m_bActiveX && !m_bSetWindowProc)
return FALSE;
return TRUE;
}
BOOL CXTPSkinObject::PreHookMessage(UINT nMessage)
{
if (nMessage == WM_SETCURSOR || nMessage == WM_NOTIFY|| nMessage == WM_COMMAND || nMessage == WM_ACTIVATE)
return TRUE;
if (nMessage == m_nMsgUpdateSkinState)
{
m_bCustomDraw = SendMessage(m_nMsgQuerySkinState) != 0;
}
return FALSE;
}
BOOL CXTPSkinObject::OnHookDefWindowProc(UINT nMessage, WPARAM& wParam, LPARAM& lParam, LRESULT& lResult)
{
if (PreHookMessage(nMessage))
return FALSE;
if (nMessage == m_nMsgQuerySkinState)
{
lResult = 0;
return TRUE;
}
if (OnWndMsg(nMessage, wParam, lParam, &lResult))
{
return TRUE;
}
return FALSE;
}
BOOL CXTPSkinObject::OnHookMessage(UINT nMessage, WPARAM& wParam, LPARAM& lParam, LRESULT& lResult)
{
if (PreHookMessage(nMessage))
return FALSE;
if (IsDefWindowProcAvail(nMessage))
return FALSE;
if (OnWndMsg(nMessage, wParam, lParam, &lResult))
{
return TRUE;
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
// CXTPSkinManager
void CXTPSkinManager::ApplyWindow(HWND hWnd)
{
if (Lookup(hWnd))
return;
TCHAR lpszClassName[50];
GetClassName(hWnd, lpszClassName, 50);
CREATESTRUCT cs;
ZeroMemory(&cs, sizeof(cs));
cs.dwExStyle = (DWORD)GetWindowLongPtr(hWnd, GWL_EXSTYLE);
cs.style = (LONG)GetWindowLongPtr(hWnd, GWL_STYLE);
cs.hwndParent = ::GetParent(hWnd);
cs.lpszClass = lpszClassName;
CXTPSkinObject* pSkinObject = SetHook(hWnd, lpszClassName, &cs, FALSE);
if (pSkinObject)
{
pSkinObject->OnSkinChanged(FALSE, m_bEnabled);
}
if (pSkinObject && pSkinObject->m_strClassName == _T("COMBOBOX"))
{
HWND hWndList = CXTPSkinObjectComboBox::GetComboListBox(hWnd);
if (hWndList)
{
ApplyWindow(hWndList);
}
}
hWnd = ::GetWindow(hWnd, GW_CHILD);
while (hWnd)
{
ApplyWindow(hWnd);
hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
}
}
BOOL CALLBACK CXTPSkinManager::EnumWindowsProcNetBroadcast(HWND hWnd, LPARAM /*lParam*/)
{
DWORD dwProcessId = 0;
if (GetWindowThreadProcessId(hWnd, &dwProcessId) && dwProcessId == GetCurrentProcessId())
{
::PostMessage(hWnd, WM_SYSCOLORCHANGE, 0, 0);
}
return TRUE;
}
void CXTPSkinManager::OnSkinChanged(BOOL bPrevState, BOOL bNewState)
{
CWnd* pWnd = AfxGetMainWnd();
if (pWnd) pWnd->SendMessage(WM_SYSCOLORCHANGE);
HWND hWnd;
POSITION pos = m_mapObjects.GetStartPosition();
CXTPSkinObject* pSink;
EnumWindows(EnumWindowsProcNetBroadcast, 0);
while (pos)
{
m_mapObjects.GetNextAssoc(pos, hWnd, pSink);
if (::IsWindow(hWnd))
{
pSink->OnSkinChanged(bPrevState, bNewState);
}
else
{
Remove(hWnd);
}
}
}
CXTPSkinObject* CXTPSkinManager::Lookup(HWND hWnd)
{
CXTPLockGuard lock(m_csObjects);
CXTPSkinObject* pSink;
if (m_mapObjects.Lookup(hWnd, pSink))
return pSink;
return NULL;
}
#ifndef OBJID_WINDOW
#define OBJID_WINDOW 0x00000000
#endif
#ifndef EVENT_OBJECT_REORDER
#define EVENT_OBJECT_REORDER 0x8004
#endif
void CALLBACK CXTPSkinManager::WinEventProc(HWINEVENTHOOK /*hWinEventHook*/,
DWORD event, HWND hWnd, LONG idObject, LONG /*idChild*/, DWORD /*dwEventThread*/, DWORD /*dwmsEventTime*/)
{
if (event == EVENT_OBJECT_REORDER && idObject == OBJID_WINDOW && (XTPSkinManager()->GetApplyOptions() & xtpSkinApplyFrame)
&& XTPSkinManager()->IsEnabled())
{
CXTPSkinObjectFrame* pFrame = (CXTPSkinObjectFrame*)XTPSkinManager()->Lookup(hWnd);
if (pFrame && ::IsWindow(hWnd))
{
DWORD dwStyle = pFrame->GetStyle();
DWORD dwStyleRemove = (WS_CAPTION | WS_VSCROLL | WS_HSCROLL);
if (dwStyle & dwStyleRemove)
{
pFrame->SetTimer(XTP_TID_REFRESHFRAME, 1000, &CXTPSkinObjectFrame::OnTimerInternal);
}
}
}
return;
}
BOOL CXTPSkinObject::IsSkinEnabled() const
{
return !m_bCustomDraw && m_hWnd && m_pManager->IsEnabled();
}
#define PSH_WIZARD97IE4 0x00002000
#define PSH_WIZARD97IE5 0x01000000
#ifndef DWLP_USER
#define DWLP_USER 8
#endif
AFX_INLINE BOOL IsTabPage(LPCREATESTRUCT lpcs)
{
if (!lpcs || !lpcs->hwndParent)
return FALSE;
if (!((lpcs->style & DS_CONTROL) && (lpcs->style & WS_CHILD)))
return FALSE;
CXTPSkinObjectFrame* pParent = (CXTPSkinObjectFrame*)XTPSkinManager()->Lookup(lpcs->hwndParent);
if (pParent && pParent->m_dwDialogTexture == ETDT_ENABLETAB)
return TRUE;
HWND hwndTabControl = (HWND)::SendMessage(lpcs->hwndParent, PSM_GETTABCONTROL, 0, 0);
if (!hwndTabControl || !::IsWindow(hwndTabControl))
return FALSE;
HWND* ppd = (HWND*)GetWindowLongPtr(lpcs->hwndParent, DWLP_USER);
if (!ppd || *ppd != lpcs->hwndParent)
return FALSE;
PROPSHEETHEADER* psh = (PROPSHEETHEADER*)(ppd + 1);
if (!psh)
return FALSE;
if ((psh->dwFlags & (PSH_WIZARD | PSH_WIZARD97IE4 | PSH_WIZARD97IE5)) != 0)
return FALSE;
return TRUE;
}
CXTPSkinObject* CXTPSkinManager::SetHook(HWND hWnd, LPCTSTR lpszClassName, LPCREATESTRUCT lpcs, BOOL bAuto)
{
if (_tcscmp(lpszClassName, _T("tooltips_class32")) == 0)
return NULL;
if (_tcsicmp(lpszClassName, _T("IME")) == 0)
return NULL;
if(_tcsicmp(lpszClassName,_T("CicMarshalWndClass")) == 0)
return NULL;
if(_tcsicmp(lpszClassName,_T("MSCTFIME UI")) == 0)
return NULL;
if (_tcsicmp(lpszClassName, _T("WorkerW")) == 0)
return NULL;
if (_tcsicmp(lpszClassName, _T("SHELLDLL_DefView")) == 0)
return NULL;
CXTPSkinObject* pSink = NULL;
if (pSink == NULL && _tcsstr(lpszClassName, _T("WindowsForms")) != NULL)
{
CString strClass(lpszClassName);
int nClassNameStart = strClass.Find(_T('.'));
int nClassNameEnd = strClass.Find(_T('.'), nClassNameStart + 1);
if (nClassNameStart != -1 && nClassNameEnd != -1 && nClassNameEnd != nClassNameStart)
{
strClass = strClass.Mid(nClassNameStart + 1, nClassNameEnd - nClassNameStart - 1);
CXTPSkinObjectClassInfo* pInfo = m_pClassMap->Lookup(strClass);
if (pInfo)
{
pSink = pInfo->CreateObject(lpszClassName, lpcs);
}
}
if (pSink == NULL)
{
pSink = new CXTPSkinObjectApplicationFrame();
}
pSink->m_bWindowsForms = TRUE;
}
if (pSink == NULL)
{
CXTPSkinObjectClassInfo* pInfo = m_pClassMap->Lookup(lpszClassName);
if (pInfo)
{
pSink = pInfo->CreateObject(lpszClassName, lpcs);
}
else
{
if (_tcsstr(lpszClassName, _T("Internet Explorer")) != NULL)
return NULL;
if (_tcsstr(lpszClassName, _T("OleMainThread")) != NULL)
return NULL;
pSink = new CXTPSkinObjectApplicationFrame();
}
}
if (pSink && _tcscmp(lpszClassName, _T("#32770")) == 0)
{
((CXTPSkinObjectFrame*)pSink)->m_dwDialogTexture = IsTabPage(lpcs) ? ETDT_ENABLETAB : ETDT_ENABLE;
}
if (pSink)
{
pSink->m_pManager = this;
{
CXTPLockGuard lock(m_csObjects);
m_mapObjects[hWnd] = pSink;
}
pSink->AttachHook(hWnd, lpcs, bAuto);
}
return pSink;
}
void CXTPSkinManager::Remove(HWND hWnd)
{
Remove(hWnd, FALSE);
}
void CXTPSkinManager::Remove(HWND hWnd, BOOL bAuto)
{
CXTPSkinObject* pSink = Lookup(hWnd);
if (pSink)
{
{
CXTPLockGuard lock(m_csObjects);
m_mapObjects.RemoveKey(hWnd);
}
pSink->UnattachHook(bAuto);
#ifdef _AFXDLL
pSink->m_pModuleState = AfxGetModuleState();
#endif
pSink->InternalRelease();
}
}
void CXTPSkinManager::RemoveAll(BOOL bUnattach)
{
HWND hWnd;
POSITION pos = m_mapObjects.GetStartPosition();
CXTPSkinObject* pSink;
while (pos)
{
m_mapObjects.GetNextAssoc(pos, hWnd, pSink);
if (bUnattach) pSink->UnattachHook(FALSE);
#ifdef _AFXDLL
pSink->m_pModuleState = AfxGetModuleState();
#endif
pSink->InternalRelease();
}
CXTPLockGuard lock(m_csObjects);
m_mapObjects.RemoveAll();
}
void CXTPSkinObject::OnBeginHook(UINT nMessage, XTPSkinDefaultProc defProc, PROC defProcAddr, LPVOID defProcPrevWndFunc)
{
InternalAddRef();
CXTPLockGuard lock(m_csDescriptors);
DEFWINDOW_DESCRIPTIOR des;
des.defProc = defProc;
des.nMessage = nMessage;
des.defProcAddr = defProcAddr;
des.lpPrev = defProcPrevWndFunc;
m_arrDescriptors.AddHead(des);
}
void CXTPSkinObject::OnEndHook()
{
{
CXTPLockGuard lock(m_csDescriptors);
m_arrDescriptors.RemoveHead();
}
InternalRelease();
}
UINT CXTPSkinObject::GetHeadMessage()
{
CXTPLockGuard lock(m_csDescriptors);
if (!m_arrDescriptors.IsEmpty())
{
return m_arrDescriptors.GetHead().nMessage;
}
return WM_NULL;
}
LRESULT CALLBACK CXTPSkinManager::DoCallWindowProc(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return CXTPSkinManagerApiHook::CallWindowProcOrig(lpPrevWndFunc, hWnd, Msg, wParam, lParam);
}
LRESULT CALLBACK CXTPSkinManager::HookWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// Get hook object for this window. Get from hook map
CXTPSkinObject* pSink = XTPSkinManager()->Lookup(hWnd);
if (!pSink)
return 0;
LRESULT lResult = 0;
WNDPROC wndProc = pSink->m_pOldWndProc;
if (!pSink->GetSkinManager()->m_bEnabled)
{
if (message == WM_NCDESTROY)
{
pSink->GetSkinManager()->Remove(hWnd, TRUE);
}
return ::CallWindowProc(wndProc, hWnd, message, wParam, lParam);
}
MSG& curMsg = AfxGetThreadState()->m_lastSentMsg;
MSG oldMsg = curMsg;
curMsg.hwnd = hWnd;
curMsg.message = message;
curMsg.wParam = wParam;
curMsg.lParam = lParam;
BOOL bCallWindowProc = TRUE;
// Window is being destroyed: unhook all hooks (for this window)
// and pass message to orginal window proc
if (message == WM_NCDESTROY)
{
pSink->GetSkinManager()->Remove(hWnd, TRUE);
}
// pass to message hook
else if (!pSink->m_bCustomDraw || message == CXTPSkinObject::m_nMsgUpdateSkinState)
{
pSink->OnBeginHook(message, xtpSkinDefaultHookMessage, 0, 0);
if (pSink->OnHookMessage(message, wParam, lParam, lResult))
{
bCallWindowProc = FALSE;
}
pSink->OnEndHook();
}
if (bCallWindowProc)
{
lResult = DoCallWindowProc(wndProc, hWnd, message, wParam, lParam);
}
curMsg = oldMsg;
return lResult;
}
//////////////////////////////////////////////////////////////////////////
// CXTPSkinObjectClassInfo
CXTPSkinObjectClassInfo::CXTPSkinObjectClassInfo(CRuntimeClass* pClass)
{
m_pMap = NULL;
m_pClass = pClass;
}
CXTPSkinObject* CXTPSkinObjectClassInfo::CreateObject(LPCTSTR /*lpszClassName*/, LPCREATESTRUCT /*lpcs*/)
{
if (!m_pClass)
return NULL;
return (CXTPSkinObject*)m_pClass->CreateObject();
}
void CXTPSkinObjectClassInfo::AddClass(LPCTSTR lpszClassName)
{
m_pMap->AddClass(lpszClassName, this);
}
void CXTPSkinObjectClassInfo::Remove()
{
m_pMap->RemoveClass(this);
}
//////////////////////////////////////////////////////////////////////////
// CXTPSkinObjectClassMap
CXTPSkinObjectClassMap::CXTPSkinObjectClassMap()
{
}
CXTPSkinObjectClassMap::~CXTPSkinObjectClassMap()
{
RemoveAll();
}
#define RUNTIME_CLASS_INFO(x) new CXTPSkinObjectClassInfo(RUNTIME_CLASS(x))
#define RUNTIME_CLASS_INFOACTIVEX(x) new CXTPSkinObjectClassInfoActiveX(RUNTIME_CLASS(x), FALSE, FALSE)
#define RUNTIME_CLASS_INFOSYSACTIVEX(x) new CXTPSkinObjectClassInfoActiveX(RUNTIME_CLASS(x), TRUE, FALSE)
#define RUNTIME_CLASS_INFOSYSACTIVEX2(x) new CXTPSkinObjectClassInfoActiveX(RUNTIME_CLASS(x), FALSE, TRUE)
void CXTPSkinObjectClassMap::AddStandardClasses()
{
AddClass(_T("Button"), RUNTIME_CLASS_INFO(CXTPSkinObjectButton));
AddClass(_T("ComboBox"), RUNTIME_CLASS_INFO(CXTPSkinObjectComboBox));
AddClass(_T("Edit"), RUNTIME_CLASS_INFO(CXTPSkinObjectEdit));
AddClass(_T("ListBox"), RUNTIME_CLASS_INFO(CXTPSkinObjectListBox));
AddClass(_T("SysDateTimePick32"), RUNTIME_CLASS_INFO(CXTPSkinObjectDateTime));
AddClass(_T("SysMonthCal32"), RUNTIME_CLASS_INFO(CXTPSkinObjectMonthCal));
AddClass(_T("ScrollBar"), RUNTIME_CLASS_INFO(CXTPSkinObjectScrollBar));
AddClass(_T("SysListView32"), RUNTIME_CLASS_INFO(CXTPSkinObjectListView));
AddClass(_T("SysHeader32"), RUNTIME_CLASS_INFO(CXTPSkinObjectHeader));
AddClass(_T("msctls_statusbar32"), RUNTIME_CLASS_INFO(CXTPSkinObjectStatusBar));
AddClass(_T("SysTreeView32"), RUNTIME_CLASS_INFO(CXTPSkinObjectTreeView));
AddClass(_T("msctls_progress32"), RUNTIME_CLASS_INFO(CXTPSkinObjectProgress));
AddClass(_T("msctls_trackbar32"), RUNTIME_CLASS_INFO(CXTPSkinObjectTrackBar));
AddClass(_T("SysTabControl32"), RUNTIME_CLASS_INFO(CXTPSkinObjectTab));
AddClass(_T("MDIClient"), RUNTIME_CLASS_INFO(CXTPSkinObjectMDIClient));
AddClass(_T("msctls_updown32"), RUNTIME_CLASS_INFO(CXTPSkinObjectSpin));
AddClass(_T("ToolbarWindow32"), RUNTIME_CLASS_INFO(CXTPSkinObjectToolBar));
AddSynonymClass(_T("SysIPAddress32"), _T("Edit"));
AddSynonymClass(_T("msctls_hotkey32"), _T("Edit"));
AddSynonymClass(_T("ComboLBox"), _T("ListBox"));
AddSynonymClass(_T("ATL:ScrollBar"), _T("ScrollBar"));
AddSynonymClass(_T("TButton"), _T("Button"));
AddSynonymClass(_T("TEdit"), _T("Edit"));
AddSynonymClass(_T("TMemo"), _T("Edit"));
AddSynonymClass(_T("TNewProgressBar"), _T("msctls_progress32"));
AddSynonymClass(_T("TRichEditViewer"), _T("Edit"));
AddSynonymClass(_T("TRadioButton"), _T("Button"));
AddSynonymClass(_T("TCheckBox"), _T("Button"));
AddSynonymClass(_T("TComboBox"), _T("ComboBox"));
AddSynonymClass(_T("TGroupBox"), _T("Button"));
AddSynonymClass(_T("TScrollBar"), _T("ScrollBar"));
AddSynonymClass(_T("TProgressBar"), _T("msctls_progress32"));
AddSynonymClass(_T("TTrackBar"), _T("msctls_trackbar32"));
AddSynonymClass(_T("TTabControl"), _T("SysTabControl32"));
AddSynonymClass(_T("TTreeView"), _T("SysTreeView32"));
AddSynonymClass(_T("TListView"), _T("SysListView32"));
AddSynonymClass(_T("TListBox"), _T("ListBox"));
AddClass(_T("#32768"), new CXTPSkinObjectClassInfo(NULL));
AddClass(_T("XTPSkinManagerMenu"), new CXTPSkinObjectClassInfo(NULL));
AddClass(_T("SysPager"), new CXTPSkinObjectClassInfo(NULL));
}
void CXTPSkinObjectClassMap::AddSynonymClass(LPCTSTR lpszClassNameSynonym, LPCTSTR lpszClassName)
{
if (Lookup(lpszClassNameSynonym))
return;
if (lpszClassName == NULL || *lpszClassName == 0)
{
AddClass(lpszClassNameSynonym, new CXTPSkinObjectClassInfo(NULL));
return;
}
CXTPSkinObjectClassInfo* pInfo = Lookup(lpszClassName);
ASSERT(pInfo);
if (!pInfo)
return;
AddClass(lpszClassNameSynonym, pInfo);
}
CXTPSkinObjectClassInfo* CXTPSkinObjectClassMap::AddClass(LPCTSTR lpszClassName, CXTPSkinObjectClassInfo* pInfo)
{
CString strClassName(lpszClassName);
strClassName.MakeUpper();
ASSERT(Lookup(strClassName) == NULL);
m_mapInfo.SetAt(strClassName, pInfo);
if (pInfo->m_pMap == 0)
{
pInfo->m_pMap = this;
}
else
{
ASSERT(pInfo->m_pMap == this);
pInfo->InternalAddRef();
}
return pInfo;
}
void CXTPSkinObjectClassMap::RemoveClass(LPCTSTR lpszClassName)
{
CString strClassName(lpszClassName);
strClassName.MakeUpper();
CXTPSkinObjectClassInfo* pInfo = Lookup(strClassName);
if (!pInfo)
return;
m_mapInfo.RemoveKey(strClassName);
pInfo->InternalRelease();
}
void CXTPSkinObjectClassMap::RemoveClass(CXTPSkinObjectClassInfo* pInfo)
{
POSITION pos = m_mapInfo.GetStartPosition();
CString strClassName;
void* p;
while (pos)
{
m_mapInfo.GetNextAssoc(pos, strClassName, p);
if (p == pInfo)
{
m_mapInfo.RemoveKey(strClassName);
pInfo->InternalRelease();
}
}
}
void CXTPSkinObjectClassMap::RemoveAll()
{
POSITION pos = m_mapInfo.GetStartPosition();
CString strClassName;
CXTPSkinObjectClassInfo* pInfo;
while (pos)
{
m_mapInfo.GetNextAssoc(pos, strClassName, (void*&)pInfo);
pInfo->InternalRelease();
}
m_mapInfo.RemoveAll();
}
CXTPSkinObjectClassInfo* CXTPSkinObjectClassMap::Lookup(LPCTSTR lpszClassName)
{
CString strClassName(lpszClassName);
strClassName.MakeUpper();
void* pInfo;
if (!m_mapInfo.Lookup(strClassName, pInfo))
return NULL;
return (CXTPSkinObjectClassInfo*)pInfo;
}