ID: Q183107
The information in this article applies to:
Microsoft Windows NT 4.0 and Microsoft Windows 98 provide the TrackMouseEvent API to notify a window that the mouse has left the window. Windows 95 does not provide any such notification. An application can detect when the mouse exits a window by starting a timer when the mouse enters the window, and using that timer to monitor the mouse position and find when it is no longer within the window.
The following sample code provides an example of how to implement mouse leave detection on Windows NT 3.51 and Windows 95 so that it follows TrackMouseEvent's interface. Implementation of the WM_MOUSEHOVER functionality is left to the discretion of the reader.
#if(_WIN32_WINNT < 0x0400)
#define WM_MOUSELEAVE WM_USER+2
#define TME_LEAVE 1
typedef struct tagTRACKMOUSEEVENT {
DWORD cbSize;
DWORD dwFlags;
HWND hwndTrack;
} TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT;
VOID CALLBACK
TrackMouseTimerProc(HWND hWnd,UINT uMsg,UINT idEvent,DWORD dwTime) {
RECT rect;
POINT pt;
GetClientRect(hWnd,&rect);
MapWindowPoints(hWnd,NULL,(LPPOINT)&rect,2);
GetCursorPos(&pt);
if (!PtInRect(&rect,pt) || (WindowFromPoint(pt) != hWnd)) {
if (!KillTimer(hWnd,idEvent)) {
// Error killing the timer!
}
PostMessage(hWnd,WM_MOUSELEAVE,0,0);
}
}
BOOL
TrackMouseEvent(LPTRACKMOUSEEVENT ptme) {
OutputDebugString(TEXT("TrackMouseEvent\n"));
if (!ptme || ptme->cbSize < sizeof(TRACKMOUSEEVENT)) {
OutputDebugString(TEXT("TrackMouseEvent: invalid "
"TRACKMOUSEEVENT structure\n"));
return FALSE;
}
if (!IsWindow(ptme->hwndTrack)) {
OutputDebugString(
TEXT("TrackMouseEvent: invalid hwndTrack\n"));
return FALSE;
}
if (!(ptme->dwFlags & TME_LEAVE)) {
OutputDebugString(TEXT("TrackMouseEvent: invalid dwFlags\n"));
return FALSE;
}
return SetTimer(ptme->hwndTrack, ptme->dwFlags,
100,(TIMERPROC)TrackMouseTimerProc);
}
#endif
LRESULT CALLBACK
MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
TRACKMOUSEEVENT tme;
static BOOL fInWindow;
static BOOL fInMenu;
switch (uMsg) {
case WM_CREATE:
fInWindow = FALSE;
fInMenu = FALSE;
return 0;
case WM_MOUSEMOVE:
if (!fInWindow) {
fInWindow = TRUE;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hWnd;
if (!TrackMouseEvent(&tme)) {
MessageBox(hWnd,
TEXT("TrackMouseEvent Failed"),
TEXT("Mouse Leave"),MB_OK);
}
}
break;
case WM_MOUSELEAVE:
fInWindow = FALSE;
if (!fInMenu)
MessageBox(hWnd,TEXT("Elvis has left the building"),
TEXT("Mouse Leave"),MB_OK);
break;
case WM_ENTERMENULOOP:
fInMenu = TRUE;
break;
case WM_EXITMENULOOP:
fInMenu = FALSE;
break;
default:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
return FALSE;
}
(c) Microsoft Corporation 1997, All Rights Reserved.
Contributions by Rob Caplan, Microsoft Corporation
Additional query words:
Keywords : kbcode kbInput kbMouse kbNTOS350 kbNTOS351 kbNTOS400 kbGrpUser kbWinOS95 kbWinOS98 kbWndw kbWndwMsg
Issue type : kbhowto
Last Reviewed: December 17, 1998