当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 设计XP风格的按钮

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 设计XP风格的按钮


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 117 ::
收藏到网摘: n/a

设计XP风格的按钮
作者:郑恒(lbird)

下载本文示例代码

论坛上许多人都在讨论如何编写具有XP风格的界面,其实网上有设计好的类库,可以直接拿来使用。但这些终归是别人写的,能不能转化成自已的呢。于是笔者就对这些代码进行研究,算是偷一点吧:)
研究了几种控件,这里就把其中最简单的按钮控件拿来供大家一起讨论。
这是程序的运行效果:

步骤:
1、创建一个派生自CButton的新类CButtonXp
2、重载PreSubClassWindow()函数,在该函数内修改按钮的风格为自绘制(owner):
添加如下代码:ModifyStyle(0,BS_OWNERDRAW);
3、因为XP风格按钮具有鼠标感应的效果,当鼠标移动到按钮上方时,按钮的颜色会改变。所以就必须跟踪鼠标。当鼠标移到按钮上方时,窗口会收到
WM_MOUSEMOVE消息,但怎么才能得知鼠标离开按钮呢?
这里我们使用 TrackMouseEvent() Api函数:
BOOL TrackMouseEvent( LPTRACKMOUSEEVENT lpEventTrack );
参数:
typedef struct tagTRACKMOUSEEVENT {
DWORD cbSize; //结构大小
DWORD dwFlags; //设定为TME_LEAVE
HWND hwndTrack; //要跟踪鼠标的窗口句柄
DWORD dwHoverTime;} TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT;
调用该函数可以在鼠标离开指定窗口时收到WM_MOUSELEAVE消息。

添加成员变量:m_bOver ,初始化为FALSE。m_bOver=true用来表示鼠标在按钮区域。
添加WM_MOUSEMOVE消息处理函数:
void CButtonXp::OnMouseMove(UINT nFlags, CPoint point) {	if(m_bOver ==FALSE)	{	//鼠标在按钮之上	m_bOver =TRUE;	//按钮重绘	InvalidateRect(NULL,FALSE);	//跟踪鼠标	//当鼠标离开按钮区域会收到WM_MOUSELEAVE,该消息直接调用OnMouseOut()	TRACKMOUSEEVENT	tme;	tme.cbSize =sizeof(TRACKMOUSEEVENT);	tme.dwFlags =TME_LEAVE;	tme.dwHoverTime=0;	tme.hwndTrack =m_hWnd;	::TrackMouseEvent(&tme);	}	CButton::OnMouseMove(nFlags, point);}
再添加一成员函数OnMouseOut(),
并在BEGIN_MESSAGE_MAP(CButtonXp, CButton)和END_MESSAGE_MAP()之间添加
宏 ON_MESSAGE(WM_MOUSELEAVE,OnMouseOut)

在OnMouseOut()中写入以下代码

void CButtonXp::OnMouseOut (){	//鼠标已离开按钮区域 m_bOver =FALSE;	//重绘按钮	InvalidateRect(NULL,FALSE);	}
4、添加成员函数 MouseOver()
//返回鼠标是否在按钮区域内BOOL CButtonXp::MouseOver(){	return m_bOver;}
5、最后重载DrawItem(LPDRAWITEMSTRUCT lpDIS)
void CButtonXp::DrawItem(LPDRAWITEMSTRUCT lpDIS) {	CDC	*pDC =CDC::FromHandle(lpDIS->hDC);	CRect	rtControl(lpDIS->rcItem);	CPen	pen,*old_pen;	CBrush	brush,*old_brush;	CString strText;	HFONT hOldFont = (HFONT)pDC->SelectObject ((HFONT)::GetStockObject (DEFAULT_GUI_FONT));	UINT	state =lpDIS->itemState;	if(state & ODS_FOCUS)	{	rtControl.DeflateRect(1,1);	//拥有焦点矩形变小	}	if((state & ODS_DISABLED) ||	(!MouseOver() &&!(state & ODS_SELECTED)))	{	//普通状态、禁用、拥有焦点三种情况下	pen.CreatePen (PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));	brush.CreateSolidBrush(HLS_TRANSFORM(::GetSysColor(COLOR_3DFACE),-10,0));	}	else	{	COLORREF	crBorder =::GetSysColor(COLOR_HIGHLIGHT);	pen.CreatePen(PS_SOLID, 1, crBorder);	if( state & ODS_SELECTED)	{	//按钮按下时	brush.CreateSolidBrush(HLS_TRANSFORM(crBorder,+50,-50));	pDC->SetTextColor(RGB(240,240,240));	}	else	{	//鼠标在区域内	brush.CreateSolidBrush(HLS_TRANSFORM(crBorder,+80,-66));	pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));	}	}	if(state &ODS_DISABLED)	pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));//灰色字:禁用状态	else if(state & ODS_SELECTED)	pDC->SetTextColor(RGB(240,240,240));	//白色字:PUSH状态	else if(MouseOver())	pDC->SetTextColor(0);	//黑色字:热感应状态	else	pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));	//黑色字:普通状态	old_brush=pDC->SelectObject(&brush);	old_pen =pDC->SelectObject(&pen);	pDC->Rectangle(rtControl);	pDC->SetBkMode(TRANSPARENT);	GetWindowText(strText);	pDC->DrawText(strText,rtControl,DT_SINGLELINE|DT_CENTER|DT_VCENTER);	if(state & ODS_FOCUS)	{	rtControl.Def