`
helpbs
  • 浏览: 1161829 次
文章分类
社区版块
存档分类
最新评论

eVC下自绘按钮实现

 
阅读更多

按钮这个控件在软件中使用是非常广泛的,特别是基于MFC开发,按钮提供了很好的便捷。

但是在eVC下的按钮显示效果是非常土的,且背景颜色不好改。如果裁系统的时候将XP风格裁进去的话,默认按钮效果会好一些,但是背景颜色不好控制,在ce平台下,没有鼠标是很正常的,带XP风格的CE系统按钮提示不够明显,这个时候就需要自绘按钮了。

首先,先建立一个基于CWnd的类,如:CMyButton : public CWnd

1、添加成员变量:
CDC m_dcBack;
CBitmap m_bmpBack; //背景
COLORREF m_clNorBack; //正常时背景颜色
COLORREF m_clFocBack; //设上焦点时背景颜色
COLORREF m_clNorText;
COLORREF m_clFocText;
bool m_bLastState; //最后一次状态,true =焦点
CString m_strTitleInfo; //按钮上字符

2、添加成员函数:
void InitMyButton(); //初始化按钮
void DrawBackForNor(); //默认
void DrawBackForFoc(); //按下去
void DrawBackForMid(); //中间
BOOL CreateBTN(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, UINT nID,LPDealWithBTN lpDealWithBTN = NULL);//创建
void SetWindowText(LPCTSTR lpszString);//重载函数
BOOL EnableWindow(BOOL bEnable = TRUE);//重载函数

3、在View里添加消息: 如果考虑到右键效果,可以参考LBUTTONDOWN()添加
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_ENABLE()

上面的工作已经将基本工作完成了。接下来就是完成相应的代码了:

void CMyButton::OnPaint()
...{
// CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect rectClient;
GetClientRect(rectClient);

CDC memDC ;
CBitmap memBitmap ;
CBitmap* oldBitmap ;

memDC.CreateCompatibleDC(&dc) ;
memBitmap.CreateCompatibleBitmap(&dc, rectClient.Width(), rectClient.Height()) ;
oldBitmap = (CBitmap *)memDC.SelectObject(&memBitmap) ;

//将m_dcCoor和m_dcLine绘制到控件上
if (memDC.GetSafeHdc() != NULL)
...{
memDC.BitBlt(0, 0, rectClient.Width(), rectClient.Height(),
&m_dcBack, 0, 0, SRCCOPY) ;

dc.BitBlt(0, 0, rectClient.Width(), rectClient.Height(),
&memDC, 0, 0, SRCCOPY) ;
}

memDC.SelectObject(oldBitmap) ;

//删除内存位图GDI对象
memBitmap.DeleteObject();
//删除内存绘图环境
memDC.DeleteDC();
// Do not call CWnd::OnPaint() for painting messages
}

BOOL CMyButton::CreateBTN(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, UINT nID,LPDealWithBTN lpDealWithBTN/**//* = NULL*/)
...{
// TODO: Add your specialized code here and/or call the base class
BOOL bresult ;
//注册窗体类
static CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);
//创建窗体类
bresult = CWnd::CreateEx(NULL, className, NULL, dwStyle,
rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
pParentWnd->GetSafeHwnd(), (HMENU)nID) ;

//更新窗体显示
if (bresult != 0)
...{
m_strTitleInfo = lpszWindowName;
m_lpDealWithBTN = lpDealWithBTN;
InitMyButton();
DrawBackForNor();
}
return TRUE;

// return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
}


void CMyButton::InitMyButton()
...{
CClientDC dc(this);
// CBrush brushBack;
CRect rect;
GetClientRect(rect);

// brushBack.CreateSolidBrush(m_clNorBack) ;
//创建画线设备环境以及创建相应缓冲区
if (m_dcBack.GetSafeHdc() == NULL)
...{
m_dcBack.CreateCompatibleDC(&dc) ;
m_bmpBack.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height()) ;
m_dcBack.SelectObject(&m_bmpBack) ;
}

m_dcBack.SetBkColor (m_clNorBack) ;
m_dcBack.FillSolidRect(rect,m_clNorBack);

}

void CMyButton::DrawBackForFoc()
...{
CBrush bRushBack(m_clFocBack);
CBrush *OldBrush = m_dcBack.SelectObject(&bRushBack);

CPen penBlack;
penBlack.CreatePen(PS_SOLID,1,RGB(0,0,0));

CPen *penOld = m_dcBack.SelectObject(&penBlack);

CRect rect;
GetClientRect(&rect);

m_dcBack.FillSolidRect(rect,RGB(192,192,192));
// rect.DeflateRect(5,5);
m_dcBack.RoundRect(rect,CPoint(4,4));

m_dcBack.SelectObject(OldBrush);
m_dcBack.SelectObject(penOld);

bRushBack.DeleteObject();
penBlack.DeleteObject();

int nLenthBuf = WideCharToMultiByte(CP_ACP,0,m_strTitleInfo,-1,NULL,0,NULL,NULL) - 1;
LONG lLeftX = rect.left + (rect.Width() - nLenthBuf * 6) / 2;
LONG lLeftY = rect.top + (rect.Height() - 14) / 2;

m_dcBack.SetBkColor(m_clFocBack);
m_dcBack.SetTextColor(m_clFocText);
m_dcBack.ExtTextOut(lLeftX,lLeftY,ETO_OPAQUE,NULL,m_strTitleInfo,NULL);

Invalidate(FALSE);
m_bLastState = true;
}

void CMyButton::DrawBackForMid()
...{
CBrush bRushBack(RGB(230,230,207));
CBrush *OldBrush = m_dcBack.SelectObject(&bRushBack);

CPen penBlack;
penBlack.CreatePen(PS_SOLID,1,RGB(128,128,128));

CPen *penOld = m_dcBack.SelectObject(&penBlack);

CRect rect;
GetClientRect(&rect);

m_dcBack.FillSolidRect(rect,RGB(192,192,192));
// rect.DeflateRect(5,5);
m_dcBack.RoundRect(rect,CPoint(4,4));

m_dcBack.SelectObject(OldBrush);
m_dcBack.SelectObject(penOld);

bRushBack.DeleteObject();
penBlack.DeleteObject();

int nLenthBuf = WideCharToMultiByte(CP_ACP,0,m_strTitleInfo,-1,NULL,0,NULL,NULL) - 1;
LONG lLeftX = rect.left + (rect.Width() - nLenthBuf * 6) / 2;
LONG lLeftY = rect.top + (rect.Height() - 14) / 2;

m_dcBack.SetBkColor(RGB(230,230,207));
m_dcBack.SetTextColor(RGB(128,128,128));
m_dcBack.ExtTextOut(lLeftX,lLeftY,ETO_OPAQUE,NULL,m_strTitleInfo,NULL);

Invalidate(FALSE);
}

//normal
void CMyButton::DrawBackForNor()
...{
CRect rect;
GetClientRect(&rect);

CBrush bRushBack(m_clNorBack);
CBrush *OldBrush = m_dcBack.SelectObject(&bRushBack);

CPen penBlack;
penBlack.CreatePen(PS_SOLID,2,RGB(100,100,192));

CPen *penOld = m_dcBack.SelectObject(&penBlack);

m_dcBack.FillSolidRect(rect,RGB(192,192,192));

//rect.DeflateRect(5,5);
// m_dcBack.RoundRect(rect,CPoint(4,4));
m_dcBack.FillSolidRect(rect,RGB(100,100,192));

m_dcBack.SelectObject(OldBrush);
m_dcBack.SelectObject(penOld);

bRushBack.DeleteObject();
penBlack.DeleteObject();

int nLenthBuf = WideCharToMultiByte(CP_ACP,0,m_strTitleInfo,-1,NULL,0,NULL,NULL) - 1;
LONG lLeftX = rect.left + (rect.Width() - nLenthBuf * 6) / 2;
LONG lLeftY = rect.top + (rect.Height() - 14) / 2;

m_dcBack.SetBkColor(m_clNorBack);
m_dcBack.SetTextColor(m_clNorText);
m_dcBack.ExtTextOut(lLeftX,lLeftY,ETO_OPAQUE,NULL,m_strTitleInfo,NULL);

Invalidate(FALSE);
m_bLastState = false;
}

void CMyButton::OnSetFocus(CWnd* pOldWnd)
...{
CWnd::OnSetFocus(pOldWnd);

// TODO: Add your message handler code here
if (!m_bLastState)
...{
DrawBackForFoc();
}
}

void CMyButton::OnKillFocus(CWnd* pNewWnd)
...{
CWnd::OnKillFocus(pNewWnd);

// TODO: Add your message handler code here
if (m_bLastState)
...{
DrawBackForNor();
}
}

void CMyButton::OnLButtonDown(UINT nFlags, CPoint point)
...{
// TODO: Add your message handler code here and/or call default
if (m_lpDealWithBTN != NULL)
...{
m_lpDealWithBTN();
}
SetFocus();
CWnd::OnLButtonDown(nFlags, point);
}

void CMyButton::SetWindowText(LPCTSTR lpszString)
...{
m_strTitleInfo = lpszString;
if (m_bLastState)
...{
DrawBackForFoc();
}
else
...{
DrawBackForNor();
}
}


BOOL CMyButton::EnableWindow(BOOL bEnable /**//* = TRUE */)
...{
if (bEnable)
...{
DrawBackForNor();
}
else
...{
DrawBackForMid();
}

return CWnd::EnableWindow(bEnable);
}

注意:所有代码中ExtTextOut 完全可以用DrawText来代替,更简单一些。

为了实现主窗体跟按钮之间的通信,例如当按钮按下时,按钮要通知主窗体,我在这里添加函数指针来实现,当然也可以通过消息的方式来实现。声明函数指针:typedef void (*LPDealWithBTN)();
LPDealWithBTN m_lpDealWithBTN;//函数指针

把所有代码添加完毕就可以实现效果了。在主程序就可以添加相关的函数,如果要使用函数指针来实现通知的话,需先建立一个static函数。例如static void OnDealWithBTN01();

test:

CMyButton m_myBTN01;

m_myBTN01.CreateBTN(L"TestBTN",WS_CHILD|WS_VISIBLE,CRect(260,110,335,130),this,0,OnDealWithBTN01);

void CTestBtnDlg::OnDealWithBTN01()
{
printf("BTN01 pressed/r/n");
}

当然也可以实现贴图,这是完全可以的。如果要贴图的话,又要实现透明效果图片的话,那么参考一下代码:

//画透明图片
void CMyButton::DrawTransParent(CBitmap &bmp,int const x,int const y,int const cx,int const cy,
int const srcx,int const srcy,CDC *pDC,COLORREF TransparentColor)
...{
//定义源、掩码、透明绘制环境
CDC SrcDC,MaskDC,TransDC;
//定义掩码、透明位图
CBitmap MaskBmp,TransBmp;
BITMAP bm;

//创建源、掩码、透明绘制环境
SrcDC.CreateCompatibleDC(pDC);
MaskDC.CreateCompatibleDC(pDC);
TransDC.CreateCompatibleDC(pDC);

//得到位图结构
bmp.GetBitmap(&bm);
//创建透明位图
TransBmp.CreateCompatibleBitmap(pDC,cx,cy);
//创建掩码位图
MaskBmp.CreateBitmap(cx,cy,1,1,NULL);

//将透明位图对象选入到透明绘图环境
CBitmap *pTransBmp = TransDC.SelectObject(&TransBmp);
//将目标位图绘制到透明位图中
TransDC.BitBlt(x,y,cx,cy,pDC,srcx,srcy,SRCCOPY);

//将实际位图对象选入源绘图环境
CBitmap *pSrcBmp = SrcDC.SelectObject(&bmp);

//设置背景为透明模式
SrcDC.SetBkMode(TRANSPARENT);
//设置背景色
if (TransparentColor)
SrcDC.SetBkColor(TransparentColor);
else
...{
COLORREF col = SrcDC.GetPixel(0,bm.bmHeight-1);
SrcDC.SetBkColor(col);
}

CBitmap *pMaskBmp = MaskDC.SelectObject(&MaskBmp);

//将源绘图环境绘制到掩码绘图环境中
MaskDC.BitBlt(x,y,cx,cy,&SrcDC,0,0,SRCCOPY);

//将源位图和透明位图进行异或操作融合
TransDC.BitBlt(x,y,cx,cy,&SrcDC,0,0,SRCINVERT);
//将透明位图和掩码位图进行与操作
TransDC.BitBlt(x,y,cx,cy,&MaskDC,0,0,SRCAND);
//再将源位图和透明位图进行异或操作
TransDC.BitBlt(x,y,cx,cy,&SrcDC,0,0,SRCINVERT);

//此时将透明位图绘制到目标设备上
BOOL bRet = pDC->BitBlt(x,y,cx,cy,&TransDC,srcx,srcy,SRCCOPY);

//绘制绘图对象,并释放相应绘图环境和位图对象
SrcDC.SelectObject(pSrcBmp);
SrcDC.DeleteDC();

TransDC.SelectObject(pTransBmp);
TransBmp.DeleteObject();
TransDC.DeleteDC();

MaskDC.SelectObject(pMaskBmp);
MaskDC.DeleteDC();
MaskBmp.DeleteObject();
}
调用时:

CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP_MID);
BITMAP bm;
bmp.GetBitmap(&bm);
DrawTransParent(bmp,0,0,bm.bmWidth,bm.bmHeight,0,0,&m_dcBack,NULL);
bmp.DeleteObject();


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/favory/archive/2008/11/05/3227677.aspx

分享到:
评论

相关推荐

    基于Springboot+Vue的墙绘产品展示交易平台毕业源码案例设计.zip

    网络技术和计算机技术发展至今,已经拥有了深厚的理论基础,并在现实中进行了充分运用,尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代,所以对于信息的宣传和管理就很关键。系统化是必要的,设计网上系统不仅会节约人力和管理成本,还会安全保存庞大的数据量,对于信息的维护和检索也不需要花费很多时间,非常的便利。 网上系统是在MySQL中建立数据表保存信息,运用SpringBoot框架和Java语言编写。并按照软件设计开发流程进行设计实现。系统具备友好性且功能完善。 网上系统在让售信息规范化的同时,也能及时通过数据输入的有效性规则检测出错误数据,让数据的录入达到准确性的目的,进而提升数据的可靠性,让系统数据的错误率降至最低。 关键词:vue;MySQL;SpringBoot框架 【引流】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    99-青海大学大数据中心建设分享.pptx

    99-青海大学大数据中心建设分享.pptx

    TD-LTE载波聚合方案.docx

    5G通信行业、网络优化、通信工程建设资料。

    10份网络优化创新案例.zip

    SA语音回落与切换流程冲突解决.pdf 计费模式错误导致SA语音承载建立失败,pdf BSF网元bug导致SA用户VOLTE业务故障,pdf SA基站SCTP偶联IP配置不规范导致切换失败的问题处理,pdf 第一医院SA+NSA双模基站方案保障5G查房车应用,pdf SA未配置互操作场景下终端语音业务研究案例,pdf SA站点天馈隔离度问题导致上行速率不及预期,pdf SA组网下微信小视频卡顿影响感知案例,pdf 基于八步法定位SA掉线问题.pdf SA站点测试宏微切换异常事件,pdf

    施工监理费计算依据.doc

    5G通信行业、网络优化、通信工程建设资料。

    wordpress插件WhatsApp右下角浮动悬浮客服按钮

    1、WhatsApp插件,可轻松实现wordpress后台设置,前台悬浮显示; 2、无缝集成:该插件将WordPress站点与WhatsApp无缝集成; 3、多人员支持:支持显示多个WhatsApp账户,让用户根据需求或偏好选择联系不同的团队成员 4、群组邀请:允许邀请用户加入特定的WhatsApp支持群组,便于群体咨询、公告发布或集体答疑。 5、响应式设计:插件具备响应式布局,确保在各种屏幕尺寸和设备类型上均能良好呈现并顺畅使用。 6、WooCommerce产品查询集成:针对电商网站,支持与WooCommerce产品查询功能结合,方便用户就具体商品提问。 7、带声音的自动弹窗:可设置带有声音提示的自动弹出窗口,提醒用户支持服务的存在 8、定制欢迎消息:设置个性化欢迎信息,向用户传递品牌关怀或引导其使用支持服务。 9、移动端与桌面端开关控制:可根据需要独立开启或关闭移动端或桌面端上的插件功能 10、GDPR合规:遵循欧盟GDPR数据保护法规,保障用户隐私及数据安全。

    基于YOLOv7的芯片表面缺陷检测系统

    目前随着电子领域的快速发展,芯片也已经成为日常生活中不可或缺的一部分。随着市场对芯片的需求不断增大,裸芯片表面缺陷检测任务的压力也越来越大。裸芯片表面的缺陷检测不仅能保证芯片成品的质量,而且有着统计缺陷数量,反馈给生产前道工序的重要意义,但是目前许多生产线对于裸芯片表面依旧采用人工目检的方法进行缺陷检测,不仅实时性差,耗时长,而且结果会受到检测人员主观因素的影响。  目前国内外的芯片表面缺陷检测设备不仅价格昂贵,而且功能比较单一,因此本文提出了一种基于深度学习的裸芯片表面缺陷检测算法,具有高效率,实时性好的特点,与传统人工目检的方式相比具有一定的优势

    基于SpringBoot的“大学生社团活动平台”的设计与实现.zip

    基于SpringBoot的“大学生社团活动平台”的设计与实现基于SpringBoot的“大学生社团活动平台”的设计与实现基于SpringBoot的“大学生社团活动平台”的设计与实现基于SpringBoot的“大学生社团活动平台”的设计与实现基于SpringBoot的“大学生社团活动平台”的设计与实现基于SpringBoot的“大学生社团活动平台”的设计与实现基于SpringBoot的“大学生社团活动平台”的设计与实现基于SpringBoot的“大学生社团活动平台”的设计与实现基于SpringBoot的“大学生社团活动平台”的设计与实现

    英飞凌官方ADS库1.9.20版

    英飞凌官方ADS库1.9.20版

    汇编语言-assembly-贪吃蛇游戏-汇编语言期末大作业

    汇编语言——贪吃蛇游戏 GREEDY_SNAKE 是基于8086 汇编语言开发的,汇编语言风格是采用《汇编语言》第二版 王爽著; G_Snake.asm 本贪吃蛇游戏 实现了随机出现食物、统计分数、显示小蛇运动方向、响应键盘中断、指定方向自动移动、游戏结束恢复9h键盘中断和正常退出。 文件说明: 1. 安装DOSBOX:运行DOSBox0.74-win32-installer.exe即可安装; 2. 将Greedy_Snake clone到本地任意盘,eg:d:\Greedy_Snake - mount d:\Greedy_Snake 到一个指定虚拟盘符: - `mount k d:\Greedy_Snake` (why is k? because i like this charactor) 3. 运行G_Snake - 在DOSBOX的DOS提示符下键入: - `Z:\>K:`(回车) - `K:\>cd G_Snake`(回车) - 使用masm 5.0工具编译、链接、运行.asm源程序 - MASM.EXE、LINK.EXE、d

    物联网考试题库答案.doc

    5G通信行业、网络优化、通信工程建设资料

    基于Python的在线学习与推荐系统设计带vue前后端分离毕业源码案例设计.zip

    网络技术和计算机技术发展至今,已经拥有了深厚的理论基础,并在现实中进行了充分运用,尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代,所以对于信息的宣传和管理就很关键。系统化是必要的,设计网上系统不仅会节约人力和管理成本,还会安全保存庞大的数据量,对于信息的维护和检索也不需要花费很多时间,非常的便利。 网上系统是在MySQL中建立数据表保存信息,运用SpringBoot框架和Java语言编写。并按照软件设计开发流程进行设计实现。系统具备友好性且功能完善。 网上系统在让售信息规范化的同时,也能及时通过数据输入的有效性规则检测出错误数据,让数据的录入达到准确性的目的,进而提升数据的可靠性,让系统数据的错误率降至最低。 关键词:vue;MySQL;SpringBoot框架 【引流】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    考试资料+7、互联网与物联网.docx

    5G通信行业、网络优化、通信工程建设资料

    参考资料-人工智能对劳动力市场的影响机制研究.pdf

    参考资料-人工智能对劳动力市场的影响机制研究.pdf

    99-数据开放平台技术实现方案.pptx

    99-数据开放平台技术实现方案.pptx

    199-IBM数据治理新主张-数据治理及元数据管理.pptx

    199-IBM数据治理新主张-数据治理及元数据管理.pptx

    关注于一个操作系统框架的设计与实现。所使用的工具有gcc、nasm、bochs、gdb、vim等.zip

    【资源说明】【毕业设计】 1、该资源内项目代码都是经过测试运行成功,功能正常的情况下才上传的,请放心下载使用。 2、适用人群:主要针对计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、数学、电子信息等)的同学或企业员工下载使用,具有较高的学习借鉴价值。 3、不仅适合小白学习实战练习,也可作为大作业、课程设计、毕设项目、初期项目立项演示等,欢迎下载,互相学习,共同进步!

    自动驾驶中的数据闭环建立(一).pdf

    自动驾驶中的数据闭环链路的建立,数据驱动算法

    通信工程监理工作流程表.doc

    5G通信、网络优化与通信建设

    推荐智慧政务大数据 政务综合服务平台建设项目方案书.doc

    社会治理大数据平台建设项目的总体目标是以项目建设为契机,以“一个网络体系、一套应用系统、三个基础库”为依托,充分利用大数据挖掘、云计算等先进技术,有效整合各方信息资源,实现“人、地、物、事、组织”的网格化管理,从而带动XXX社会管理源头治理体系、动态协调机制、应急管理体制建设,实现XXX社会管理“精确化”、社会服务“人性化”,提升社会服务效能,并为XXX实现智慧城市奠定信息化基础。 主要建设目标是为政府社会管理良性有序运行提供基本手段和保证,促进政府对社会系统的组成部分、社会生活的不同领域以及社会发展的各个环节进行组织、协调、服务、监督和控制,整合政府各部门资源,实现统一运维管理,并建立安全和运维保障体系。科学划分网格单元,优化网格资源配置,构筑“区—街道—社区—网格”的四级管理架构,以社会管理、基层服务为核心,实现管理服务工作的全员化、精细化、信息化、实效化。

Global site tag (gtag.js) - Google Analytics