wtl自绘,按钮Button

最近接到个需求,要求在一个按钮上面同时显示大的文字和小的文字。想到了wtl的控件自绘。百度了下,发现竟然没人给出详细的代码,大部分都只是描述了下怎么弄,只好自己弄。先发个效果图。

.h文件

#pragma once
class CMyButtonEx
    : public CWindowImpl<CMyButtonEx, CButton>
    , public COwnerDraw<CMyButtonEx>
{
public:
    CMyButtonEx();
    ~CMyButtonEx();

    void SetWindowText2(LPCTSTR sText) { m_sText2 = sText; }

    BEGIN_MSG_MAP(CMyButtonEx)
        CHAIN_MSG_MAP_ALT(COwnerDraw<CMyButtonEx>, 1)
        DEFAULT_REFLECTION_HANDLER()
    END_MSG_MAP()

    void DrawItem(LPDRAWITEMSTRUCT lpdis);

private:
    CString m_sText2;
};

cpp文件

#include "stdafx.h"
#include "MyButtonEx.h"

extern CFont    m_defFont;          //缺省字体
extern CFont	m_fontBig;          //大字体

CMyButtonEx::CMyButtonEx()
{
}


CMyButtonEx::~CMyButtonEx()
{
}

void CMyButtonEx::DrawItem(LPDRAWITEMSTRUCT lpdis)
{
    CDCHandle dc(lpdis->hDC);
    CRect rc(lpdis->rcItem);

    CPen pen;
    pen.CreatePen(PS_SOLID, 1, (lpdis->itemState & ODS_DISABLED) ? RGB(173, 173, 173) : RGB(191, 191, 191));
    HPEN hOldPen = dc.SelectPen(pen.m_hPen);

    CBrush brush;

    brush.CreateSolidBrush((lpdis->itemState & ODS_DISABLED) ? RGB(204, 204, 204) : RGB(225, 225, 225));
    HBRUSH hOldBrush = dc.SelectBrush(brush.m_hBrush);

    dc.Rectangle(&rc);

    TCHAR szText[MAX_PATH] = { 0 };
    ::GetWindowText(m_hWnd, szText, MAX_PATH);
    if (wcslen(szText) > 0) {
        int nOldMode = dc.SetBkMode(TRANSPARENT);
        COLORREF crlOld = dc.SetTextColor((lpdis->itemState & ODS_DISABLED) ? RGB(131, 131, 131) : RGB(0, 0, 0));
        HFONT hOldFont = dc.SelectFont(m_fontBig.m_hFont);

        if (m_sText2.GetLength()) {
            SIZE size1, size2;
            GetTextExtentPoint32(dc.m_hDC, szText, wcslen(szText), &size1);
            dc.SelectFont(m_defFont.m_hFont);
            GetTextExtentPoint32(dc.m_hDC, m_sText2, m_sText2.GetLength(), &size2);

            CRect rc1;
            rc1.left = rc.left + (rc.Width() - size1.cx - size2.cx) / 2;
            rc1.top = 0;
            rc1.right = rc1.left + size1.cx;
            rc1.bottom = rc.bottom;
            dc.SelectFont(m_fontBig.m_hFont);
            dc.DrawText(szText, -1, rc1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);

            CRect rc2;
            rc2.left = rc1.right;
            rc2.top = 0;
            rc2.right = rc2.left + size2.cx;
            rc2.bottom = rc.bottom;
            dc.SelectFont(m_defFont.m_hFont);
            dc.DrawText(m_sText2, -1, rc2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        }
        else {
            dc.DrawText(szText, -1, rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
            
        }

        dc.SelectFont(hOldFont);
        dc.SetTextColor(crlOld);
        dc.SetBkMode(nOldMode);
    }
    
    if (hOldPen)
        dc.SelectPen(hOldPen);
    if (hOldBrush)
        dc.SelectBrush(hOldBrush);
}

创建font

    LOGFONT logfont;
    memset(&logfont, 0, sizeof(LOGFONT));
    lstrcpy(logfont.lfFaceName, _T("宋体")/*_T("Tahoma")*/);

    //默认字体
    logfont.lfWeight = FW_NORMAL;
    logfont.lfHeight = -12;
    m_defFont.CreateFontIndirect(&logfont);

    //大号字体
    logfont.lfWeight = FW_NORMAL;
    logfont.lfHeight = -16;
    m_fontBig.CreateFontIndirect(&logfont);

如果自绘失败的话,请按如下步骤检查一遍

1.添加自绘控件类,使其派生自COwnerDraw,例如

class MyButtonEx:public CWindowImpl<MyButtonEx, CButton>
,public COwnerDraw<MyButtonEx>

2.在自绘控件类中添加消息映射CHAIN_MSG_MAP_ALT,例如:CHAIN_MSG_MAP_ALT(COwnerDraw<MyButtonEx>, 1)

3.END_MSG_MAP之前要添加DEFAULT_REFLECTION_HANDLER()

4.重写void DrawItem(LPDRAWITEMSTRUCT lpds)等函数,在此函数中完成自绘工作

5.修改自绘控件类的窗口样式,添加OWNERDRAW属性,例如BS_OWNERDRAW

6.不要使用DDX_CONTROL关联控件变量与控件ID!而是使用SubclassWindow来实现,否则看不出自绘效果!(这一点浪费了我半小时找原因)

引自:https://www.cnblogs.com/mygmh/archive/2012/11/08/2761715.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
非客户区自绘wtl版本指的是在Windows模板库(WTL)基础上通过自主绘制非客户区来定制界面的版本。 WTL是一个开源的C++模板库,用于简化Windows桌面应用程序的开发。它相较于MFC更轻量级,更容易学习和使用。WTL提供了一系列的模板类和宏,可以快速开发具有Windows UI风格的应用程序。 在WTL中,非客户区(Non-Client Area)是指窗口边框以及标题栏、菜单栏、状态栏等装饰性的部分。传统上,这部分通常由操作系统负责绘制和管理。但是对于一些特殊需求,比如自定义的窗口样式、非矩形窗口等,我们需要对非客户区进行自主绘制。 非客户区自绘wtl版本即是基于WTL框架,在需要自定义非客户区的情况下,通过手动绘制实现。这种方式需要重载WTL框架中的非客户区绘制相关的函数,比如`OnNcPaint()`、`OnNcCalcSize()`等,来处理非客户区的绘制逻辑。 非客户区自绘wtl版本的好处在于可以完全控制非客户区的外观。可以根据自己的需要,实现各种特殊的样式和效果,如渐变色、图案填充、自定义按钮等。这样可以使应用程序更加美观和独特,增强用户体验。 但是非客户区自绘wtl版本也存在一些挑战。首先,自绘非客户区需要较高的绘制技术和图形处理能力。其次,自绘非客户区还会涉及到一些与系统相关的问题,如窗口移动、窗口关闭等操作的处理。因此,需要对WTL框架有较深入的理解和熟练的编程技巧。 总之,非客户区自绘wtl版本是在WTL框架基础上,通过自主绘制实现自定义非客户区的一种方式。它可以让我们灵活控制非客户区的外观,提升应用程序的美观程度和用户体验。然而,也需要考虑到相关的技术和系统问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值