HOWTO: Detect When the Cursor Leaves the Window
ID: Q183107
|
The information in this article applies to:
-
Microsoft Win32 Software Development Kit (SDK)
-
Microsoft Windows NT, versions 3.5, 3.51, 4.0
-
Microsoft Windows 95
-
Microsoft Windows 98
SUMMARY
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.
MORE INFORMATION
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.
Sample Code
#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;
}
© 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
Version : WINDOWS:95; winnt:3.5,3.51,4.0
Platform : WINDOWS winnt
Issue type : kbhowto