您的位置:首页 > 其它

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

2012-06-08 11:06 176 查看
之前很长一段时间,在做界面中的自绘按钮时,都是通过将控件子类化的办法,
切换按钮贴图来完成按钮的一些动画效果。但是,后来慢慢发现,每次做程序
界面画一个按钮都需要将按钮子类化,按钮多了过程就繁重,代码重复性也很
高,于是就想了个办法,将其封装成一个类,以后再做自绘按钮的时候 只要载
入这个类,调用一个函数,就可以完成按钮的动画效果,现在贴出来大家分享下,
如果觉得方便您可以自己建一个头文件,把代码放进去,每次程序调用该头文件
就可以轻松完成按钮的自绘。

代码如下:

/********************************************************************
**							定义自绘按钮类.			               **
**	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里面才是编译器自动载入的. 百度上有将得很详细载入什么库文件和头文件,这里我就不多说,也是只要两行代码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: