想要让鼠标经过按钮时,按钮上的图像发生改变,首先要知道的是,鼠标什么时候在按钮上。这里有一个很有用的函数
BOOL TrackMouseEvent(
LPTRACKMOUSEEVENT lpEventTrack // pointer to a TRACKMOUSEEVENT
// structure
);
它可以用来跟踪鼠标是否在某一个区域上,是否离开某个区域。
它的参数是一个结构LPTRACKMOUSEEVENT,在该结构内可以指出要跟踪鼠标的什么行为,以及在什么区域内进行跟踪。
typedef struct tagTRACKMOUSEEVENT {
DWORD cbSize;
DWORD dwFlags;
HWND hwndTrack;
DWORD dwHoverTime;
} TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT;
Members
-
cbSize
- Specifies the size of the TRACKMOUSEEVENT structure. dwFlags
-
Specifies the services requested. This member can be a combination of the following values:
Value Meaning TME_CANCEL The caller wants to cancel a prior tracking request. The caller should also specify the type of tracking that it wants to cancel. For example, to cancel hover tracking, the caller must pass the TME_CANCEL and TME_HOVER flags.
TME_HOVER The caller wants hover notification. Notification is delivered as a WM_MOUSEHOVER message. If the caller requests hover tracking while hover tracking is already active, the hover timer will be reset.
This flag is ignored if the mouse pointer is not over the specified window or area.
TME_LEAVE The caller wants leave notification. Notification is delivered as a WM_MOUSELEAVE message. If the mouse is not over the specified window or area, a leave notification is generated immediately and no further tracking is performed.
TME_QUERY The function fills in the structure instead of treating it as a tracking request. The structure is filled such that had that structure been passed to TrackMouseEvent it would generate the current tracking. The only anomaly is that the hover timeout returned is always the actual timeout and not HOVER_DEFAULT, if HOVER_DEFAULT was specified during the original TrackMouseEvent request.
hwndTrack
- Specifies the handle of the window to track. dwHoverTime
- Specifies the hover timeout (if TME_HOVER was specified in dwFlags), in milliseconds. Can be HOVER_DEFAULT, which means to use the system default hover timeout.
Remarks
The system default hover timeout is initially the menu dropdown time, which is 400 milliseconds. You can call SystemParametersInfo and use SPI_GETMOUSEHOVERTIME to retrieve the default hover timeout.
The system default hover rectangle is the same as the double-click rectangle. You can call SystemParametersInfo and use SPI_GETMOUSEHOVERWIDTH and SPI_GETMOUSEHOVERHEIGHT to retrieve the size of the rectangle within which the mouse pointer has to stay for TrackMouseEvent to generate a WM_MOUSEHOVER message.
下面来通过一个实例来讲述:
BOOL CHotButton::IsCursorOn()
{
TRACKMOUSEEVENT mouseEve;
mouseEve.cbSize=sizeof(mouseEve);
mouseEve.dwFlags=TME_LEAVE;
mouseEve.dwHoverTime=HOVER_DEFAULT;
mouseEve.hwndTrack=GetSafeHwnd();
return _TrackMouseEvent(&mouseEve);
}
该函数的功能是判断鼠标是否在某一个控件上。
dwFlags=TME_LEAVE,由MSDN上的说明可以知道,当鼠标离开指定区域时会发出消息WM_MOUSELEAVE ,由此我们对鼠标离开该区域时的处理操作就可以放到WM_MOUSELEAVE 的响应函数OnMouseLeave(...)中。
mouseEve.hwndTrack=GetSafeHwnd();指明了跟踪鼠标的区域,GetSafeHwnd();得到本对象的句柄,如果有一按钮声明成了类CHotButton的对象,则GetSafeHwnd();得到的就是这个按钮的句柄,从而当鼠标离开这个按钮时就会有消息WM_MOUSELEAVE 发出。
void CHotButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//AfxMessageBox("good");
if(IsCursorOn())//如果鼠标在按钮上
{
if(!flag)//flag用来标记鼠标是否走出按钮的范围,如果没有走出,则按钮图像在第一次变化过后就不再变化
{
flag=TRUE;
if(ID_B1!=NULL)//如果没有指定图像,就不加载图像
this->LoadBitmaps(ID_B1,ID_B2);//加载图像
InvalidateRgn(NULL,true);//更新按钮区域
}
}
else//如果不在,则将消息交给上层处理
{
CBitmapButton::OnMouseMove(nFlags, point);
}
}
上面这个函数当鼠标在按钮上进行移动时进行相应处理,如果不在,就不对鼠标移动事件进行处理。
LRESULT CHotButton::MouseLeave(WPARAM wParam, LPARAM lParam)
{
flag=FALSE;
if(ID_B1!=NULL)//如果没有指定图像,就不加载图像
this->LoadBitmaps(ID_B1,ID_B2);//加载图像
InvalidateRgn(NULL,true);//更新按钮区域
return 0;
}
上面这个函数当鼠标离开时更新按钮的图像。
由上面两个函数便可以实现鼠标经过按钮时按钮的图像发现改变这一功能。