介绍
如果喜欢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.