2408wtl,玻璃类

原文

介绍

如果喜欢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.hFirstTest\项目目录中,并更改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::对应项更改CFrameWindowImplm_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,如果要在XPW2k运行应用,请为uxtheme.dlldwmapi.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_APPICONIDC_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视图类.CMainFrameCAboutDlg的更改相同,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替换了CTabViewCAeroView类的"AppWizard选项卡视图应用".

4,AeroSplitMainFrm.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::CAeroImplCAeroBaseWTL::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.

相关推荐
许野平13 天前
Rust:GUI 开源框架
开发语言·后端·rust·gui
Liigo14 天前
初次体验Tauri和Sycamore(1)
rust·electron·gui·tauri·wasm·sycamore
gonghw40318 天前
DearPyGui学习
python·gui
大福是小强20 天前
004-Kotlin界面开发快速入水之TicTacToe
开发语言·kotlin·界面开发·gui·教程·桌面应用·快速入水
0zxm21 天前
JavaFx -- chapter06(UDPSocket)
java·网络·单片机·嵌入式硬件·gui·javafx
闲暇部落24 天前
Android OpenGL ES详解——裁剪Scissor
android·kotlin·opengl·窗口·裁剪·scissor·视口
软件算法开发25 天前
基于MATLAB的地下水模拟系统开发
matlab·gui·地下水模拟
大福是小强1 个月前
026_Callbacks_in_MATLAB中APP界面回调函数编程实现
ui·matlab·gui·回调函数·界面设计·app designer
这是一个图像1 个月前
从opencv-python入门opencv--GUI功能之绘图&鼠标与图像界面的交互
图像处理·python·opencv·计算机视觉·计算机外设·交互·gui
#sakura1 个月前
GUI 图像
gui