最近在学习按钮的自绘.关于按钮的自绘,主要的难点如下:
1. 如果想要做到的效果稍微有点美观的话,我想这几个状态时必须要考虑的:鼠标移入、鼠标按下、鼠标弹起、鼠标移开.然后相应对其处理即可.这里主要讨论如何捕捉这些事件:首先是鼠标按下和鼠标弹起事件,这两个事件比较简单,windows已经和我们写好了这两个响应消息(我们只需重载他们即可).一个是OnLButtonUp一个是OnLButtonDown..我们可以在鼠标按下和弹起时设置一个标志位即可.其实我们可以再DrawItem里面进行判断.(这个东西可以再下面看到)其次是鼠标进入和鼠标移开消息.你不要认为我们可以重载OnMouseMove和OnMouseLeave这两个消息即可.其实这两类消息比较"特殊"(因为Windows并没有直接替我们对其处理),我们需要借助windows的一个函数(TrackMouseEvent)来进行判断、处理.大概的处理是这样的:我们在OnMouseMOve响应函数里面添加如下代码:
//其中bHighlight是标示变量:标示鼠标是否在按钮上.
if ( !bHighlight )
{
bHighlight = TRUE;
TRACKMOUSEEVENT tm;
tm.cbSize = sizeof( TRACKMOUSEEVENT );
tm.dwFlags = TME_LEAVE;
tm.dwHoverTime = 0;
tm.hwndTrack = m_hWnd;
::TrackMouseEvent( &tm );
}
//按钮重绘
InvalidateRect(NULL,TRUE);
这样之后,我们就安装了类似的一个鼠标离开函数:OnMouseLeave.
现在我们来添加这个函数的消息响应:
void CLinkButton::OnMouseLeave( WPARAM wParam,LPARAM lParam )
{
if ( bHighlight )
{
//重绘按钮
bHighlight = FALSE;
}
//注意这个语句,如果我们不进行界面刷新,那么很可能界面不能处理鼠标移开消息.
InvalidateRect( NULL,TRUE );
}
两种类的消息添加好了之后我们还要做一些类似初始化的工作,让WM_MOUSELEAVE和OnMouseLeave对应,还有,我们要使用::TrackMouseEvent两个函数,必须要包含这样一个声明:
extern "C" WINUSERAPI BOOL WINAPI TrackMouseEvent(LPTRACKMOUSEEVENT lpEventTrack);.如果不是如此,编译器是不认识TrackMouseEvent这个函数的.
关于TRACKMOUSEEVENT这个结构体的详细情况,请参考我的另一篇博客.
博客地址:http://blog.youkuaiyun.com/yuanweihuayan/article/details/6831248
2. 接着是定义好几种不同的状态.分别对应前面四种状态.
这里主要是关于系统颜色的获取.
◆ COLOR_3DHIGHLIGHT和 COLOR_GRAYTEXT两种颜色来做到Disable.
◆ COLOR_3DSHADOW 和COLOR_3DHILIGHT两种颜色来做到鼠标按下状态
这里你可以参考GetSystemColor函数.
DWORD GetSysColor(int nIndex); | ||||||
说明 | ||||||
判断指定windows显示对象的颜色 | ||||||
返回值 | ||||||
Long,指定对象的RGB颜色 | ||||||
参数表 | ||||||
参数 |
类型及说明 | |||||
nIndex |
Long,一个常数,指出特定的windows显示对象,如下表 | |||||
Windows对象常数表 | ||||||
常数定义 |
Windows对象 |
常数定义 |
Windows对象 | |||
COLOR_ACTIVEBORDER |
活动窗口的边框 |
COLOR_ACTIVECAPTION |
活动窗口的标题 | |||
COLOR_APPWORKSPACE |
MDI桌面的背景 |
COLOR_BACKGROUND |
windows桌面 | |||
COLOR_BTNFACE |
按钮 |
COLOR_BTNHIGHLIGHT |
按钮的3D加亮区 | |||
COLOR_BTNSHADOW |
按钮的3D阴影 |
COLOR_BTNTEXT |
按钮文字 | |||
COLOR_CAPTIONTEXT |
窗口标题中的文字 |
COLOR_GRAYTEXT |
灰色文字;如使用了抖动技术则为零 | |||
COLOR_HIGHLIGHT |
选定的项目背景 |
COLOR_HIGHLIGHTTEXT |
选定的项目文字 | |||
COLOR_INACTIVEBORDER |
不活动窗口的边框 |
COLOR_INACTIVECAPTION |
不活动窗口的标题 | |||
COLOR_INACTIVECAPTIONTEXT |
不活动窗口的文字 |
COLOR_MENU |
菜单 | |||
COLOR_MENUTEXT |
菜单正文 |
COLOR_SCROLLBAR |
滚动条 | |||
COLOR_WINDOW |
窗口背景 |
COLOR_WINDOWFRAME |
窗框 | |||
COLOR_WINDOWTEXT |
窗口正文 |
COLOR_3DDKSHADOW |
3D深阴影 * | |||
COLOR_3DFACE |
3D阴影化对象的正面颜色 * |
COLOR_3DHILIGHT |
3D加亮颜色(win95) | |||
COLOR_3DLIGHT |
3D阴影化对象的浅色 * |
COLOR_INFOBK |
工具提示的背景色 * | |||
COLOR_INFOTEXT |
工具提示的文本色 * |
|
| |||
*:带 * 号的常数未获NT 3.51的支持 |
3. 关于DrawItem的一些讲解:
详细请见:http://blog.youkuaiyun.com/yuanweihuayan/article/details/6817631
关键是如下结构体:DRAWITEMSTRUCT.这个里面我们经常用到的一些成员.
itemState:表示当前的状态:需要和ODS_开头的宏与操作即可.
rcItem:控件的大小.
hDC:可以通过它来获取当前控件的CDC.
另外就是几个CDC常用的成员函数:
Draw3dRect:用来绘制3D按钮.
DrawFocusRect:绘制具有焦点的矩形.
具体的用法可以参考msdn.
今天大概就总结这么一些.等以后看到了更好的再继续....