介绍
如果喜欢Vista
的玻璃
玻璃效果,并想在(现有或新的)WTL
应用中启用它,则本文可能有用.
本地API
方便投入使用
,玻璃
名字空间允许简单调整现有软件
.
参考
此处使用的本地API
的主要文档是MSDN
的桌面窗管部分.
旅游
对支持玻璃
的应用
使用WTLAppWizard
创建简单FirstTest
应用:只需在向导
的第一个屏幕
上点击下一步
,取选"使用视图
"框,然后点击"完成
".现在搞一些简单的更改
,总是要完成这些步骤
:
1,更改stdafx.h
中的常数:
cpp
//`stdafx.h`:标准系统包含文件,或常用但不经常更改的项目
#pragma once
//更改这些值以使用不同版本
#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
#define _WIN32_IE 0x0700
#define _RICHEDIT_VER 0x0200
//...
2,从WtlAero.zip
提取toolbar.bmp
,到FirstTest\res\
项目目录中.
3,从WtlAero.zip
提取WtlAero.h
到FirstTest\
项目目录中,并更改FirstTest.cpp
以包含它:
cpp
//`FirstTest.cpp`:`FirstTest.exe`的主源文件
#include "stdafx.h"
#include<atlframe.h>
#include <atlctrls.h>
#include <atldlgs.h>
#include <atlctrlw.h>
#include "WtlAero.h"//..
#include "resource.h"
//...
4,在MainFrm.h
中,按它们的aero::
对应项更改CFrameWindowImpl
和m_CmdBar
的定义:
cpp
//`MainFrm.h:CMainFrame`类的接口
#pragma once
class CMainFrame : public aero::CFrameWindowImpl<CMainFrame>,
public CUpdateUI<CMainFrame>,
public CMessageFilter, public CIdleHandler
{
public:
DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)
CFirstTestView m_view;
aero::CCommandBarCtrl m_CmdBar;//..
//...
5,更改消息映射
中的基类定义
,并在OnCreate()
处理器前移动它
:
cpp
BEGIN_MSG_MAP(CMainFrame)
CHAIN_MSG_MAP(aero::CFrameWindowImpl<CMainFrame>)//..
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew)
COMMAND_ID_HANDLER(ID_VIEW_TOOLBAR, OnViewToolBar)
COMMAND_ID_HANDLER(ID_VIEW_STATUS_BAR, OnViewStatusBar)
COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
END_MSG_MAP()
6,如果要在XP
或W2k
下运行应用
,请为uxtheme.dll
和dwmapi.dll
设置懒加载
就这样.编译并运行.应该就行了.
用第一个测试做更多的事情:
1,按透明工具栏
更改工具栏
,只需在CMainFrame::OnCreate()
中替换调用CreateSimpleToolBarCtrl()
即可:
cpp
HWND hWndToolBar = CreateAeroToolBarCtrl(m_hWnd,
IDR_MAINFRAME,FALSE,ATL_SIMPLE_TOOLBAR_PANE_STYLE);//..
要一些绘画,请在CMainFrame
中插入此成员
:
cpp
void Paint(CDCHandle dc, RECT& rClient, RECT& rView, RECT& rDest)
{
CLogFont lf;
GetThemeSysFont(TMT_MSGBOXFONT, &lf);
lf.lfHeight *= 3;
CFont f = lf.CreateFontIndirect();
HFONT hfOld = dc.SelectFont(f);
DrawText(dc, L"Hello Aero", &rClient, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
dc.SelectFont(hfOld);
}
取"Aero
"对话框
1,在资源编辑器中,打开IDD_ABOUTBOX
对话框,并按IDC_APPICON
和IDC_APPTEXT
更改图标
和文本控件ID
.
2,更改aboutdlg.h
中的代码:
cpp
//`aboutdlg.h:CAboutDlg`类的接口...
class CAboutDlg : public aero::CDialogImpl<CAboutDlg >//..
{
public:
enum { IDD = IDD_ABOUTBOX };
BEGIN_MSG_MAP(CAboutDlg)
CHAIN_MSG_MAP(aero::CDialogImpl<CAboutDlg >)//..
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
COMMAND_ID_HANDLER(IDOK, OnCloseCmd)
COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)
END_MSG_MAP()
//...
LRESULT OnInitDialog(UINT /*`uMsg`*/, WPARAM /*`wParam`*/,
LPARAM /*l参数*/, BOOL& /*b已处理*/)
{
CenterWindow(GetParent());
AERO_CONTROL(CStatic, m_Icon, IDC_APPICON)//<<
AERO_CONTROL(CStatic, m_Text, IDC_APPTEXT)
AERO_CONTROL(CButton, m_OK, IDOK)//>>
return TRUE;
}
//`...`
玻璃示例
在AeroSamples
项目中,你可找到其他适合玻璃
的AppWizard
应用:
1,AeroFrame
与你的FirstTest
相同
2,AeroView
使用简单的WTL
视图类.CMainFrame
和CAboutDlg
的更改相同,CAeroView::Paint()
也可在无主题运行时环境
中工作.
cpp
//`AeroView.h:CAeroView`类的接口`
class CAeroView : public aero::CWindowImpl<CAeroView>//..
{
public:
DECLARE_WND_CLASS(NULL)
BOOL PreTranslateMessage(MSG* pMsg)
{
pMsg;
return FALSE;
}
void Paint(CDCHandle dc, RECT& rClient, RECT& rView, RECT& rDest)
{
CLogFont lf;
if (IsTheming())
{
GetThemeSysFont(TMT_MSGBOXFONT, &lf);
if (!aero::IsSupported())
DrawThemeBackground(dc, 1, 1, &rClient, &rDest);
}
else
{
NONCLIENTMETRICS ncm = { sizeof(NONCLIENTMETRICS) };
SystemParametersInfo ( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, false );
lf = ncm.lfMessageFont;
dc.FillSolidRect(&rClient, GetSysColor(COLOR_WINDOW));
}
lf.lfHeight *= 3;
CFont f = lf.CreateFontIndirect();
HFONT hfOld = dc.SelectFont(f);
DrawText(dc, L"Hello Aero", &rClient,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
dc.SelectFont(hfOld);
}
BEGIN_MSG_MAP(CAeroView)
CHAIN_MSG_MAP(aero::CWindowImpl<CAeroView>)//..
END_MSG_MAP()
};
3,AeroTab
是一个使用相同,aero::CTabView
替换了CTabView
的CAeroView
类的"AppWizard
选项卡视图应用".
4,AeroSplit
与MainFrm.h
中向导
生成的代码相比,有更多变化.
cpp
class CMainFrame : public aero::CFrameWindowImpl<CMainFrame>,//..
public CUpdateUI<CMainFrame>,
public CMessageFilter, public CIdleHandler
{
public:
DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)
aero::CSplitterWindow m_splitter;
aero::CPaneContainer m_pane;
aero::CCtrl<CTreeViewCtrl> m_treeview;
CAeroView m_view;
aero::CCommandBarCtrl m_CmdBar;
//`...`
LRESULT OnCreate(UINT /*`uMsg`*/, WPARAM /*`wParam`*/, LPARAM /*l参数*/,
BOOL& /*b已处理*/)
{
//...
m_treeview.SetWindowTheme(L"explorer", NULL);
HTREEITEM hti = m_treeview.InsertItem(L"Test", TVI_ROOT, TVI_LAST);
m_treeview.InsertItem(L"Child Test", hti, TVI_LAST);
//...
5,AeroDialog
是一个在对话框编辑器
中,添加了一些控件
的"模态对话框AppWizard
应用".
cpp
//`MainDlg.h:CMainDlg`类的接口`
#pragma once
class CMainDlg : public aero::CDialogImpl<CMainDlg>//..
{
public:
enum { IDD = IDD_MAINDLG };
BEGIN_MSG_MAP(CMainDlg)
CHAIN_MSG_MAP(aero::CDialogImpl<CMainDlg>)//..
//...
LRESULT OnInitDialog(UINT /*`uMsg`*/, WPARAM /*`wParam`*/, LPARAM /*l参数*/, BOOL& /*b已处理*/)
{
//...
AERO_CONTROL(CButton, m_OK, IDOK)//<<
AERO_CONTROL(CButton, m_Cancel, IDCANCEL)
AERO_CONTROL(CButton, m_About, ID_APP_ABOUT)
AERO_CONTROL(CEdit, m_Edit, IDC_EDIT1)
AERO_CONTROL(CButton, m_C1, IDC_CHECK1)
AERO_CONTROL(CButton, m_C2, IDC_CHECK2)
AERO_CONTROL(CButton, m_R1, IDC_RADIO1)
AERO_CONTROL(CButton, m_R2, IDC_RADIO2)
AERO_CONTROL(CButton, m_Group, IDC_GROUP)
AERO_CONTROL(CListBox, m_LB, IDC_LIST1)
AERO_CONTROL(CComboBox, m_CB, IDC_COMBO1)//>>
m_LB.AddString(L"TEST Item");
m_CB.AddString(L"Combo Test");
SetOpaqueUnder(IDC_MONTHCALENDAR1);
return TRUE;
}
//...
WTL::aero
名字空间内部
WTL::aero
名字空间提供了支持玻璃
的WTL
应用的工具集
.
名间
函数
这些函数运行时
测试,允许后向兼容.
1,bool aero::IsSupported()
:如果为false
,则不试内容.
2,bool aero::IsComposing()
:如果这是真,请继续.
3,bool aero::IsOpaqueBlend()
:如果为true
,则关闭Vista
透明度
4,template <class TCtrl>BOOL aero::Subclass(TCtrl&Ctrl,HWND hCtrl)
仅在aero::IsSupported()
时,用TCtrl
类型的Ctrl
子类化hCtrl
控件.
基类
基类
是库的引擎.
1,aero::CAeroBase
为其继承类
提供访问主题API
的权限.Subclass()
成员接受控件ID
并在其HWND
上调用aero::Subclass()
.
在半透明背景
上绘画
时,各种DrawText()
成员都使用::DrawThemeTextEx()
.
cpp
//`aero::CAeroBase`,(如果可用)`Aero`半透明基类
template <class T>
class CAeroBase :
public WTL::CThemeImpl<T>
{
public:
CAeroBase(LPCWSTR lpstrThemeClassList = L"globals")
{
SetThemeClassList(lpstrThemeClassList);
}
bool IsTheming() const
{
return m_hTheme != 0;
}
template <class TCtrl>
BOOL Subclass(TCtrl& Ctrl, INT idCtrl)
{
return aero::Subclass(Ctrl,
static_cast<T*>(this)->GetDlgItem(idCtrl));
}
bool DrawPartText(HDC dc, int iPartID, int iStateID,
LPCTSTR pStr, LPRECT prText, UINT uFormat, DTTOPTS &dto)
{
HRESULT hr = S_FALSE;
if(IsTheming())
if (IsSupported())
hr = DrawThemeTextEx (dc, iPartID, iStateID, pStr, -1, uFormat, prText, &dto );
else
hr = DrawThemeText(dc, iPartID, iStateID, pStr, -1, uFormat, 0, prText);
else
hr = CDCHandle(dc).DrawText(pStr, -1, prText, uFormat) != 0 ? S_OK : S_FALSE;
return SUCCEEDED(hr);
}
bool DrawPartText(HDC dc, int iPartID, int iStateID, LPCTSTR pStr,
LPRECT prText, UINT uFormat,
DWORD dwFlags = DTT_COMPOSITED, int iGlowSize = 0)
{
DTTOPTS dto = {sizeof(DTTOPTS)};
dto.dwFlags = dwFlags;
dto.iGlowSize = iGlowSize;
return DrawPartText(dc, iPartID, iStateID, pStr, prText, uFormat, dto);
}
bool DrawText(HDC dc, LPCTSTR pStr, LPRECT prText, UINT uFormat, DTTOPTS &dto)
{
return DrawPartText(dc, 1, 1, pStr, prText, uFormat, dto);
}
bool DrawText(HDC dc, LPCTSTR pStr, LPRECT prText, UINT uFormat, DWORD dwFlags = DTT_COMPOSITED, int iGlowSize = 0)
{
return DrawPartText(dc, 1, 1, pStr, prText, uFormat, dwFlags, iGlowSize);
}
};
1,aero::CAeroImpl
从CAeroBase
和WTL::CBufferedPaintImpl
继承,并通过其m_Margins
成员管理半透明区域
.
2,SetMargins()
和各种SetOpaque()
成员允许控件半透明区域
.
3,CBufferedPaintImpl::OnPaint()
用系统缓冲
的DC
调用DoPaint()
成员.
4,它依次调用继承类Paint(CDCHandledc,RECT&rClient,RECT&rView,RECT&rDest)
,其中rClient
是窗口
客户矩,rView
是外边距内的区域
,rDest
是绘画区域
.
cpp
//`aero::CAeroImpl`,(如果可用)`Aero`半透明实现
template <class T>
class CAeroImpl :
public WTL::CBufferedPaintImpl<T>,
public CAeroBase<T>
{
public:
CAeroImpl(LPCWSTR lpstrThemeClassList = L"globals") :
CAeroBase<T>(lpstrThemeClassList)
{
m_PaintParams.dwFlags = BPPF_ERASE;
MARGINS m = {-1};
m_Margins = m;
}
MARGINS m_Margins;
bool SetMargins(MARGINS& m)
{
m_Margins = m;
T* pT = static_cast<T*>(this);
return pT->IsWindow() && IsComposing()?
SUCCEEDED(DwmExtendFrameIntoClientArea (pT->m_hWnd, &m_Margins)) : true;
}
bool SetOpaque(bool bOpaque = true)
{
MARGINS m = {bOpaque - 1};
return SetMargins(m);
}
bool SetOpaque(RECT &rOpaque)
{
T* pT = static_cast<T*>(this);
RECT rClient;
pT->GetClientRect(&rClient);
MARGINS m = {rOpaque.left, rClient.right - rOpaque.right, rOpaque.top, rClient.bottom - rOpaque.bottom};
return SetMargins(m);
}
bool SetOpaqueUnder(ATL::CWindow wChild)
{
T* pT = static_cast<T*>(this);
ATLASSERT(wChild.IsWindow());
ATLASSERT(pT->IsChild(wChild));
RECT rChild;
wChild.GetWindowRect(&rChild);
pT->ScreenToClient(&rChild);
return SetOpaque(rChild);
}
bool SetOpaqueUnder(UINT uID)
{
return SetOpaqueUnder(static_cast<T*>(this)->GetDlgItem(uID));
}
//实现
void DoPaint(CDCHandle dc, RECT& rDest)
{
T* pT = static_cast<T*>(this);
RECT rClient;
pT->GetClientRect(&rClient);
RECT rView = {rClient.left + m_Margins.cxLeftWidth,
rClient.top + m_Margins.cyTopHeight,
rClient.right - m_Margins.cxRightWidth,
rClient.bottom - m_Margins.cyBottomHeight};
if (!IsComposing())
if (IsTheming())
pT->DrawThemeBackground(dc, WP_FRAMEBOTTOM, pT->m_hWnd == GetFocus() ? FS_ACTIVE : FS_INACTIVE, &rClient, &rDest);
else
dc.FillSolidRect(&rClient, ::GetSysColor(COLOR_MENUBAR));
if ((m_Margins.cxLeftWidth != -1) && !::IsRectEmpty(&rView))
{
dc.FillSolidRect(&rView, ::GetSysColor(COLOR_WINDOW));
if (!m_BufferedPaint.IsNull())
m_BufferedPaint.MakeOpaque(&rView);
}
else
::SetRectEmpty(&rView);
pT->Paint(dc, rClient, rView, rDest);
}
//可覆盖对象
void Paint(CDCHandle /*直流*/, RECT& /*r客户*/, RECT& /*`rView`视图*/, RECT& /*`rDest`*/)
{}
void OnComposition()
{}
void OnColorization()
{}
BEGIN_MSG_MAP(CAeroImpl)
CHAIN_MSG_MAP(CThemeImpl<T>)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
MESSAGE_HANDLER(WM_DWMCOMPOSITIONCHANGED, OnCompositionChanged)
MESSAGE_HANDLER(WM_DWMCOLORIZATIONCOLORCHANGED, OnColorizationChanged)
CHAIN_MSG_MAP(CBufferedPaintImpl<T>)
END_MSG_MAP()
LRESULT OnCreate(UINT /*`uMsg`*/, WPARAM /*`wParam`*/, LPARAM /*l参数*/, BOOL& bHandled)
{
if (IsThemingSupported())
OpenThemeData();
if (IsComposing())
::DwmExtendFrameIntoClientArea(static_cast<T*>(this)->m_hWnd, &m_Margins);
return bHandled = FALSE;
}
LRESULT OnActivate(UINT /*`uMsg`*/, WPARAM /*`wParam`*/, LPARAM /*l参数*/, BOOL& bHandled)
{
if (!IsComposing() && IsTheming())
static_cast<T*>(this)->Invalidate(FALSE);
return bHandled = FALSE;
}
LRESULT OnCompositionChanged(UINT /*`uMsg`*/, WPARAM /*`wParam`*/, LPARAM /*l参数*/, BOOL& bHandled)
{
if (IsComposing())
SetMargins(m_Margins);
static_cast<T*>(this)->OnComposition();
return bHandled = FALSE;
}
LRESULT OnColorizationChanged(UINT /*`uMsg`*/, WPARAM /*`wParam`*/, LPARAM /*l参数*/, BOOL& bHandled)
{
static_cast<T*>(this)->OnColorization();
return bHandled = FALSE;
}
};
适配器类
这些类给现有控件加上AeroGlass
效果.
用aero::CCtrl
来子类化系统
和常见控件
.
两个成员
来特化:GetThemeName()
返回创建或子类化
时要打开的控件
的主题名
,通过覆盖的OnBufferedPaint()
成员绘画CtrlPaint(HDChdc,RECT&rCtrl,RECT&rPaint)
调用.
三个DrawCtrlxxx()
成员是特定绘图例程
的助手
.
AERO_CONTROL()
宏帮助一步声明和子类化
子控件.
cpp
//`aero::CCtrl`,为系统控件实现`玻璃`绘图.
//注意:此类针对系统主题的控件特化
template<class TBase>
class CCtrl :
public WTL::CBufferedPaintWindowImpl<CCtrl<TBase>, TBase>,
public CAeroBase<CCtrl<TBase> >
{
public:
typedef CAeroBase<CCtrl<TBase> > baseAero;
typedef WTL::CBufferedPaintWindowImpl<CCtrl<TBase>, TBase> baseWindow;
DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())
//创建和初化
CCtrl(LPCWSTR lpstrThemeClassList = GetThemeName()) : baseAero(lpstrThemeClassList)
{
m_PaintParams.dwFlags = BPPF_ERASE;
}
CCtrl<TBase>& operator =(HWND hWnd)
{
TBase::m_hWnd = hWnd;
return *this;
}
HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL,
LPCTSTR szWindowName = NULL,
DWORD dwStyle = 0, DWORD dwExStyle = 0,
ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
{
TBase baseCtrl;
if (baseCtrl.Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam) != NULL)
SubclassWindow(baseCtrl.m_hWnd);
return m_hWnd;
}
BOOL SubclassWindow(HWND hWnd)
{
ATLASSERT(IsSupported());
if(baseWindow::SubclassWindow(hWnd))
OpenThemeData();
return m_hWnd != NULL;
}
//特化
static LPCWSTR GetThemeName()
{
return TBase::GetWndClassName();
}
void CtrlPaint(HDC hdc, RECT& /*`rCtrl`键*/, RECT& rPaint)
{
DefCtrlPaint(hdc, rPaint);
}
//操作
void DefCtrlPaint(HDC hdc, RECT& rPaint, bool bEraseBkGnd = false)
{
if (bEraseBkGnd)
DefWindowProc(WM_ERASEBKGND, (WPARAM)hdc, NULL);
DefWindowProc(WM_PAINT, (WPARAM)hdc, 0);
m_BufferedPaint.MakeOpaque(&rPaint);
}
BOOL DrawCtrlBackground(HDC hdc, int nPartID, int nStateID, RECT &rCtrl, RECT &rPaint)
{
return SUCCEEDED(DrawThemeBackground(hdc, nPartID, nStateID, &rCtrl, &rPaint));
}
BOOL DrawCtrlEdge(HDC hdc, int nPartID, int nStateID, RECT &rCtrl,
UINT uEdge = EDGE_ETCHED, UINT uFlags = BF_RECT,
LPRECT pContentRect = NULL)
{
return SUCCEEDED(DrawThemeEdge(hdc, nPartID, nStateID, &rCtrl, uEdge, uFlags, pContentRect));
}
BOOL DrawCtrlText(CDCHandle dc, int nPartID, int nStateID,
UINT uFormat, RECT &rCtrl, HFONT hFont = 0,
DWORD dwFlags = DTT_COMPOSITED, int iGlowSize = 0)
{
HRESULT hr;
RECT rText;
hr = GetThemeBackgroundContentRect
(dc, nPartID, nStateID, &rCtrl, &rText);
MARGINS m = {0};
hr = GetThemeMargins(dc, nPartID, nStateID, TMT_CONTENTMARGINS, &rText, &m);
rText.left += m.cxLeftWidth;
rText.right -= m.cxRightWidth;
int iLength = GetWindowTextLength();
if (iLength > 0)
{
CTempBuffer<wchar /> sText(++iLength);
GetWindowText(sText, iLength);
HFONT hf = dc.SelectFont(hFont == 0 ? GetFont() : hFont);
hr = DrawPartText(dc, nPartID, nStateID, sText, &rText , uFormat, dwFlags, iGlowSize);
dc.SelectFont(hf);
}
return SUCCEEDED(hr) && iLength > 0;
}
//实现
void DoBufferedPaint(HDC hdc, RECT& rPaint)
{
HDC hDCPaint = NULL;
RECT rCtrl;
GetClientRect(&rCtrl);
m_BufferedPaint.Begin(hdc, &rCtrl, m_dwFormat, &m_PaintParams, &hDCPaint);
ATLASSERT(hDCPaint != NULL);
CtrlPaint(hDCPaint, rCtrl, rPaint);
m_BufferedPaint.End();
}
void DoPaint(HDC /*`HDC`*/, RECT& /*`rCtrl`键*/)
{
DefWindowProc();
}
BEGIN_MSG_MAP(CCtrl)
MESSAGE_HANDLER(WM_PAINT, OnPaintMsg)
MESSAGE_HANDLER(WM_ERASEBKGND, OnPaintMsg)
CHAIN_MSG_MAP(baseAero)
CHAIN_MSG_MAP(baseWindow)
END_MSG_MAP()
LRESULT OnPaintMsg(UINT /*`uMsg`*/, WPARAM /*`wParam`*/, LPARAM /*l参数*/, BOOL& bHandled)
{
if(!IsComposing())
return DefWindowProc();
else
return bHandled = FALSE;
}
};
//宏声明和子类化控件(在`OnCreate`或`OnInitDialog`成员中使用的静态声明)
#define AERO_CONTROL(type, name, id)\
static aero::type name;\
Subclass(name, id);
aero::CCtrlImpl
在现有TCtrlImpl
上启用玻璃
绘图.可在继承类
中覆盖DoPaint()
成员,以调用TCtrlImpl
相关代码.
cpp
//`aero::CCtrlImpl`,对用户和`WTL`定义的控件,实现`玻璃`绘图,注意:从此类继承
template <class T, class TCtrlImpl, bool t_bOpaque = false>
class ATL_NO_VTABLE CCtrlImpl :
public TCtrlImpl,
public CAeroImpl<T>
{
public:
DECLARE_WND_SUPERCLASS(NULL, TCtrlImpl::GetWndClassName())
CCtrlImpl(LPCWSTR lpstrThemeClassList = L"window") : CAeroImpl(lpstrThemeClassList)
{
m_PaintParams.dwFlags = BPPF_ERASE;
}
void DoPaint(HDC hdc, RECT& rect)
{
BOOL bHandled = TRUE;
TCtrlImpl::OnPaint(WM_PAINT, (WPARAM) hdc, NULL, bHandled);
if (t_bOpaque)
m_BufferedPaint.MakeOpaque(&rect);
}
BEGIN_MSG_MAP(CCtrlImpl)
CHAIN_MSG_MAP(CAeroImpl<T>)
CHAIN_MSG_MAP(TCtrlImpl)
END_MSG_MAP()
};
替换类
这些是启用玻璃
的类,用来替换同名的WTL::
或ATL::
类.
可继承类
:这些类从aero::CAeroImpl
继承:
cpp
aero::CWindowImpl< T, TBase, TWinTraits >
aero::CDialogImpl<T, TBase>
aero::CFrameWindowImpl<T, TBase, TWinTraits>
aero::CPropertySheetImpl<T, TBase>
aero::CPropertyPageImpl<T, TBase>
aero::CSplitterImpl<T, t_bVertical>
aero::CSplitterWindowImpl<T, t_bVertical, TBase, TWinTraits>
aero::CSplitterWindowT<t_bVertical>
从aero::CCtrl
,继承或特化
的类:
cpp
aero::CEdit
aero::CTabCtrl
aero::CToolBarCtrl
aero::CStatusBarCtrl
aero::CListBox
aero::CComboBox
aero::CStatic
aero::CButton
从aero::CCtrlImpl
继承的类:
cpp
aero::CCommandBarCtrl
aero::CTabView
aero::CPaneContainer
aero::CPrintPreviewWindow
结论
在现有本地代码应用
上启用漂亮
的Aeroglass
并不难.干杯!
见,WtlAero/AeroSamples
.