默认情况下Windows窗体是不会响应WM_MOUSELEAVE和WM_MOUSEHOVER消息的,通过使用_TrackMouseEvent这个函数可以激活这两个消息。在调用这个函数后,当鼠标在指定窗口上停留超过一定时间或离开窗口后,该函数会就会发送这两个消息到指定窗口。
为了使窗体追踪鼠标事件,首先需要定义 isMouseTrack变量来标识窗体是否在追踪当前鼠标状态,这样就能避免鼠标已经在窗体之上时,一移动鼠标就不断重复产生WM_MOUSEHOVER。在窗体初始化时将isMouseTrack初始化为0。
_TrackMouseEvent函数需要用到结构体TRACKMOUSEEVENT,该结构体的定义如下:
TRACKMOUSEEVENT struct
cbSize dword ? ;该结构体的大小
dwFlags dword ? ;定义服务请求,可以是TME_CANCEL,TME_LEAVE,TME_HOVER的组合值,
;TME_CANCEL用来取消前一次的跟踪请求
hwndTrack dword ? ;指定要追踪的窗口
dwHoverTime dword ? ;定义hover事件的耗尽时间,单位是毫秒
TRACKMOUSEEVENT ends
在窗体消息处理函数处理WM_MOUSEMOVE事件中调用_TrackMouseEvent函数,并将isMouseTrack中的值修改为1,表示开始追踪鼠标状态。在窗体消息处理函数中添加处理WM_MOUSELEAVE和WM_MOUSEHOVER事件的代码,在处理WM_MOUSELEAVE事件时,将isMouseTrack置为0,表示再次允许追踪鼠标状态。
_ProcWnd proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
local @tME:TRACKMOUSEEVENT
mov eax,uMsg
;*******************************************************************************************
.if eax == WM_MOUSEMOVE
.if isMouseTrack == 0
mov @tME.cbSize,sizeof TRACKMOUSEEVENT
mov @tME.dwFlags,TME_LEAVE
push hWnd
pop @tME.hwndTrack
mov @tME.dwHoverTime,1
invoke _TrackMouseEvent,addr @tME
mov isMouseTrack,1
.endif
;*******************************************************************************************
.elseif eax == WM_MOUSELEAVE
mov isMouseTrack,0
;*******************************************************************************************
.elseif eax == WM_MOUSEHOVER
;do something
;*******************************************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
_ProcWnd endp