使用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. 如何在grails2.3.x中的fork模式下进行调试?-【grails】

    grails2.3.x中默认情况下运行模式被设置成了fork模式,在这种模式下,大家会发现设置了断点后无法进行中断.这是由于fork模式造成的,因为在fork模式下,JVM新起了一个进程,这样调试器就 ...

  2. es6 promise对象

    function next(){ return new Promise( function( resolve, reject ){ var num =7 // Math.floor( Math.ran ...

  3. js清除单选框所选的值

    js清除单选框所选的值 $("input[type='radio']").removeAttr('checked');

  4. Ubuntu 硬盘分区只读,重新挂载为读写分区之后,文件依然创建出错

    原因: 分区只读,可能是windows没有正常关机,或者使用了混合休眠模式. 解决方案: sudo mount -o remount,rw /dev/sdaX 若重新挂载后,创建文件以及文件夹失败: ...

  5. (转)thymeleaf中的判断总结

    判断String字符串,添加引号 th:class="${flag=='forum.html'}?'active'" 判断boolean类型,注意不能当成字符串处理,不能添加引号 ...

  6. Dataset:利用Python将已有mnist数据集通过移动像素上下左右的方法来扩大数据集为初始数据集的5倍—Jason niu

    from __future__ import print_function import cPickle import gzip import os.path import random import ...

  7. jOOR

    --摘自<android插件化开发指南> 1.jOOR库就一个Reflect.java类很重要 2.Reflect.java包括6个核心方法 1)on:包裹一个类或者对象,表示在这个类或对 ...

  8. 总结mysql的三种外键约束方式

    如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表.外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是修改或者删除的级联操作将使得日常 ...

  9. python之psutil模块(获取系统性能信息(CPU,内存,磁盘,网络)

    一.psutil模块 1. psutil是一个跨平台库(http://code.google.com/p/psutil/),能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等) ...

  10. Vue-Router 学习笔记

    1:当router-link组件默认渲染成一个a标签,通过to属性指定目标地址,当对应的路由匹配成功,会自动给激活的标签设置class属性值 API 1:to:表示目标路由的链接,当被点击时,内部会立 ...