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