I am relatively novice in WIN32 API and have problems with the code shown below, which is from my WinProc function: I use TrackMouseEvent with TME_HOVER to get a WM_MOUSEHOVER when the mouse cursor stays for a while in my window. This works if I call TrackMouseEvent on each WM_MOUSEMOVE, but not if I call in only once somewhere else. Why? (this is the 1st question)
When I receive WM_MOUSEHOVER I create a POPUP window, which I can see, and call again TrackMouseEvent for TME_LEAVE. This works and I receive WM_MOUSELEAVE when the mouse cursor leaves my window, then I want to hide and destroy the popup window (the HWND of which I stored in a static variable) but this does not work, the popup windows stays there. Why? (this is the 2nd question)
Can anybody give me an example or link to a simple example showing TrackMouseEvent and PopUp windows? Many Thanks.
case WM_MOUSEMOVE:
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_HOVER;
tme.hwndTrack = hSBox;
TrackMouseEvent(&tme);
}
break;
case WM_MOUSEHOVER:
{
hPop = CreateWindowEx(WS_EX_STATICEDGE, //WS_EX_CLIENTEDGE,
TEXT("STATIC"),
TEXT("pop-up"),
WS_POPUP | WS_BORDER,
100, 100, 100, 100,
hWnd, (HMENU)0, hInstance, NULL);
ShowWindow(hPop, SW_SHOW);
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hSBox;
TrackMouseEvent(&tme);
}
return 0;
case WM_MOUSELEAVE:
{
ShowWindow(hPop, SW_HIDE);
DestroyWindow(hPop);
}
return 0;
There are two problems that I can see:
Your problem with TME_HOVER
is because you're not initialising the dwHoverTime
member; you should set it to HOVER_DEFAULT
. Otherwise the hover timeout will be set to whatever random value is on the stack.
Your second problem is that each call to TrackMouseEvent
overrides the previous one. Because you're calling TrackMouseEvent
on every WM_MOUSEMOVE
message, the TME_LEAVE
call is quickly being overridden by your next TME_HOVER
call.
The solution to this is to use some sort of flag in your WM_MOUSEMOVE
handler, so that you only call TrackMouseEvent
once, when the mouse first enters your window. Tracking is cancelled when you get the WM_MOUSEHOVER
and WM_MOUSELEAVE
messages, so at those points you'd reset the flag so that next time you get WM_MOUSEMOVE
you can start it again if necessary.
// note: BOOL g_fMouseTracking needs to be declared in the same place
// hPop is
case WM_MOUSEMOVE:
if (!g_fMouseTracking && !hPop)
{
// start tracking if we aren't already
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_HOVER | TME_LEAVE;
tme.hwndTrack = hSBox;
tme.dwHoverTime = HOVER_DEFAULT;
g_fMouseTracking = TrackMouseEvent(&tme);
}
break;
case WM_MOUSEHOVER:
g_fMouseTracking = FALSE; // tracking now cancelled
if (!hPop)
{
hPop = CreateWindowEx(WS_EX_STATICEDGE, //WS_EX_CLIENTEDGE,
TEXT("STATIC"),
TEXT("pop-up"),
WS_POPUP | WS_BORDER,
100, 100, 100, 100,
hWnd, (HMENU)0, hInstance, NULL);
ShowWindow(hPop, SW_SHOW);
// set up leave tracking
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hSBox;
g_fMouseTracking = TrackMouseEvent(&tme);
}
return 0;
case WM_MOUSELEAVE:
g_fMouseTracking = FALSE; // tracking now cancelled
if (hPop)
{
// close popup if it's open
ShowWindow(hPop, SW_HIDE);
DestroyWindow(hPop);
hPop = NULL;
}
return 0;