稻草人的程序之路--自绘按钮的类封装

之前很长一段时间,在做界面中的自绘按钮时,都是通过将控件子类化的办法,

切换按钮贴图来完成按钮的一些动画效果。但是,后来慢慢发现,每次做程序

界面画一个按钮都需要将按钮子类化,按钮多了过程就繁重,代码重复性也很

高,于是就想了个办法,将其封装成一个类,以后再做自绘按钮的时候 只要载

入这个类,调用一个函数,就可以完成按钮的动画效果,现在贴出来大家分享下,

如果觉得方便您可以自己建一个头文件,把代码放进去,每次程序调用该头文件

就可以轻松完成按钮的自绘。



代码如下:

/********************************************************************
**							定义自绘按钮类.			               **
**	DrawBtn类,允许用户自己绘制自己所要的按钮外观,如载入按钮表面贴图,   **
**  当鼠标在按钮上和离开按钮时候两种情况下的按钮外观.让按钮具有多样化   **
**  外观,使界面更加人性化.										   **
********************************************************************/


//调用所需头文件
#ifndef	WINDOWS_H
#define WINDOWS_H
#include <Windows.h>
#endif



class DrawBtn
{
public:
	//类构造函数
	DrawBtn(HWND hwndOfParent): 
			hwnd(hwndOfParent){}

	//创建按钮函数
	
	HWND CreateDrawButton(int uIdOfOnButton,				//鼠标在按钮上显示的图片
						  int uIdOfOffButton,				//鼠标离开按钮显示的图片
						  int xofposition,					//按钮在父窗口的X坐标
						  int yofposition,					//按钮在父窗口的Y坐标
						  int xofsize,						//按钮的宽度
						  int yofsize,						//按钮的高度
						  int IdOfButton) ;					//按钮ID

private:

	//私有成员变量定义
	HWND hwnd		 ;		//父窗口句柄	
	int uID_OnButton ;		//鼠标在按钮上时,绘制的贴图
	int uID_OffButton ;		//鼠标离开按钮时,绘制的贴图

	//私有成员函数定义
	static LRESULT CALLBACK ButtonProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)  ;
	void	MakeTheEffectButton(HWND hwnd) ;

};


/*************************************************
**	定义一个静态变量指针,因为回调函数在类中调用如果	**
** 不定义为static,则会隐含有this指针,返回的参数和	**
** 地址都有问题,定义为static就能锁定地址和参数。	**
** 而再一个静态的成员函数中调用非静态的变量,我们要	**
** 变量也为静态,但是变量为静态就不能接受用户给定的	**
** 值,因此我们定义一个静态的类类型指针,并为其申请	**
** 内存空间,用静态的类类型指针来引用非静态的变量,	**
** 就可以使非静态的变量在静态成员中使用。			**
*************************************************/
static DrawBtn* pthis = (DrawBtn*)malloc(sizeof(int)*2) ;


//返回上一个回调函数
WNDPROC	OldButtonProc ;

HWND DrawBtn::CreateDrawButton(int uIdOfOnButton, int uIdOfOffButton,
					int xofposition, int yofposition, int xofsize, int yofsize, int IdOfButton)
{
	//在父窗口创建按钮,并获得按钮句柄用于函数返回.
	HWND	hwndofButton ;
	hwndofButton = CreateWindow(TEXT("button"),TEXT(""),WS_CHILD | WS_VISIBLE | BS_BITMAP | BS_DEFPUSHBUTTON, 
						xofposition, yofposition, xofsize, yofsize, 
						hwnd, (HMENU)IdOfButton, (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE), NULL) ;

	pthis->uID_OnButton = uIdOfOnButton ;
	pthis->uID_OffButton = uIdOfOffButton ;


	//载入按钮初始化界面.即为鼠标离开按钮时候的界面.
	HBITMAP	hBitmap ;
	hBitmap = LoadBitmap((HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE), MAKEINTRESOURCE(pthis->uID_OffButton)) ;
	SendMessage(hwndofButton, BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBitmap);


	//载入按钮检测鼠标界面.
	MakeTheEffectButton(hwndofButton) ;
	return hwndofButton ;
}

LRESULT CALLBACK DrawBtn::ButtonProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	static BOOL bIsOnButton = FALSE;
	switch(uMsg)
	{
	case WM_MOUSEMOVE:
		{
			if(!bIsOnButton)
			{
				//定义结构体,用于返回鼠标按钮事件.
				TRACKMOUSEEVENT tme;
				tme.cbSize = sizeof(TRACKMOUSEEVENT);
				tme.dwFlags = TME_HOVER|TME_LEAVE;
				tme.hwndTrack = hwnd;
				tme.dwHoverTime = 1;
				TrackMouseEvent(&tme);
			}
		}
		break;

	case WM_MOUSEHOVER:
		{
			//鼠标在按钮上时.
			bIsOnButton = TRUE;
			HBITMAP hBmpOn = LoadBitmap((HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),
								MAKEINTRESOURCE(pthis->uID_OnButton));
			SendMessage(hwnd,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBmpOn);
			break;
		}
	case WM_MOUSELEAVE:
		{
			//鼠标离开按钮时.
			bIsOnButton = FALSE;
			HBITMAP hBmpOff = LoadBitmap((HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),
								MAKEINTRESOURCE(pthis->uID_OffButton));
			SendMessage(hwnd,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBmpOff);
			break;
		}
	}
	return CallWindowProc(OldButtonProc,hwnd,uMsg,wParam,lParam);
}

void DrawBtn::MakeTheEffectButton(HWND hwnd)
{
	OldButtonProc = (WNDPROC)SetWindowLong(hwnd,GWL_WNDPROC,(LONG)ButtonProc);
}

然后再MAIN函数中,你只要下面两句代码就能创建一个具有动画效果的按钮:

DrawBtn drawbtn(hwnd) ;        //调用DrawBtn类,并为其创建对象,初始化载入一个父窗口句柄。
     //改函数返回按钮句柄,IDB_BITMAP1和 IDB_BITMAP2是你希望鼠标在按钮上和离开按钮时候按钮的图片,需要你自己载入.
drawbtn.CreateDrawButton(IDB_BITMAP2,IDB_BITMAP1,220,20,40,20,ID_BUTTON) ;   

如果是VC6.0的用户,你可以需要自己再添加一些头文件和库文件,因为TRACKMOUSEEVENT结构只有在VS2010里面才是编译器自动载入的. 百度上有将得很详细载入什么库文件和头文件,这里我就不多说,也是只要两行代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值