使用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图片

 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类代码下载

用C++实现半透明按钮控件(PNG,GDI+)的更多相关文章

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

    http://blog.csdn.net/witch_soya/article/details/6889904

  2. WinRT自定义控件第一 - 转盘按钮控件

    之前的文章中,介绍了用WPF做一个转盘按钮控件,后来需要把这个控件移植到WinRT时,遇到了很大的问题,主要原因在于WPF和WinRT还是有很大不同的.这篇文章介绍了这个移植过程,由于2次实现的控件功 ...

  3. MFC编程入门之二十三(常用控件:按钮控件的编程实例)

    上一节讲了按钮控件Button.Radio Button和Check Box的基本用法,本节继续讲按钮控件的内容,通过一个实例让大家更清楚按钮控件在实际的软件开发中如何使用. 因为Button控件在前 ...

  4. MFC编程入门之二十二(常用控件:按钮控件Button、Radio Button和Check Box)

    本节继续讲解常用控件--按钮控件的使用. 按钮控件简介 按钮控件包括命令按钮(Button).单选按钮(Radio Button)和复选框(Check Box)等.命令按钮就是我们前面多次提到的侠义的 ...

  5. FineUI第五天---按钮控件

    按钮控件 <x:Button runat="server" ID="按下" Text="按下"></x:Button> ...

  6. VC按钮控件实现指示灯效果

    VC为按钮控件添加图片的方法有很多种: 直接调用SetBitmap:  CButton pButton->SetBitmap(hBitmap); 使用CButtonST控件: 使用CDC: 使用 ...

  7. Delphi7 第三方控件1stClass4000的TfcImageBtn按钮控件动态加载jpg图片例子

    Delphi7 第三方控件1stClass4000的TfcImageBtn按钮控件动态加载jpg图片例子 procedure TForm1.Button1Click(Sender: TObject); ...

  8. delphi按钮控件的default属性

    delphi按钮控件的default属性用于设置默认命令按钮,.设置为true时,按[Enter键]相当于用鼠标单击了该按钮 .窗口中如果有多个按钮的default是true的话,就根据tabinde ...

  9. 关于在storyboard拖按钮控件,手动设置代码不成功的问题

    首先,在 storyboard 中拖拽一个按钮控件.设置好约束条件

随机推荐

  1. 在vs.net 2010,2015 等版本,给JS函数添加代码提示\注释

    经常编写JS的朋友常常会因为函数写多了,隔一段时间就会忘记了函数的用途,或者函数里带的参数作用情况,这个时候会联想到VS工具里的强大提示功能,多希望也能在JS上实现呀,告诉你,这个想法并不是多难,VS ...

  2. h5 rem js自动适配

    (function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? ...

  3. 【JavaScript】快速入门

    摘抄地址快速入门 No1: JavaScript严格区分大小写 No2: JavaScript不区分整数和浮点数,统一用Number表示 NaN表示Not a Number,当无法计算结果时用NaN表 ...

  4. HDU4578 Transformation【线段树】

    <题目链接> <转载于 >>> > 题目大意: 有一个序列,有四种操作: 1:区间[l,r]内的数全部加c. 2:区间[l,r]内的数全部乘c. 3:区间[l ...

  5. CLR Via 第一 章 知识点整理(1)

    写这个纯粹是自己的一点学习总结,其实就学习的笔记整理,相当于对自己的一点督促,如有看到不正确的欢迎指出 一般我们写代码都是使用的高级语言,但是在CLR中运行的代码并不是我们直接写的代码,而是通过我们选 ...

  6. 【java并发核心八】Fork-Join分治编程

    jdk1.7中提供了Fork/Join并行执行任务框架,主要作用就是把大任务分割成若干个小任务,再对每个小任务得到的结果进行汇总. 正常情况下,一些小任务我们可以使用单线程递归来实现,但是如果要想充分 ...

  7. MD5_Util工具类代码

    package com.yby.mall.utils; import java.math.BigInteger; import java.security.MessageDigest; public ...

  8. Android Stuido 方法参数 p0,p1

    Android Stuido 方法参数 p0,p1 参考文献 https://stackoverflow.com/questions/49219439/incorrect-variable-names ...

  9. Java并发编程(五)-- Java内存模型补充

    前面我们已经介绍了:当对象和变量存储到计算机的各个内存区域时,必然会遇到的两个问题及解决方法 共享对象的可见性-- 解决方法:使用java volatile关键字 共享对象的竞争现象 -- 解决方法: ...

  10. [BZOJ1814]Formula 1

    Description: 一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数 Hint: \(n,m<=12\) Solution: 插头dp模板题,注意要讨论多种 ...