【MFC】Button控件美化(自绘)

news2024/11/24 13:51:59

在MFC中Button控件不能通过OnCtlColor()函数对外观做太多的改变。

HBRUSH C按钮控件自绘Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);

	switch (pWnd->GetDlgCtrlID())
	{

	case IDC_BUTTON1:
	{
		pDC->SetBkMode(TRANSPARENT);
		pDC->SetBkColor(RGB(255, 0, 255));
		pDC->SetTextColor(RGB(255, 0, 0));
		static CBrush brush(RGB(255, 0, 255));
		return brush;
	}
	break;
	return hbr;
	}
}

欲设置按钮的背景为紫色,文字为红色,但是通过OnCtlColor()函数并不能实现预期的结果
在这里插入图片描述
为了能够修改Button控件字体、字体大小、背景色、背景图片,需要对Button控件进行自绘。

设置Button控件的自绘属性

方法一:在资源视图中将所有者描述设置为true
在这里插入图片描述
方法二:在OnInitDialog函数里给按钮添加BS_OWNERDRAW风格

GetDlgItem(IDC_BUTTON1)->ModifyStyle(0, BS_OWNERDRAW);

建立一个以CButton为基类的派生类并重载DrawItem()函数

在这里插入图片描述
通过类向导添加DrawItem()函数
在这里插入图片描述

为按钮添加关联变量

变量类型将CButton改成MyButton
在这里插入图片描述

MyButton类的设计

#pragma once
#include <afxwin.h>
class MyButton :
    public CButton
{


public:
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);
public:
    //三种颜色分别为文字,Button Down的背景颜色,Button Up的背景颜色
    COLORREF m_TextColor, m_DownColor, m_UpColor;
    //Button Down的背景颜色,Button Up的背景颜色标志位
    bool bDownColor, bUpColor;
    //设置文字大小
    int nWordSize = 100;
    UINT    imageID;//记录图片ID
public:
    //设置Button Down的背景颜色
    void SetDownColor(COLORREF color);
    //设置Button Up的背景颜色
    void SetUpColor(COLORREF color);
    //设置背景图片
    void SetBkImage(UINT ID);
    //设置文字大小,默认为10号
    void SetWordSize(int wordsize);
    //设置文字颜色默认为黑色
    void SetWordColor(COLORREF wordColor);
    // 文字处理
    void SetWord(CRect rect, CDC* pDc, int size);
    //绘制背景图片
    void DrawBkImage(CRect rect, CDC* pDc, UINT ID);

};
#include "pch.h"
#include "MyButton.h"

void MyButton::SetDownColor(COLORREF color)
{
	m_DownColor = color;
	bDownColor = TRUE;//颜色是否设置标志位
}
void MyButton::SetUpColor(COLORREF color)
{
	m_UpColor = color;
	bUpColor = TRUE;
}
void MyButton::SetBkImage(UINT ID)
{
	imageID = ID;
}
void MyButton::SetWordSize(int wordsize)
{
	nWordSize = wordsize;
}
void MyButton::SetWordColor(COLORREF wordColor = RGB(255, 255, 255))
{
	m_TextColor = wordColor;
}
void MyButton::DrawBkImage(CRect rect, CDC* pDc, UINT ID)
{
	CDC   dcBmp;             //定义并创建一个内存设备环境
	dcBmp.CreateCompatibleDC(pDc);             //创建兼容性DC
	CBitmap   bmpBackground;
	bmpBackground.LoadBitmap(ID);    //载入资源中图片
	BITMAP   m_bitmap;                         //图片变量               
	bmpBackground.GetBitmap(&m_bitmap);       //将图片载入位图中
	//将位图选入临时内存设备环境
	CBitmap* pbmpOld = dcBmp.SelectObject(&bmpBackground);
	//调用函数显示图片StretchBlt显示形状可变
	pDc->SetStretchBltMode(HALFTONE);
	pDc->StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dcBmp, 0, 0, m_bitmap.bmWidth, m_bitmap.bmHeight, SRCCOPY);
}
// 文字处理
void MyButton::SetWord(CRect rect, CDC* pDc, int nWordSize)
{
	CString str;
	GetWindowText(str);//获取文字
	CFont font;
	font.CreatePointFont(nWordSize, L"仿宋");//设置控件文字大小与字体
	pDc->SelectObject(&font);
	pDc->SetTextColor(m_TextColor);//设置文字颜色
	// dc.SetBkColor(RGB(255, 0, 0));//设置文字背景颜色
	pDc->SetBkMode(TRANSPARENT);//设置文字背景透明
	pDc->DrawText(str, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_TABSTOP);//绘制文字
}
void MyButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
	CDC dc;
	dc.Attach(lpDIS->hDC);//得到绘制的设备环境CDC
	dc.SelectStockObject(NULL_BRUSH);//按钮为默认颜色
	dc.Rectangle(&lpDIS->rcItem);//画出按钮框
	CString str;
	CRect rect = lpDIS->rcItem;
	GetClientRect(&rect);//得到客户端坐标 //ScreenToClient();将屏幕坐标转换为客户端坐标
	//加载背景图片,判断是否加载背景图片,没有则使用默认背景
	if (imageID != 0) DrawBkImage(rect, &dc, imageID);
	//按钮按下时改变背景色
	if (lpDIS->itemState & ODS_SELECTED)
	{
		if (bDownColor)
		{
			CBrush brush(m_DownColor);
			dc.FillRect(&(lpDIS->rcItem), &brush);//利用画刷brush,填充矩形框
		}
	}
	else//当按钮不操作或者弹起时改变背景色
	{
		if (bUpColor)
		{
			CBrush brush(m_UpColor);
			dc.FillRect(&(lpDIS->rcItem), &brush);//利用画刷brush,填充矩形框
		}
	}
	//文字处理(绘制文字)
	SetWord(rect, &dc, nWordSize);
	dc.Detach();
}

效果

/*放在OnInitDialog函数或OnPaint函数里*/

m_button1.SetUpColor(RGB(255, 0, 0));
m_button1.SetDownColor(RGB(0, 0, 255));

在这里插入图片描述
如果要在按钮上显示图片,不要设置按钮按下和弹起的颜色,这会覆盖图片

void C按钮控件自绘Dlg::OnPaint()
{
	CPaintDC dc(this);
	CRect rect;
	GetDlgItem(IDC_BUTTON1)->GetWindowRect(&rect);//获取控件的屏幕坐标
	ScreenToClient(&rect);//转换为窗口的的客户区坐标
	m_button1.SetBkImage(IDB_BITMAP1);
	m_button1.DrawBkImage(rect, &dc, IDB_BITMAP1); 
}

在这里插入图片描述
这个时候点击按钮并没有什么变化(这里指视觉上的变化,消息还是有的)
那么可以在DrawItem()函数里添加一些功能,比如按钮按下的时候绘制边框,弹起时销毁边框

if ((lpDIS->itemState & ODS_SELECTED) && (lpDIS->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
	{
		//设置按钮边框颜色为蓝色
		COLORREF color = RGB(0, 0, 255);
		CBrush brush(color);
		dc.FrameRect(&(lpDIS->rcItem), &brush);//用画刷brush,填充矩形边框
	}
	//控制的选中状态结束,去掉边框
if (!(lpDIS->itemState & ODS_SELECTED) && (lpDIS->itemAction & ODA_SELECT))
	{
		CBrush brush(m_UpColor);
		dc.FrameRect(&lpDIS->rcItem, &brush);
	}

LPDRAWITEMSTRUCT结构体
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/995139.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【已解决】ORA-00001: unique constraint (USR_JXZX_DSJKF_MODEL.SYS_C00912833) violated

已解决&#xff1a; nested exception is java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (USR_JXZX_DSJKF_MODEL.SYS_C00912833) violated 问题 学号主键ID重复了 思路 在 Oracle 中&#xff0c;可以使用以下方法找出重复的主键&#…

Vue中实现3D得球自动旋转

具体实现 安装echarts 在终端下安装echarts npm install -D echarts 安装echarts-gl 在终端下安装echarts-gl npm install -D echarts-gl earth3D组件 earth3D.vue <template><div class"globe3d-earth-container" ><div class"globe3d-earth&qu…

桉木做的建筑模板质量评价

桉木作为一种常见的建筑模板材料&#xff0c;以其独特的特性在建筑行业中得到广泛应用。然而&#xff0c;评估桉木建筑模板的质量是确保建筑项目成功的关键因素之一。本文将对桉木建筑模板的质量进行评价&#xff0c;从材料特性、强度和耐久性等方面进行分析。 首先&#xff0c…

Pinyin4j介绍和简单使用

前言 Pinyin4j是一个Java库&#xff0c;用于将汉字转换为拼音。它是由中国清华大学的Tsinghua University和中国科学院计算技术研究所的研究人员开发的。Pinyin4j可以用于Java应用程序中&#xff0c;以便在需要时将汉字转换为拼音。例如&#xff0c;它可以用于中文输入法、文本…

大模型tokenizer流式响应解决词句连贯性问题

大模型tokenizer词句连贯性问题 现象 from transformers import LlamaTokenizerFast import numpy as nptokenizer LlamaTokenizerFast.from_pretrained("heilerich/llama-tokenizer-fast") origin_prompt "Hi, Im Minwoo Park from seoul, korea." id…

使用 multiprocessing 多进程处理批量数据

示例代码 import multiprocessingdef process_data(data):# 这里是处理单个数据的过程return data * 2# 待处理的数据 data [1, 2, 3, 4, 5]def normal_func():# 普通处理方式result []for obj in data:result.append(process_data(obj)return resultdef parallel_func():# …

JavaScript编程语法作业

目录 目录 前言 思维导图 1&#xff0c;作业资源 2&#xff0c;if语句练习 2.1代码解读: 2.2,结果展示: 3&#xff0c;switch语句练习 3.1,代码解读: 3.2,结果展示: 4.while循环练习 4.1,代码解读: 4.2.结果展示: 5.do-while循环练习 5.1,代码解读: 5.2,结果展…

STM32 CAN/CANFD软件快速配置(HAL库版本)

STM32 CAN/CANFD软件快速配置&#xff08;HAL库版本&#xff09; 目录 STM32 CAN/CANFD软件快速配置&#xff08;HAL库版本&#xff09;前言1 软件编程1.1 建立工程1.2 初始化1.2.1 引脚设置1.2.2 CAN基本参数设置1.2.3 CAN收发初始化设置1.2.4 中断设置 1.3 CAN发送1.4 CAN接收…

自定义Dynamics 365实施和发布业务解决方案 3. 开箱即用自定义

在本章中,您将开始开发SBMA会员应用程序。在开发的最初阶段,主要关注开箱即用的定制。在第2章中,我们讨论了如何创建基本解决方案的细节,在本章中,将创建作为解决方案补丁的基本自定义,并展示将解决方案添加到源代码管理和目标环境的步骤。 表单自定义 若要开始表单自定…

连续 3 年 40% 增长 续费率近 110%:纷享销客增长的底层逻辑

经营管理没有一招鲜&#xff0c;持续增长的底层逻辑&#xff0c;就是持续稳定的建设&#xff0c;不被外界所干扰。 笔记整理 | 张保文 SaaS 增长&#xff0c;比拼的是战略、组织、人才、市场、销售、客户成功等全价值链的基本功。连续 3 年 40% 增长&#xff0c;续费率近 110%…

【图解RabbitMQ-5】RabbitMQ Web管控台图文介绍

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;CSDN实力新星&#xff0c;后端开发两年经验&#xff0c;曾担任甲方技术代表&#xff0c;业余独自创办智源恩创网络科技工作室。会点点Java相关技术栈、帆软报表、低代码平台快速开…

C++ 结构体

前文 C中的结构体是一种非常有用的数据类型&#xff0c;它允许我们将不同的变量组合在一起&#xff0c;形成一个自定义的数据结构。 结构体在C中的应用非常广泛&#xff0c;它可以用来表示和管理各种实体、对象或数据的属性。比如&#xff0c;在一个学生管理系统中&#xff0c…

2.2 Java中的变量

1. 变量与赋值 在程序运行期间&#xff0c;随时可能产生一些临时数据&#xff0c;应用程序会将这些数据保存在内存单元中&#xff0c;每个内存单元都用一个标识符标识&#xff0c;这些用于标识内存单元的标识符就称为变量&#xff0c;内存单元中存储的数据就是变量的值。 下面…

C++day1---9.6

思维导图&#xff1a; 1.使用cout完成输出斐波那契前20项的内容 #include <iostream>using namespace std;int main() {int a 1;int b 0;int sum 1;int arr[20] {0};for(int i0; i<20; i){arr[i] sum; //存放最新值sum ab; //更新sumb a; …

windows mysql弹出黑框处理

现象 处理方式 点击禁用即可 以后就不会再出现了

【Arduino30】DS1302时钟芯片模拟值实验

硬件准备 DS1302芯片&#xff1a;1片 32.768kHz晶振&#xff1a;1个 面包板&#xff1a;1个 杜邦线&#xff1a;若干 硬件连线 软件程序 #include <DS1302.h> //头文件//定义引脚 const int rst_pin 5; const int date_pin 6; const int sclk_pin 7;//将DS1302实…

ARTS 2023.8.21-2023.8.27 (第一周)

ARTS 2023.8.21-2023.8.27 &#xff08;第一周&#xff09; &#x1f4a1;ARTS&#xff1a; A&#xff1a;至少每周完成一道Leecode的算法题&#xff1b; R&#xff1a;阅读并点评至少一篇英文技术文章&#xff1b; T&#xff1a;学习至少一个技术技巧&#xff1b; S&#xff…

Tina Ti 计算电路中的参数

如图所示 计算每个节点的参数 通过这个工具&#xff0c;就算你不知道电路的原理&#xff0c;电路网络分析&#xff0c;你都可以计算出理论值是多少。

PTA作业笔记——简单的输入输出

PTA前十题 7-2 输入输出整数7-3 输入输出单精度实数7-4 输入输出双精度实数7-5 输入输出字符7-6 整数的各种形式输出7-7 混合无间隔输入输出7-8 日期格式化7-9 区位码输入法 写在前面&#xff1a;不是很难的题目直接放上代码&#xff0c;只作为记录 初学C语言的时候涉及到的输入…

c++day3---9.8

1> 自行封装一个栈的类&#xff0c;包含私有成员属性&#xff1a;栈的数组、记录栈顶的变量 成员函数完成&#xff1a;构造函数、析构函数、拷贝构造函数、入栈、出栈、清空栈、判空、判满、获取栈顶元素、求栈的大小 头文件&#xff1a; #ifndef Z_H #define Z_H #inclu…