用C++实现半透明按钮控件(PNG,GDI+)

使用MFC实现上面的按钮半透明效果能看到父窗口中的内容,上面是效果图(一个是带背景图片的、另一个是不带的)。

控件继承自CWnd类(彩色的部分是窗口的背景图片、按钮是PNG图片,第二个图标是鼠标指向时的效果)。

图标的绘制使用GDI+绘制PNG图片,在此不多说了(处理WM_PAINT消息):

1 void PNGButton::OnPaint()
2 {
3 CPaintDC dc(this);
4 Graphics g(dc.m_hDC);
5 if(DrawBorder){
6 g.DrawImage(hoverBg,0,0);//画鼠标指向时的亮色背景
7 }
8 g.DrawImage(this->bg,0,0);//画按钮图标
9 g.ReleaseHDC(dc.m_hDC);
10 }

透明的关键:注意后面调用此方法的代码

关键在于InvalidateRect函数:通知父窗口重新绘制特定区域,执行此函数后按钮所在区域就被父窗口绘制的内容覆盖.在父窗口绘制完成后,
按钮也会收到WM_PAINT消息,执行上面的一段OnPaint代码.

1 void PNGButton::PaintParent()
2 {
3 CRect rect;
4 GetWindowRect(&rect);
5 GetParent()-> ScreenToClient(&rect);
6 GetParent()-> InvalidateRect(&rect);
7 }

捕获鼠标指向或移出事件(处理WM_MOUSEMOVE,WM_MOUSEOVER,WM_MOUSELEAVE消息):

1 void PNGButton::OnMouseHover(UINT nFlags, CPoint point)
2 {
3 DrawBorder=true;
4 PaintParent();//通知父窗口重绘特定区域,会引发控件自身的重绘
5 }
6
7
8 void PNGButton::OnMouseLeave()
9 {
10 m_is_mouse_over = false;
11 m_is_tracked = false;
12 DrawBorder=false;
13 PaintParent(); //通知父窗口重绘特定区域,会引发控件自身的重绘
14 CWnd::OnMouseLeave();
15 }
16
17
18 void PNGButton::OnMouseMove(UINT nFlags, CPoint point)
19 {
20 m_is_mouse_over = true;
21 if(!m_is_tracked)
22 {
23 TRACKMOUSEEVENT tme;
24 tme.cbSize = sizeof(TRACKMOUSEEVENT);
25 tme.dwFlags = TME_LEAVE|TME_HOVER;
26 tme.hwndTrack = GetSafeHwnd();
27 tme.dwHoverTime = 80;
28 _TrackMouseEvent(&tme);
29 m_is_tracked = true;
30 }
31 CWnd::OnMouseMove(nFlags, point);
32 }

附:

从资源加载PNG图片

用C++实现半透明按钮控件(PNG,GDI+)

1 #pragma once
2 #include “stdafx.h”
3 using namespace Gdiplus;
4
5 static bool ImageFromIDResource(UINT nID, LPCTSTR sTR,Image * &pImg)
6 {
7 HINSTANCE hInst = AfxGetResourceHandle();
8 HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type
9 if (!hRsrc)
10 return FALSE;
11 // load resource into memory
12 DWORD len = SizeofResource(hInst, hRsrc);
13 BYTE lpRsrc = (BYTE)LoadResource(hInst, hRsrc);
14 if (!lpRsrc)
15 return FALSE;
16 // Allocate global memory on which to create stream
17 HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
18 BYTE pmem = (BYTE)GlobalLock(m_hMem);
19 memcpy(pmem,lpRsrc,len);
20 IStream* pstm;
21 CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
22 // load from stream
23 pImg=Gdiplus::Image::FromStream(pstm);
24 // free/release stuff
25 GlobalUnlock(m_hMem);
26 pstm->Release();
27 FreeResource(lpRsrc);
28 return TRUE;
29 }

平铺图片的代码

1 CPaintDC dc(this);
2 CRect rect;
3 GetClientRect(rect);
4 CBrush bs(RGB(240,240,240));//窗口背景色
5 dc.FillRect(&rect,&bs); //窗口着色
6 //填充背景图片:平铺
7 Graphics g(dc.m_hDC);
8 if(has_bg) g.DrawImage(this->bg,0,0);
9 Gdiplus::TextureBrush bbs(this->img);
10 g.FillRectangle(&bbs,0,0,rect.Width(),this->img->GetHeight());
11 g.ReleaseHDC(dc.m_hDC);
12 //TRACE(L”CMainFrame::OnPaint\r\n”);

附: PNGButton类代码下载

Original: https://www.cnblogs.com/liangxiaofeng/p/7069176.html
Author: 默默淡然
Title: 用C++实现半透明按钮控件(PNG,GDI+)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/536573/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 29.qt quick-在QML中调用C++类

    Qt Quick文章已移植到CSDN博客:https://blog.csdn.net/qq_37997682/category_11280267.html,本博客停止更新。 专栏入…

    C++ 2023年5月29日
    054
  • C# vs C++ 全局照明渲染性能比试

    512×512像素,每像素1000采样,C#版本渲染时间为40分47秒 最近有多篇讨论程序语言趋势的博文,其中谈及到C#的性能问题。本人之前未做过相关测试,自己的回覆流于…

    C++ 2023年5月29日
    092
  • [C++] 引用

    引用的特点 通常意义上的引用是”左值引用”,(相对于右值引用,即 rvalue reference)。 引用是语法糖,变量别名。声明一个引用,不是新定义了一…

    C++ 2023年5月29日
    045
  • Microsoft Visual C++ 2019 v14.28.29617

    Microsoft Visual C++ Redistributable(系统运行库,简称MSVC,VB/VC)是Windows操作系统应用程序的基础类型库组件。 Microsof…

    C++ 2023年5月29日
    087
  • 从C++到GO

    刚开始接触Go语言,看了两本Go语言的书,从c++开发者的角度来看看go语言的新特性,说下自己感触较深的几点: 并发编程 Go语言层面支持协程,将并发业务逻辑从异步转为同步,大幅提…

    C++ 2023年5月29日
    049
  • C++教程详解

    第一篇:基础篇 简介、环境配置、基本语法、注释、数据类型、变量类型、变量作用域、常量、修饰符类型、 存储类、运算符、循环、判断、函数、数字、数组、字符串、指针、引用、日期&…

    C++ 2023年5月29日
    073
  • 对指针和引用的理解(c++)

    1.指针 typedef说明一种新类型名,来代替已有类型名。 a.案例:typedef char String_t和#define String_d char 这两句在使用上的区别…

    C++ 2023年5月29日
    053
  • c++11新特性学习2

    noexcept 替代 throw。优点是更安全, 如果noexcept 修饰的函数抛出了异常,编辑器可以直接选择终止程序。 C++ 11中析构函数默认为noexcept(true…

    C++ 2023年5月29日
    039
  • C++ 使用静态链接库和动态链接库

    C++ 使用AdbHelper静态链接库 ## 必备文件:静态库AdbHelper.h,AdbHelper.lib以及动态库AdbHelper.dll ##   资源文件使用用法:…

    C++ 2023年5月29日
    048
  • Dijkstra算法(二)之 C++详解

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。 基本…

    C++ 2023年5月29日
    044
  • std::get<C++11多线程库~线程间共享数据>(09):共享数据带来的问题(1)

    1 #include 2 3 /* 4 * 话题1:线程间共享数据 5 * a. 共享数据带来的问题 6 * b. 使用互斥量保护数据 7 * c. 数据保护的替代方案 8 * 9…

    C++ 2023年5月29日
    050
  • c++智能指针

    跟comptr类似 明确定义AddRef和Release,然后定义与comptr类似的一个辅助类. 这里有2种方式 1.Release的时候引用计数为0的时候删除对象 2.定义一个…

    C++ 2023年5月29日
    092
  • 生成1~n之间随机整数_c++

    rand() % (high – low + 1) + low; Original: https://www.cnblogs.com/douzujun/p/16457919.htm…

    C++ 2023年5月29日
    034
  • 汉诺塔的c++实现

    void hanNuoTa(int n,int a,int b,int c) { if (n == 0) return; hanNuoTa(n – 1, a, c, b); cou…

    C++ 2023年5月29日
    059
  • EclipseC++学习笔记-7 汉化

    1、复制https://download.eclipse.org/technology/babel/update-site/latest/ 注意要和版本保持一致,如果版本不对安装之…

    C++ 2023年5月29日
    057
  • Mac eclipse 编译、调试c++ 程序

    可以先安装个CDT插件: eclipse菜单 -> Help -> Install New Software… -> Work with (Add…..

    C++ 2023年5月29日
    048
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球