MFC WM_MOUSELEAVE和WM_MOUSEHOVER消息

MFC WM_MOUSELEAVE和WM_MOUSEHOVER

前言

学习书本,博客记录,便于往后回顾。

因为窗口接收WM_MOUSEMOVE消息,所以很容易知道光标何时进入了窗口或在窗口中移动了。使用**::TrackMouseEvent**,可以很容易确定光标何时离开窗口或在窗口上停止不动。
一个应用程序可以注册**::TrackMouseEvent**,当光标离开窗口时接收WM_MOUSELEAVE消息,而光标在窗口上方停滞时接收WM_MOUSEHOVER消息。

::TrackMouseEvent介绍

::TrackMouseEvent是一个结构体,只接收一个指向TRACKMOUSEEVENT结构体的指针参数,其在Winuser.h中如下:

typedef struct tagTRACEMOUSEEVENT{
	DWORD cbSize;
	DWORD dwFlags;
	HWND  hwndTrack;
	DWORD dwHoverTime;
}TRACEMOUSEEVENT

cbSize:保存结构的大小;

dwFlags:{ 保存位标志用来指定调用者想要执行的操作:
注册接收WM_MOUSELEAVE消息(TME_LEAVE);
注册接收WM_MOUSEHOVER消息(TME_HOVER);
取消WM_MOUSELEAVEWM_MOUSEHOVER消息(WM_CANCEL)
或允许系统用当前::TrackMouseEvent设置填写TRACEMOUSEEVENT结构(TME_QUERY)}

hwndTrack: 窗口的句柄,对此窗口将生成WM_MOUSELEAVEWM_MOUSEHOUVER消息。

dwHoverTime:以毫秒计时的时间长度,光标必须暂停这么久,WM_MOUSEHOVER消息才向它下面的窗口发送。可以设置dwHouverTime等于HOVER_DEFAULT,系统默认值400ms

光标并非必须纹丝不动系统才会产生WM_MOUSEHOVER消息。如果光标所在矩形的宽度和高度与用SPI_GETMOUSEHOVERWIDTHSPI_GETMOUSEHOVERHEIGTH参数调用::SystemParametersInfo 返回的值相同,并且它停留的时间与用SPI_GETMOUSEHOVERTIME调用SystemParametersInfo返回的值也相同时,就会产生WM_MOUSEHOVER消息。
可以使用SPI_SETMOUSEHOVERWIDTHSPI_SETMOUSEHOVERHEIGTHSPI_SETMOUSEHOVERTIME值调用::SystemParametersInfo来修改这些参数。

示例

下列代码段在鼠标进入、离开或停留在窗口上时将“Mouse enter”、“Mouse leave”、“Mouse hover”写道调试输出窗口。m_bMouseOver是CMainWindow的一个BOOL成员变量。

//.cpp
#define _WIN32_WINNT 0x400

//#include ...
#include <Afxwin.h>
//#include ...

//In message map
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER, OnMoudeHover)

void CMainWindow::OnMouseMove(UINT nFlags, CPoint point)
{
	if(!m_bMouseOver)
	{
		TRACE(_T("Mouse enter\n"));
		m_bMouseOver = TRUE;
	
		TRACKMOUSEEVENT tme;
		tme.cbSize = sizeof(tme);
		tme.dwFlags = TME_HOVER|TME_LEAVE;
		tme.hwndTrack = m_hWnd;
		tme.dwHoverTime = HOVER_DEFAULT;
		::TrackMouseEvent(&tme);
	}
}

LRESULT CMainWindow::OnMouseLeave(WParam wParam, LPARAM lParam)
{
	TRACE(_T("Mouse leave\n"));
	m_bMouseOver = FALSE;
	return 0;
}

LRESULT CMainWindow::OnMouseHover(WParam wParam, LPARAM lParam)
{
		TRACE(_T("Mouse hover(x= %d, y= %d)\n"), LOWORD(lParam), HIWORD(lParam));

		TRACKMOUSEEVENT tme;
		tme.cbSize = sizeof(tme);
		tme.dwFlags = TME_HOVER|TME_LEAVE;
		tme.hwndTrack = m_hWnd;
		tme.dwHoverTime = HOVER_DEFAULT;
		::TrackMouseEvent(&tme);
}	

在使用::TrackMouseEvent时需要注意,在产生WM_MOUSELEAVEWM_MOUSEHOVER消息时,它的影响就消失了。因此想要在光标离开或停留在窗口上时任何时候接收这些消息,就必须在接收到WM_MOUSELEAVE或WM_MOUSEHOVER消息时重新调用::TrackMouseEvent。

另外:伴随WM_MOUSEHOVER消息的lParam参数值在它的高位字保存了光标的y坐标,在低位字保存了光标的x坐标。wParam未被使用。在WM_MOUSELEAVE消息中lParam和wParam都未被使用。

最后关于::TrackMouseEvent的使用,必须在源代码中确保在#include <Afxwin.h>之前包括下列#define语句:
#define _WIN32_WINNT 0x400

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值