WTL 自绘Button类,支持按钮三种形态,正常模式,hover模式,鼠标按下模式,支持png图片。使用方法很简单:

MyButton* pButton = new MyButton;
   pButton->SetBtnBmp(strBtnNormal,strBtnHover,strBtnDown);
   pButton->Create(m_hWnd,rt,NULL,WS_CHILD|WS_VISIBLE);
   pButton->SetBtnID(nID);//该ID是用来处理WM_COMMAND 命令的,即单机左键命令

#pragma  once

#pragma comment(lib, "gdiplus.lib")
static ULONG_PTR s_gdiplusToken2=0; enum
{
btn_state_normal = 0,
btn_state_over = 1,
btn_state_down = 2
}; class MyButton:public CWindowImpl<MyButton>
{
public:
MyButton()
{
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&s_gdiplusToken2, &gdiplusStartupInput, NULL);
m_nState = btn_state_normal;
m_bBtnDown = false; }
~MyButton()
{
GdiplusShutdown(s_gdiplusToken2);
}
protected:
BEGIN_MSG_MAP(MyButton)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_PAINT,OnPaint)
MESSAGE_HANDLER(WM_MOUSEMOVE,OnMouseMove)
MESSAGE_HANDLER(WM_MOUSELEAVE,OnMouseLeave)
MESSAGE_HANDLER(WM_LBUTTONDOWN,OnLButtonDown)
MESSAGE_HANDLER(WM_LBUTTONUP,OnLButtonUp)
MESSAGE_HANDLER(WM_CREATE,OnCreate)
MESSAGE_HANDLER(WM_ERASEBKGND,OnEraseBkgnd)
END_MSG_MAP() LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
CRect winRect;
GetWindowRect(winRect);
SetWindowPos(HWND_TOPMOST,winRect,SWP_SHOWWINDOW); return TRUE;
}
LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{ return TRUE;
}
HBITMAP GetBitmapFromFile( LPCWSTR pFile )
{
std::auto_ptr<Bitmap> pBmp(new Bitmap(pFile));
if(!pBmp.get())
return NULL;
HBITMAP hBmp = NULL;
Color backColor = Color(255,0,0,0);
if(Ok!=pBmp->GetHBITMAP(backColor,&hBmp))
return NULL;
return hBmp;
}
void SetBtnBmp(CString strBtnNormal,CString strBtnHover,CString strBtnDown)
{
m_btmNormal.Attach(GetBitmapFromFile(strBtnNormal));
m_btmOver.Attach(GetBitmapFromFile(strBtnHover));
m_btmDown.Attach(GetBitmapFromFile(strBtnDown));
}
BOOL DrawBmp( HDC hdc, CRect rect, HBITMAP hBitmap )
{
BITMAP bm;
GetObject(hBitmap,sizeof(bm),(VOID*)&bm);
INT nWidth = bm.bmWidth;
INT nHeight = bm.bmHeight;
CDC memdc;
memdc.CreateCompatibleDC(hdc);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(hdc,nWidth,nHeight);
memdc.SelectBitmap(hBitmap); BLENDFUNCTION bf = {AC_SRC_OVER,0,255,1};
return ::AlphaBlend(hdc,rect.left,rect.top,nWidth,nHeight,memdc,0,0,nWidth,nHeight,bf); //::StretchBlt(hdc,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,
// comDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY );
}
LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
CPaintDC dc(m_hWnd);
CRect rect;
GetClientRect(&rect);
switch(m_nState)
{
case btn_state_over:
DrawBmp(dc,rect,m_btmOver);
break;
case btn_state_down:
DrawBmp(dc,rect,m_btmDown);
break;
default://case = btn_state_normal
DrawBmp(dc,rect,m_btmNormal);
break; }
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(RGB(240,250,240));
dc.DrawText(m_strText,m_strText.GetLength(),&rect,DT_CENTER);
return TRUE;
}
LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
if(!m_bBtnDown)
{
m_nState = btn_state_over;
InvalidateRect(NULL);
TRACKMOUSEEVENT t_MouseEvent;
t_MouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
t_MouseEvent.dwFlags = TME_LEAVE|TME_HOVER;
t_MouseEvent.hwndTrack = m_hWnd;
t_MouseEvent.dwHoverTime = 30;
::_TrackMouseEvent(&t_MouseEvent); } return TRUE;
}
LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
m_nState = btn_state_normal;
m_bBtnDown = false;
InvalidateRect(NULL);
return TRUE;
}
LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
m_nState = btn_state_normal;
m_bBtnDown = false;
InvalidateRect(NULL);
::PostMessage(GetParent(),WM_COMMAND,m_nBtnID,NULL);
return TRUE;
}
LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
m_bBtnDown = true;
m_nState = btn_state_down;
InvalidateRect(NULL);
return TRUE;
}
LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{ return TRUE;
}
void SetBtnText(CString strText)
{
m_strText = strText; }
void SetBtnID(int nID)
{
m_nBtnID = nID;
}
private:
CBitmap m_btmNormal;
CBitmap m_btmOver;
CBitmap m_btmDown;
int m_nState;
bool m_bBtnDown;
CString m_strText; INT m_nBtnID; };

WTL 自定义 Button类-自绘的更多相关文章

  1. IOS开发之自定义Button(集成三种回调模式)

    前面在做东西的时候都用到了storyboard,在今天的代码中就纯手写代码自己用封装个Button.这个Button继承于UIView类,在封装的时候用上啦OC中的三种回调模式:目标动作回调,委托回调 ...

  2. iOS_Swift初识之使用三种回调方式自定义Button

    最近在学习Swift ,发现青玉伏案大神早期用OC写的一篇博客--IOS开发之自定义Button(集成三种回调模式)  很适合用来熟悉Swift的回调方式,于是我就用Swift翻版了一下,具体实现原理 ...

  3. WPF 自定义Button控件及样式

    这次通过最近做的小例子说明一下自定义Button控件和样式. 实现的效果为:

  4. android 自定义Button,抛弃写shape文件

      标签: android 控件  自定义 2017年05月27日 17:52:13 611人阅读 评论(0) 收藏 举报 分类: 自定义View(2) 作者同类文章 X 版权声明:本文为博主原创文章 ...

  5. Android面试基础(一)IOC(DI)框架(ViewUtils)讲解_反射和自定义注解类

    1. Android中的IOC(DI)框架 1.1 ViewUtils简介(xUtils中的四大部分之一) IOC: Inverse of Controller 控制反转. DI: Dependenc ...

  6. C#自定义Button按钮控件

    C#自定义Button按钮控件 在实际项目开发中经常可以遇到.net自带控件并不一定可以满足需要,因此需要自定义开发一些新的控件,自定义控件的办法也有多种,可以自己绘制线条颜色图形等进行重绘,也可以采 ...

  7. Android 自定义View之自绘控件

    首先要提前声明一下,我对于自定义View的理解并不是很深,最近啃了几天guolin博主写的关于自定义View的博客,讲的非常棒,只不过涉及到源码和底层的一些东西,我自己就懵逼了,目前只是会了关于自定义 ...

  8. 【Android开发日记】之入门篇(十四)——Button控件+自定义Button控件

        好久不见,又是一个新的学期开始了,为什么我感觉好惆怅啊!这一周也发生了不少事情,节假日放了三天的假(好久没有这么悠闲过了),实习公司那边被组长半强制性的要求去解决一个后台登陆的问题,结果就是把 ...

  9. c#winform自定义窗体,重绘标题栏,自定义控件学习

    c#winform自定义窗体,重绘标题栏 虽然现在都在说winform窗体太丑了,但是我也能尽量让桌面应用程序漂亮那么一点点话不多说,先上图 重绘标题栏先将原生窗体设置成无边框,FormBoderSt ...

随机推荐

  1. USB C和USB 3.1傻傻分不清?这篇文章可以帮你

    USB Type-C接口以及USB 3.1标准的到来,理应为消费者提供更多便利.然而就目前来看,似乎这些新标准非但没有为消费者提供了更好的使用体验,反而带来了诸多隐患.Google的工程师Benson ...

  2. 【HDOJ】3315 My Brute

    几乎与2853相同,MCMF. /* 2853 */ #include <iostream> #include <string> #include <map> #i ...

  3. SIFT算法:特征描述子

    SIFT算法:DoG尺度空间生产  SIFT算法:KeyPoint找寻.定位与优化 SIFT算法:确定特征点方向  SIFT算法:特征描述子 目录: 1.确定描述子采样区域 2.生成描述子 2.1 旋 ...

  4. codeforce

    A. Playing with Dice time limit per test 1 second memory limit per test 256 megabytes input standard ...

  5. Selenium WebDriver + Grid2 + RSpec之旅(二)----Grid2的配置

    Selenium WebDriver + Grid2 + RSpec之旅(二) ----Grid2的配置 为什么要使用Selenium-Grid 分布式运行大规模的TestCase 能够通过一个中央节 ...

  6. poj 1039 Pipe(几何基础)

    Pipe Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9932   Accepted: 3045 Description ...

  7. Hdu 5213-Lucky 莫队,容斥原理,分块

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5213 Lucky Time Limit: 6000/3000 MS (Java/Others)    Me ...

  8. 神经网络中误差反向传播(back propagation)算法的工作原理

    注意:版权所有,转载需注明出处. 神经网络,从大学时候就知道,后面上课的时候老师也讲过,但是感觉从来没有真正掌握,总是似是而非,比较模糊,好像懂,其实并不懂. 在开始推导之前,需要先做一些准备工作,推 ...

  9. Tornado自定义分布式session框架

    一.session框架处理请求执行的流程: 1.服务器端生成随机的cookie字符串 2.浏览器发送请求,服务器将cookie返回给浏览器. 3.服务器在生成一个字典.字典的key为cookie,va ...

  10. oc学习之路----多级指针的使用和内存分析

    ---恢复内容开始--- 精髓:要熟悉指针的使用,首先要熟悉指针的各种状态存得是什么数据.(以一级指针 int *p1 二级指针:int **p2 三级指针:int ***p3为例) 一级指针:*p1 ...