Why is there no WM_MOUSEENTER message?

Date:October 13, 2003 / year-entry #93
Tags:code
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20031013-00/?p=42193
Comments:    6
Summary:There is a WM_MOUSELEAVE message. Why isn't there a WM_MOUSEENTER message? Because you can easily figure that out for yourself. When you receive a WM_MOUSELEAVE message, set a flag that says, "The mouse is outside the window." When you receive a WM_MOUSEMOVE message and the flag is set, then the mouse has entered the window....

There is a WM_MOUSELEAVE message. Why isn't there a WM_MOUSEENTER message?

Because you can easily figure that out for yourself.

When you receive a WM_MOUSELEAVE message, set a flag that says, "The mouse is outside the window." When you receive a WM_MOUSEMOVE message and the flag is set, then the mouse has entered the window. (And clear the flag while you're there.)

Let's illustrate this with our sample program, just to make sure you get the idea:

BOOL g_fMouseInClient;
void OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
{
    if (!g_fMouseInClient) {
        g_fMouseInClient = TRUE;
        MessageBeep(0);
        TRACKMOUSEEVENT tme = { sizeof(tme) };
        tme.dwFlags = TME_LEAVE;
        tme.hwndTrack = hwnd;
        TrackMouseEvent(&tme);
    }
}
    case WM_MOUSELEAVE: g_fMouseInClient = FALSE; return 0;
    HANDLE_MSG(hwnd, WM_MOUSEMOVE, OnMouseMove);

This program beeps whenever the mouse enters the client area.

Exercise: If the program starts with the mouse already in the client area without moving, why do you get a beep?


Comments (6)
  1. Damit says:

    Is it because g_fMouseInClient is initialized to 0 (FALSE) ?

  2. Raymond Chen says:

    That’s half of it. But the mouse never moved, so why does it beep?

  3. YOu explained it two weeks ago in your post "Why do I get spurious WM_MOUSEMOVE messages?": "Often, Windows wants to do that follow-on work even though the mouse hasn’t actually moved. The most obvious example is when a window is shown, hidden or moved."

  4. Ian Hanschen says:

    just taking a stab at it..

    When an app calls GetMessage(), the WM not only dispatches messages from other threads and clears out the message queue, but it also checks the system input queue. <guessing part because I’ve not verified> This code checks the win32thread structure for the timestamp of the last mouse message sent. If it is 0, or does not match, a WM_MOUSEMOVE input message with the current timestamp is pushed onto the message queue.

  5. Dmitriy Zaslavskiy says:

    Raymond,
    Sorry for off topic question, could you blog about using user API from multiple theads, and GUI api (i.e. painting from multiple threads onto the same window). Normally user handles are scopped by desktop and so it seems that multiple threads are already using user/gui subsystems from multiple threads, yet there are some API such as DestroyWindow that require explicitly to be called from the creator thread. There are also some info about "trying" not creating parent/child windows from diff. threads.
    Could you comment on the source of all that. Is GDI/USER code multithread safe or not?
    Thanks in advance.

  6. Karl says:

    I would assume Windows sends a WM_MOUSEMOVE to apps on startup if the cursor is inside the client area because some apps need to know the position of the mouse cursor whenever it is inside the client area to maintain a consistant user experience. For example, if you launch a web browser with a page that has a link directly under the mouse cursor, you’d expect the cursor to change immediately to indicate it’s a link.

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index