VC2005下高级彩色按钮的实现
MoaKap 2007-9-3
所谓高级彩色按钮,就是按钮在鼠标单击、选中等操作中,呈现不同的颜色,使应用程序更加美观。
我们首先定义按钮的几种状态,根据需要,又下面几种状态:
0. 默认状态
1. 焦点状态——鼠标放置在按钮上时按钮的状态
2. 选中状态——按钮被按下时的状态
要制作高级彩色按钮,必须对CButton按钮类进行重载。下面详细介绍高级彩色按钮的实现过程:
1、 根据应用需要使用普通按钮设计程序的界面。
2、 将按钮的Owner Draw属性设置为TRUE。
3、 新建CAdvButton类,其父类为CButton。
4、 在CAdvButton类中添加下列私有成员变量:
1) Int m_State 按钮的状态标志,分别取0,1,2
2) CPoint m_Point 点变量,用来捕捉鼠标的当前位置
3) Int m_IsTimerOn 定时器标示,指示定时器状态
5、 设置鼠标单击(按钮被按下)时的操作
利用MFC ClassWizard向导为CAdvButton类添加WM_LBUTTONDOWN消息的响应函数,在该函数中得到当前鼠标的位置和按钮的客户区域 ,当鼠标位置在按钮客户区域是,设置为选中状态。
void CAdvButton::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rect;
GetWindowRect(&rect); //得到按钮的客户区域
GetCursorPos(&m_Point); //得到鼠标的当前位置
if((rect.PtInRect(m_Point))&&(m_State != 2)) //判断鼠标是否在客户区域
{
m_State = 2; //设置按钮为选中状态
Invalidate();
}
CButton::OnLButtonDown(nFlags, point);
}
6、 设置松开鼠标左键(按钮弹起)的操作
利用MFC ClassWizard向导为CAdvButton类添加WM_LBUTTONUP消息的响应函数。当鼠标位置在按钮客户区域时,将按钮状态设置成焦点状态。
void CAdvButton::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rect;
GetWindowRect(&rect); //得到按钮的客户区域
GetCursorPos(&m_Point); //得到鼠标的当前位置
if((rect.PtInRect(m_Point))&&(m_State != 1)) //判断鼠标是否在客户区域
{
m_State = 1; //设置按钮为焦点状态
Invalidate();
}
CButton::OnLButtonUp(nFlags, point);
}
7、 设置鼠标移动过按钮的操作
利用MFC ClassWizard向导为CAdvButton类添加WM_MOUSEMOVE消息的响应函数。在函数中获得按钮的客户区域和鼠标当前位置。当鼠标位置在按钮客户区域时,将按钮状态设置成焦点状态。
void CAdvButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if(!m_IsTimerOn)//检测到鼠标移动,打开定时器,定期检测鼠标的位置是否在按钮客户区域
{
SetTimer(1000,10,NULL);//启动定时器,定时器时间为1000mS,检测周期为10ms.
m_IsTimerOn = TRUE;
}
CButton::OnMouseMove(nFlags, point);
}
利用MFC ClassWizard向导为CAdvButton类添加WM_TIMER消息的响应函数。在函数 中检测鼠标的当前位位 置,根据当前位置设置按钮的状态。
void CAdvButton::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rect;
GetWindowRect(&rect); //得到按钮的客户区域
GetCursorPos(&m_Point); //得到鼠标的当前位置
if(rect.PtInRect(m_Point)) //判断鼠标是否在客户区域
{
if((m_State != 1)&&(m_State != 2))
{
m_State = 1; //设置按钮为焦点状态
Invalidate();
}
}
else
{
if(m_State != 0)
{
m_State = 0; //将按钮状态设置为默认状态
Invalidate();
}
KillTimer(nIDEvent);
m_IsTimerOn = FALSE;
}
CButton::OnTimer(nIDEvent);
}
8、 为CAdvButton类添加DrawItem函数,在函数中对按钮客户区域进行绘制。
void CAdvButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: 添加您的代码以绘制指定项
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
GetClientRect(&m_ClientRect); //得到客户区域的设备环境变量
switch(m_State) //根据按钮状态分别对按钮客户区填充不同的颜色
{
case 0:
pDC->FillRect(&m_ClientRect,new CBrush(RGB(225,225,255)));
break;
case 1:
pDC->FillRect(&m_ClientRect,new CBrush(RGB(192,192,255)));
break;
case 2:
pDC->FillRect(&m_ClientRect,new CBrush(RGB(225,225,255)));
break;
}
char *pCaption = new char[MAXCAPTION];
int iLen = GetWindowText((LPTSTR)pCaption,MAXCAPTION);//得到按钮标题
pDC->SetBkMode(TRANSPARENT);//设置背景模式为透明
pDC->SetTextColor(TEXTCOLOR); //设置按钮字体颜色
pDC->DrawText((LPTSTR)pCaption,iLen,&m_ClientRect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);//绘制标题
}
9、 在对话框中显示按钮
在应用程序对话框文件中包含CAdvButton类,#include “CAdvButton.h”
直接将对话框中的按钮变量类型设置成CAdvButton类型即可。
我们还可以根据不同功能设置不同颜色系列的按钮。