📄 atltheme.h
字号:
HBRUSH GetThemeSysColorBrush(int nColorID) const
{
ATLASSERT(m_hTheme != NULL);
return ::GetThemeSysColorBrush(m_hTheme, nColorID);
}
int GetThemeSysSize(int nSizeID) const
{
ATLASSERT(m_hTheme != NULL);
return ::GetThemeSysSize(m_hTheme, nSizeID);
}
BOOL GetThemeSysBool(int nBoolID) const
{
ATLASSERT(m_hTheme != NULL);
return ::GetThemeSysBool(m_hTheme, nBoolID);
}
HRESULT GetThemeSysFont(int nFontID, LOGFONT* plf) const
{
ATLASSERT(m_hTheme != NULL);
return ::GetThemeSysFont(m_hTheme, nFontID, plf);
}
HRESULT GetThemeSysString(int nStringID, LPWSTR pszStringBuff, int cchMaxStringChars) const
{
ATLASSERT(m_hTheme != NULL);
return ::GetThemeSysString(m_hTheme, nStringID, pszStringBuff, cchMaxStringChars);
}
HRESULT GetThemeSysInt(int nIntID, int* pnValue) const
{
ATLASSERT(m_hTheme != NULL);
return ::GetThemeSysInt(m_hTheme, nIntID, pnValue);
}
};
__declspec(selectany) int CTheme::m_nIsThemingSupported = -1;
///////////////////////////////////////////////////////////////////////////////
// CThemeImpl - theme support implementation
// Derive from this class to implement window with theme support.
// Example:
// class CMyThemeWindow : public CWindowImpl<CMyThemeWindow>, public CThemeImpl<CMyThemeWindow>
// {
// ...
// BEGIN_MSG_MAP(CMyThemeWindow)
// CHAIN_MSG_MAP(CThemeImpl<CMyThemeWindow>)
// ...
// END_MSG_MAP()
// ...
// };
//
// If you set theme class list, the class will automaticaly open/close/reopen theme data.
// Helper for drawing theme client edge
inline bool AtlDrawThemeClientEdge(HTHEME hTheme, HWND hWnd, HRGN hRgnUpdate = NULL, HBRUSH hBrush = NULL, int nPartID = 0, int nStateID = 0)
{
ATLASSERT(hTheme != NULL);
ATLASSERT(::IsWindow(hWnd));
CWindowDC dc(hWnd);
if(dc.IsNull())
return false;
// Get border size
int cxBorder = GetSystemMetrics(SM_CXBORDER);
int cyBorder = GetSystemMetrics(SM_CYBORDER);
if(SUCCEEDED(::GetThemeInt(hTheme, nPartID, nStateID, TMT_SIZINGBORDERWIDTH, &cxBorder)))
cyBorder = cxBorder;
RECT rect;
::GetWindowRect(hWnd, &rect);
// Remove the client edge from the update region
int cxEdge = GetSystemMetrics(SM_CXEDGE);
int cyEdge = GetSystemMetrics(SM_CYEDGE);
::InflateRect(&rect, -cxEdge, -cyEdge);
CRgn rgn;
rgn.CreateRectRgnIndirect(&rect);
if(rgn.IsNull())
return false;
if(hRgnUpdate != NULL)
rgn.CombineRgn(hRgnUpdate, rgn, RGN_AND);
::OffsetRect(&rect, -rect.left, -rect.top);
::OffsetRect(&rect, cxEdge, cyEdge);
dc.ExcludeClipRect(&rect);
::InflateRect(&rect, cxEdge, cyEdge);
::DrawThemeBackground(hTheme, dc, nPartID, nStateID, &rect, NULL);
// Use background brush too, since theme border might not cover everything
if(cxBorder < cxEdge && cyBorder < cyEdge)
{
if(hBrush == NULL)
// need conditional code because types don't match in winuser.h
#ifdef _WIN64
hBrush = (HBRUSH)::GetClassLongPtr(hWnd, GCLP_HBRBACKGROUND);
#else
hBrush = (HBRUSH)UlongToPtr(::GetClassLongPtr(hWnd, GCLP_HBRBACKGROUND));
#endif
::InflateRect(&rect, cxBorder - cxEdge, cyBorder - cyEdge);
dc.FillRect(&rect, hBrush);
}
::DefWindowProc(hWnd, WM_NCPAINT, (WPARAM)rgn.m_hRgn, 0L);
return true;
}
// Theme extended styles
#define THEME_EX_3DCLIENTEDGE 0x00000001
#define THEME_EX_THEMECLIENTEDGE 0x00000002
template <class T, class TBase = CTheme>
class CThemeImpl : public TBase
{
public:
// Data members
LPWSTR m_lpstrThemeClassList;
DWORD m_dwExtendedStyle; // theme specific extended styles
// Constructor & destructor
CThemeImpl() : m_lpstrThemeClassList(NULL), m_dwExtendedStyle(0)
{ }
~CThemeImpl()
{
delete [] m_lpstrThemeClassList;
}
// Attributes
bool SetThemeClassList(LPCWSTR lpstrThemeClassList)
{
if(m_lpstrThemeClassList != NULL)
{
delete [] m_lpstrThemeClassList;
m_lpstrThemeClassList = NULL;
}
if(lpstrThemeClassList == NULL)
return true;
int cchLen = lstrlenW(lpstrThemeClassList) + 1;
ATLTRY(m_lpstrThemeClassList = new WCHAR[cchLen]);
if(m_lpstrThemeClassList == NULL)
return false;
bool bRet = (lstrcpyW(m_lpstrThemeClassList, lpstrThemeClassList) != NULL);
if(!bRet)
{
delete [] m_lpstrThemeClassList;
m_lpstrThemeClassList = NULL;
}
return bRet;
}
bool GetThemeClassList(LPWSTR lpstrThemeClassList, int cchListBuffer) const
{
int cchLen = lstrlenW(m_lpstrThemeClassList) + 1;
if(cchListBuffer < cchLen)
return false;
return (lstrcpyW(lpstrThemeClassList, m_lpstrThemeClassList) != NULL);
}
LPCWSTR GetThemeClassList() const
{
return m_lpstrThemeClassList;
}
DWORD SetThemeExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)
{
DWORD dwPrevStyle = m_dwExtendedStyle;
if(dwMask == 0)
m_dwExtendedStyle = dwExtendedStyle;
else
m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask);
return dwPrevStyle;
}
DWORD GetThemeExtendedStyle() const
{
return m_dwExtendedStyle;
}
// Operations
HTHEME OpenThemeData()
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
ATLASSERT(m_lpstrThemeClassList != NULL);
if(m_lpstrThemeClassList == NULL)
return NULL;
CloseThemeData();
return TBase::OpenThemeData(pT->m_hWnd, m_lpstrThemeClassList);
}
HTHEME OpenThemeData(LPCWSTR pszClassList)
{
if(!SetThemeClassList(pszClassList))
return NULL;
return OpenThemeData();
}
HRESULT SetWindowTheme(LPCWSTR pszSubAppName, LPCWSTR pszSubIDList)
{
if(!IsThemingSupported())
return S_FALSE;
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
return ::SetWindowTheme(pT->m_hWnd, pszSubAppName, pszSubIDList);
}
HTHEME GetWindowTheme() const
{
if(!IsThemingSupported())
return NULL;
const T* pT = static_cast<const T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
return ::GetWindowTheme(pT->m_hWnd);
}
HRESULT EnableThemeDialogTexture(DWORD dwFlags)
{
if(!IsThemingSupported())
return S_FALSE;
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
return ::EnableThemeDialogTexture(pT->m_hWnd, dwFlags);
}
BOOL IsThemeDialogTextureEnabled() const
{
if(!IsThemingSupported())
return FALSE;
const T* pT = static_cast<const T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
return ::IsThemeDialogTextureEnabled(pT->m_hWnd);
}
HRESULT DrawThemeParentBackground(HDC hDC, LPRECT pRect = NULL)
{
if(!IsThemingSupported())
return S_FALSE;
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
return ::DrawThemeParentBackground(pT->m_hWnd, hDC, pRect);
}
// Message map and handlers
// Note: If you handle any of these messages in your derived class,
// it is better to put CHAIN_MSG_MAP at the start of your message map.
BEGIN_MSG_MAP(CThemeImpl)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged)
MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint)
END_MSG_MAP()
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
if(m_lpstrThemeClassList != NULL)
OpenThemeData();
bHandled = FALSE;
return 1;
}
LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
CloseThemeData();
bHandled = FALSE;
return 1;
}
LRESULT OnThemeChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
CloseThemeData();
if(m_lpstrThemeClassList != NULL)
OpenThemeData();
bHandled = FALSE;
return 1;
}
LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
ATLASSERT(::IsWindow(pT->m_hWnd));
LRESULT lRet = 0;
bHandled = FALSE;
if(IsThemingSupported() && ((pT->GetExStyle() & WS_EX_CLIENTEDGE) != 0))
{
if((m_dwExtendedStyle & THEME_EX_3DCLIENTEDGE) != 0)
{
lRet = ::DefWindowProc(pT->m_hWnd, uMsg, wParam, lParam);
bHandled = TRUE;
}
else if((m_hTheme != NULL) && ((m_dwExtendedStyle & THEME_EX_THEMECLIENTEDGE) != 0))
{
HRGN hRgn = (wParam != 1) ? (HRGN)wParam : NULL;
if(pT->DrawThemeClientEdge(hRgn))
bHandled = TRUE;
}
}
return lRet;
}
// Drawing helper
bool DrawThemeClientEdge(HRGN hRgnUpdate)
{
T* pT = static_cast<T*>(this);
return AtlDrawThemeClientEdge(m_hTheme, pT->m_hWnd, hRgnUpdate, NULL, 0, 0);
}
};
}; //namespace WTL
#endif // __ATLTHEME_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -