www.pudn.com > TreePropSheetEx_Demo.zip > PropPageFrameDefault.cpp


/******************************************************************** 
* 
* Copyright (c) 2002 Sven Wiegand  
* 
* You can use this and modify this in any way you want, 
* BUT LEAVE THIS HEADER INTACT. 
* 
* Redistribution is appreciated. 
* 
* $Workfile:$ 
* $Revision: 1.4 $ 
* $Modtime:$ 
* $Author: ytkaczyk $ 
* 
* Revision History: 
*	$History:$ 
* 
*********************************************************************/ 
 
#include "stdafx.h" 
#include "PropPageFrameDefault.h" 
 
 
namespace TreePropSheet 
{ 
 
 
//uncomment the following line, if you don't have installed the 
//new platform SDK 
#define XPSUPPORT 
 
#ifdef XPSUPPORT 
#include  
#include  
#endif 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
//------------------------------------------------------------------- 
// class CThemeLib 
//------------------------------------------------------------------- 
 
#define THEMEAPITYPE(f)					typedef HRESULT (__stdcall *_##f) 
#define THEMEAPITYPE_(t, f)			typedef t (__stdcall *_##f) 
#define THEMEAPIPTR(f)					_##f m_p##f 
 
#ifdef XPSUPPORT 
	#define THEMECALL(f)						return (*m_p##f) 
	#define GETTHEMECALL(f)					m_p##f = (_##f)GetProcAddress(m_hThemeLib, #f) 
#else 
	void ThemeDummy(...) {ASSERT(FALSE);} 
	#define HTHEME									void* 
	#define TABP_PANE								0 
	#define THEMECALL(f)						return 0; ThemeDummy 
	#define GETTHEMECALL(f)					m_p##f = NULL 
#endif 
 
 
/** 
Helper class for loading the uxtheme DLL and providing their  
functions. 
 
One global object of this class exists. 
 
@author Sven Wiegand 
*/ 
class CThemeLib 
{ 
// construction/destruction 
public: 
	CThemeLib(); 
	~CThemeLib(); 
 
// operations 
public: 
	/** 
	Returns TRUE if the call wrappers are available, FALSE otherwise. 
	*/ 
	BOOL IsAvailable() const; 
 
// call wrappers 
public: 
	BOOL IsThemeActive()  
	{THEMECALL(IsThemeActive)();} 
 
	HTHEME OpenThemeData(HWND hwnd, LPCWSTR pszClassList)  
	{THEMECALL(OpenThemeData)(hwnd, pszClassList);} 
 
	HRESULT CloseThemeData(HTHEME hTheme)  
	{THEMECALL(CloseThemeData)(hTheme);} 
 
	HRESULT GetThemeBackgroundContentRect(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId,  const RECT *pBoundingRect, OUT RECT *pContentRect) 
	{THEMECALL(GetThemeBackgroundContentRect)(hTheme, hdc, iPartId, iStateId, pBoundingRect, pContentRect);} 
 
	HRESULT DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect) 
	{THEMECALL(DrawThemeBackground)(hTheme, hdc, iPartId, iStateId, pRect, pClipRect);} 
 
// function pointers 
private: 
#ifdef XPSUPPORT 
	THEMEAPITYPE_(BOOL, IsThemeActive)(); 
	THEMEAPIPTR(IsThemeActive); 
 
	THEMEAPITYPE_(HTHEME, OpenThemeData)(HWND hwnd, LPCWSTR pszClassList); 
	THEMEAPIPTR(OpenThemeData); 
 
	THEMEAPITYPE(CloseThemeData)(HTHEME hTheme); 
	THEMEAPIPTR(CloseThemeData); 
 
	THEMEAPITYPE(GetThemeBackgroundContentRect)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId,  const RECT *pBoundingRect, OUT RECT *pContentRect); 
	THEMEAPIPTR(GetThemeBackgroundContentRect); 
 
	THEMEAPITYPE(DrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect); 
	THEMEAPIPTR(DrawThemeBackground); 
#endif 
 
// properties 
private: 
	/** instance handle to the library or NULL. */ 
	HINSTANCE m_hThemeLib; 
}; 
 
/** 
One and only instance of CThemeLib. 
*/ 
static CThemeLib g_ThemeLib; 
 
 
CThemeLib::CThemeLib() 
:	m_hThemeLib(NULL) 
{ 
#ifdef XPSUPPORT 
	m_hThemeLib = LoadLibrary(_T("uxtheme.dll")); 
	if (!m_hThemeLib) 
		return; 
 
	GETTHEMECALL(IsThemeActive); 
	GETTHEMECALL(OpenThemeData); 
	GETTHEMECALL(CloseThemeData); 
	GETTHEMECALL(GetThemeBackgroundContentRect); 
	GETTHEMECALL(DrawThemeBackground); 
#endif 
} 
 
 
CThemeLib::~CThemeLib() 
{ 
	if (m_hThemeLib) 
		FreeLibrary(m_hThemeLib); 
} 
 
 
BOOL CThemeLib::IsAvailable() const 
{ 
	return m_hThemeLib!=NULL; 
} 
 
 
//------------------------------------------------------------------- 
// class CPropPageFrameDefault 
//------------------------------------------------------------------- 
 
BEGIN_MESSAGE_MAP(CPropPageFrameDefault, CWnd) 
	//{{AFX_MSG_MAP(CPropPageFrameDefault) 
	ON_WM_PAINT() 
	ON_WM_ERASEBKGND() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
CPropPageFrameDefault::CPropPageFrameDefault() 
{ 
} 
 
 
CPropPageFrameDefault::~CPropPageFrameDefault() 
{ 
	if (m_Images.GetSafeHandle()) 
		m_Images.DeleteImageList(); 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// Overridings 
 
BOOL CPropPageFrameDefault::Create(DWORD dwWindowStyle, const RECT &rect, CWnd *pwndParent, UINT nID) 
{ 
	return CWnd::Create( 
		AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, AfxGetApp()->LoadStandardCursor(IDC_ARROW), GetSysColorBrush(COLOR_3DFACE)), 
		_T("Page Frame"), 
		dwWindowStyle, rect, pwndParent, nID); 
} 
 
 
CWnd* CPropPageFrameDefault::GetWnd() 
{ 
	return static_cast(this); 
} 
 
 
void CPropPageFrameDefault::SetCaption(LPCTSTR lpszCaption, HICON hIcon /*= NULL*/) 
{ 
	CPropPageFrame::SetCaption(lpszCaption, hIcon); 
 
	// build image list 
	if (m_Images.GetSafeHandle()) 
		m_Images.DeleteImageList(); 
	if (hIcon) 
	{ 
		ICONINFO	ii; 
		if (!GetIconInfo(hIcon, &ii)) 
			return; 
 
		CBitmap	bmMask; 
		bmMask.Attach(ii.hbmMask); 
		if (ii.hbmColor) DeleteObject(ii.hbmColor); 
 
		BITMAP	bm; 
		bmMask.GetBitmap(&bm); 
 
		if (!m_Images.Create(bm.bmWidth, bm.bmHeight, ILC_COLOR32|ILC_MASK, 0, 1)) 
			return; 
 
		if (m_Images.Add(hIcon) == -1) 
			m_Images.DeleteImageList(); 
	} 
} 
 
 
CRect CPropPageFrameDefault::CalcMsgArea() 
{ 
	CRect	rect; 
	GetClientRect(rect); 
	if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive()) 
	{ 
		HTHEME	hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab"); 
		if (hTheme) 
		{ 
			CRect	rectContent; 
			CDC		*pDc = GetDC(); 
			g_ThemeLib.GetThemeBackgroundContentRect(hTheme, pDc->m_hDC, TABP_PANE, 0, rect, rectContent); 
			ReleaseDC(pDc); 
			g_ThemeLib.CloseThemeData(hTheme); 
			 
			if (GetShowCaption()) 
				rectContent.top = rect.top+GetCaptionHeight()+1; 
			rect = rectContent; 
		} 
	} 
	else if (GetShowCaption()) 
		rect.top+= GetCaptionHeight()+1; 
	 
	return rect; 
} 
 
 
CRect CPropPageFrameDefault::CalcCaptionArea() 
{ 
	CRect	rect; 
	GetClientRect(rect); 
	if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive()) 
	{ 
		HTHEME	hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab"); 
		if (hTheme) 
		{ 
			CRect	rectContent; 
			CDC		*pDc = GetDC(); 
			g_ThemeLib.GetThemeBackgroundContentRect(hTheme, pDc->m_hDC, TABP_PANE, 0, rect, rectContent); 
			ReleaseDC(pDc); 
			g_ThemeLib.CloseThemeData(hTheme); 
			 
			if (GetShowCaption()) 
				rectContent.bottom = rect.top+GetCaptionHeight(); 
			else 
				rectContent.bottom = rectContent.top; 
 
			rect = rectContent; 
		} 
	} 
	else 
	{ 
		if (GetShowCaption()) 
			rect.bottom = rect.top+GetCaptionHeight(); 
		else 
			rect.bottom = rect.top; 
	} 
 
	return rect; 
} 
 
void CPropPageFrameDefault::DrawCaption(CDC *pDc, CRect rect, LPCTSTR lpszCaption, HICON hIcon) 
{ 
	COLORREF	clrLeft = GetSysColor(COLOR_INACTIVECAPTION); 
	COLORREF	clrRight = pDc->GetPixel(rect.right-1, rect.top); 
	FillGradientRectH(pDc, rect, clrLeft, clrRight); 
 
	// draw icon 
	if (hIcon && m_Images.GetSafeHandle() && m_Images.GetImageCount() == 1) 
	{ 
		IMAGEINFO	ii; 
		m_Images.GetImageInfo(0, &ii); 
		CPoint		pt(3, rect.CenterPoint().y - (ii.rcImage.bottom-ii.rcImage.top)/2); 
		m_Images.Draw(pDc, 0, pt, ILD_TRANSPARENT); 
		rect.left+= (ii.rcImage.right-ii.rcImage.left) + 3; 
	} 
 
	// draw text 
	rect.left+= 2; 
 
	COLORREF	clrPrev = pDc->SetTextColor(GetSysColor(COLOR_CAPTIONTEXT)); 
	int				nBkStyle = pDc->SetBkMode(TRANSPARENT); 
	CFont			*pFont = (CFont*)pDc->SelectStockObject(SYSTEM_FONT); 
 
	pDc->DrawText(lpszCaption, rect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS); 
 
	pDc->SetTextColor(clrPrev); 
	pDc->SetBkMode(nBkStyle); 
	pDc->SelectObject(pFont); 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// Implementation helpers 
 
void CPropPageFrameDefault::FillGradientRectH(CDC *pDc, const RECT &rect, COLORREF clrLeft, COLORREF clrRight) 
{ 
	// pre calculation 
	int	nSteps = rect.right-rect.left; 
	int	nRRange = GetRValue(clrRight)-GetRValue(clrLeft); 
	int	nGRange = GetGValue(clrRight)-GetGValue(clrLeft); 
	int	nBRange = GetBValue(clrRight)-GetBValue(clrLeft); 
 
	double	dRStep = (double)nRRange/(double)nSteps; 
	double	dGStep = (double)nGRange/(double)nSteps; 
	double	dBStep = (double)nBRange/(double)nSteps; 
 
	double	dR = (double)GetRValue(clrLeft); 
	double	dG = (double)GetGValue(clrLeft); 
	double	dB = (double)GetBValue(clrLeft); 
 
	CPen	*pPrevPen = NULL; 
	for (int x = rect.left; x <= rect.right; ++x) 
	{ 
		CPen	Pen(PS_SOLID, 1, RGB((BYTE)dR, (BYTE)dG, (BYTE)dB)); 
		pPrevPen = pDc->SelectObject(&Pen); 
		pDc->MoveTo(x, rect.top); 
		pDc->LineTo(x, rect.bottom); 
		pDc->SelectObject(pPrevPen); 
		 
		dR+= dRStep; 
		dG+= dGStep; 
		dB+= dBStep; 
	} 
} 
 
 
///////////////////////////////////////////////////////////////////// 
// message handlers 
 
void CPropPageFrameDefault::OnPaint()  
{ 
	CPaintDC dc(this); 
	Draw(&dc);	 
} 
 
 
BOOL CPropPageFrameDefault::OnEraseBkgnd(CDC* pDC)  
{ 
	if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive()) 
	{ 
		HTHEME	hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab"); 
		if (hTheme) 
		{ 
			CRect	rect; 
			GetClientRect(rect); 
			g_ThemeLib.DrawThemeBackground(hTheme, pDC->m_hDC, TABP_PANE, 0, rect, NULL); 
 
			g_ThemeLib.CloseThemeData(hTheme); 
		} 
		return TRUE; 
	} 
	else 
	{ 
		return CWnd::OnEraseBkgnd(pDC); 
	} 
} 
 
 
 
} //namespace TreePropSheet