themed.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 616 行 · 第 1/2 页
CPP
616 行
// Themed.cpp: implementation of the CThemed class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Themed.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// theme function definitions
typedef BOOL (STDAPICALLTYPE *PFNISTHEMEACTIVE)();
typedef DWORD (STDAPICALLTYPE *PFNGETTHEMEAPPPROPERTIES)();
typedef HTHEME (STDAPICALLTYPE *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList);
typedef HRESULT (STDAPICALLTYPE *PFNCLOSETHEMEDATA)(HTHEME hTheme);
typedef HRESULT (STDAPICALLTYPE *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
const RECT *pRect, const RECT *pClipRect);
typedef HRESULT (STDAPICALLTYPE *PFNDRAWTHEMEPARENTBACKGROUND)(HWND hWnd, HDC hdc, RECT *pRect);
typedef HRESULT (STDAPICALLTYPE *PFNDRAWTHEMETEXT)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
LPCWSTR pszText, int iCharCount, DWORD dwTextFlags,
DWORD dwTextFlags2, const RECT *pRect);
typedef HRESULT (STDAPICALLTYPE *PFNDRAWTHEMEEDGE)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
const RECT *pDestRect, UINT uEdge, UINT uFlags,
RECT *pContentRect);
typedef HRESULT (STDAPICALLTYPE *PFNDRAWTHEMEICON)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
const RECT *pRect, HIMAGELIST himl, int iImageIndex);
typedef HRESULT (STDAPICALLTYPE *PFNDRAWTHEMEBORDER)(HTHEME hTheme, HDC hdc, int iStateId, const RECT *pRect);
typedef HRESULT (STDAPICALLTYPE *PFNGETTHEMEPARTSIZE)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
RECT *prc, THEMESIZE eSize, SIZE *psz);
typedef HRESULT (STDAPICALLTYPE *PFNGETTHEMETEXTEXTENT)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
LPCWSTR pszText, int iCharCount, DWORD dwTextFlags,
const RECT *pBoundingRect, RECT *pExtentRect);
typedef HRESULT (STDAPICALLTYPE *PFNGETTHEMECOLOR)(HTHEME hTheme, int iPartId, int iStateId, int iPropID,
COLORREF* pColor);
typedef HRESULT (STDAPICALLTYPE *PFNGETTHEMEBACKGROUNDCONTENTRECT)(HTHEME hTheme, HDC hdc, int iPartId,
int iStateId, LPCRECT pBoundingRect, LPRECT pContentRect);
#define WSTR(string) (LPCWSTR)COleVariant(string).bstrVal
#ifndef DFCS_TRANSPARENT
# define DFCS_TRANSPARENT 0x0800
# define DFCS_HOT 0x1000
# define DFC_POPUPMENU 5
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
HMODULE CThemed::s_hUxTheme = HMODULE(-1);
CThemed::CThemed(CWnd* pWnd, LPCTSTR szClassList) : m_hWnd(NULL), m_hTheme(NULL)
{
InitUxTheme();
if (pWnd && pWnd->GetSafeHwnd())
Open(pWnd, szClassList);
}
CThemed::~CThemed()
{
Close();
}
BOOL CThemed::InitUxTheme()
{
if (s_hUxTheme == HMODULE(-1)) // one time only
s_hUxTheme = LoadLibrary("UxTheme.dll");
return (NULL != s_hUxTheme);
}
BOOL CThemed::SupportsTheming(int nFlag)
{
return (IsThemeActive() && (GetAppThemeProperties() & nFlag));
}
BOOL CThemed::Open(const CWnd* pWnd, LPCTSTR szClassList)
{
if (pWnd && pWnd->GetSafeHwnd())
{
if (!s_hUxTheme)
{
s_hUxTheme = LoadLibrary("UxTheme.dll");
if (!s_hUxTheme)
return FALSE;
}
else
Close();
CString sClassList(szClassList);
if (sClassList.IsEmpty())
{
::GetClassName(pWnd->GetSafeHwnd(), sClassList.GetBuffer(128), 128);
sClassList.ReleaseBuffer();
}
m_hTheme = OpenThemeData(pWnd->GetSafeHwnd(), WSTR(sClassList));
m_hWnd = pWnd->GetSafeHwnd();
return (NULL != m_hTheme);
}
return FALSE;
}
BOOL CThemed::Close()
{
if (CloseThemeData(m_hTheme))
m_hTheme = NULL;
return (NULL == m_hTheme);
}
BOOL CThemed::AreControlsThemed()
{
return SupportsTheming(STAP_ALLOW_CONTROLS);
}
BOOL CThemed::IsNonClientThemed()
{
return SupportsTheming(STAP_ALLOW_NONCLIENT);
}
BOOL CThemed::IsWebContentThemed()
{
return SupportsTheming(STAP_ALLOW_WEBCONTENT);
}
// static
BOOL CThemed::DrawFrameControl(const CWnd* pWnd, CDC* pDC, LPRECT pRect, UINT nType, UINT nState, LPCRECT pClip)
{
CThemed th;
if (th.SupportsTheming(STAP_ALLOW_CONTROLS) && th.SupportsTheming(STAP_ALLOW_NONCLIENT))
{
// determine the appropriate class, part and state
CString sThClass;
int nThPart = 0, nThState = 0;
if (!th.GetThemeClassPartState(nType, nState, sThClass, nThPart, nThState))
return FALSE;
if (!th.Open(pWnd, sThClass))
return FALSE;
th.DrawParentBackground(pWnd, pDC, (LPRECT)(pClip ? pClip : pRect));
th.DrawBackground(pDC, nThPart, nThState, pRect, pClip);
return TRUE;
}
else
return pDC->DrawFrameControl(pRect, nType, nState);
}
BOOL CThemed::DrawEdge(const CWnd* pWnd, CDC* pDC, LPRECT pRect, UINT nType, UINT nState, UINT nEdge, UINT nFlags)
{
CThemed th;
if (th.SupportsTheming(STAP_ALLOW_CONTROLS) && th.SupportsTheming(STAP_ALLOW_NONCLIENT))
{
// determine the appropriate class, part and state
CString sThClass;
int nThPart = 0, nThState = 0;
if (!th.GetThemeClassPartState(nType, nState, sThClass, nThPart, nThState))
return FALSE;
if (!th.Open(pWnd, sThClass))
return FALSE;
th.DrawEdge(pDC, nThPart, nThState, pRect, nEdge, nFlags);
return TRUE;
}
else
return pDC->DrawFrameControl(pRect, nType, nState);
}
BOOL CThemed::DrawBackground(CDC* pDC, int nPart, int nState, const CRect& rect, LPCRECT prClip)
{
ASSERT (m_hTheme);
ASSERT_VALID (pDC);
return DrawThemeBackground(*pDC, nPart, nState, rect, prClip);
}
BOOL CThemed::DrawParentBackground(const CWnd* pWnd, CDC* pDC, LPRECT pRect)
{
ASSERT (m_hTheme);
ASSERT_VALID (pDC);
ASSERT_VALID (pWnd);
return DrawThemeParentBackground(*pWnd, *pDC, pRect);
}
BOOL CThemed::DrawText(CDC* pDC, int nPart, int nState, const CString& sText, DWORD dwTextFlags, DWORD dwTextFlags2, const CRect& rect)
{
ASSERT (m_hTheme);
ASSERT_VALID (pDC);
return DrawThemeText(*pDC, nPart, nState, WSTR(sText), sText.GetLength(), dwTextFlags, dwTextFlags2, rect);
}
BOOL CThemed::DrawEdge(CDC* pDC, int nPart, int nState, const CRect& rDest, UINT nEdge, UINT nFlags, LPRECT prContent)
{
ASSERT (m_hTheme);
ASSERT_VALID (pDC);
return DrawThemeEdge(*pDC, nPart, nState, rDest, nEdge, nFlags, prContent);
}
BOOL CThemed::DrawIcon(CDC* pDC, int nPart, int nState, const CRect& rect, const CImageList* pIL, int nImage)
{
ASSERT (m_hTheme);
ASSERT_VALID (pDC);
ASSERT_VALID (pIL);
return DrawThemeIcon(*pDC, nPart, nState, rect, *pIL, nImage);
}
BOOL CThemed::DrawBorder(CDC* pDC, int nState, const CRect& rect)
{
ASSERT (m_hTheme);
ASSERT_VALID (pDC);
return DrawThemeBorder(*pDC, nState, rect);
}
BOOL CThemed::GetSize(int nPart, int nState, CSize& size, BOOL bMin)
{
ASSERT (m_hTheme);
return GetThemePartSize(nPart, nState, bMin ? TS_MIN : TS_TRUE, &size);
}
BOOL CThemed::GetTextExtent(CDC* pDC, int nPart, int nState, const CString& sText, DWORD dwTextFlags, CRect& rExtent, LPCRECT prBounding)
{
ASSERT (m_hTheme);
return GetThemeTextExtent(pDC ? *pDC : (HDC)NULL, nPart, nState, WSTR(sText), sText.GetLength(), dwTextFlags, prBounding, rExtent);
}
BOOL CThemed::BuildImageList(CImageList& il, int nPart, const int nStates[], int nNumStates, COLORREF crMask)
{
ASSERT (!il.GetSafeHandle());
if (il.GetSafeHandle())
return FALSE;
if (!nNumStates)
return FALSE;
CSize size;
GetSize(nPart, 1, size);
// little cheat for check boxes
const UINT BORDER = (nPart == BP_CHECKBOX) ? 1 : 0;
// create a bitmap containing the required images
HWND hWnd = m_hWnd ? m_hWnd : GetDesktopWindow();
CClientDC dc(CWnd::FromHandle(hWnd));
CDC dcBack;
if (dcBack.CreateCompatibleDC(&dc))
{
CBitmap bitmap;
int nImWidth = (size.cx + 2 * BORDER);
int nImHeight = (size.cy + 2 * BORDER);
if (bitmap.CreateCompatibleBitmap(&dc, nImWidth * nNumStates, nImHeight))
{
CGdiObject* pOld = dcBack.SelectObject(&bitmap);
dcBack.FillSolidRect(0, 0, nImWidth * nNumStates, nImHeight, crMask);
CRect rState(BORDER, BORDER, size.cx + BORDER, size.cy + BORDER);
for (int nState = 0; nState < nNumStates; nState++)
{
if (nStates[nState] != -1)
DrawBackground(&dcBack, nPart, nStates[nState], rState);
// next state
rState.OffsetRect(nImWidth, 0);
}
dcBack.SelectObject(pOld);
// create imagelist
if (il.Create(nImWidth, nImHeight, ILC_COLOR32 | ILC_MASK, 0, 1))
il.Add(&bitmap, crMask);
}
}
return (il.GetSafeHandle() != NULL);
}
COLORREF CThemed::GetThemeColor(int nPart, int nState, int nProp)
{
ASSERT (m_hTheme);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?