tags:

views:

197

answers:

1

Hi, I just met a problem about WM_NCMOUSELEAVE.

I noticed that when a window is created, then just move the cursor over its caption, then a WM_NCMOUSELEAVE will be sent to it. There's no call of TrackMouseEvent().

I read MSDN, but get no clue. :(

thank you for your advise.

A: 

It actually isn't sent immediately after creation, but can be received anytime after creation if the window has a Non-Client area defined. Windows have two major regions, Client and Non-Client. The Non-Client area is the outer border/margin of a window, and the client area can be considered the 'body' of the window. This is the area where you will get the most activity, and usually this is the intended area of a window where a user should interact. Of course, sometimes other parties will make controls that have no non-client areas and yet still display their own borders and other details.

For almost all stock controls (anything in the Common Control Library and other window-based controls published by Microsoft), the following areas are treated as Non-Client areas.

  • Captions Caption Details
  • System Menu / Minimize / Maximize / Close
  • Borders

Messages that are prefixed with NC represent events that occurred in Non-Client areas of the window. Messages without the prefix are in the Client area.

Anyhow, I presume that you have a function that is tracking mouse events on a specific window. If there is a need to track any movement over the non-client areas of the window (say, for dragging or hover operations) you'll want to add the following messages to your mouse tracking.

  • WM_NCMOUSEMOVE

(mouse position has changed in a non-client area)

  • WM_NCLBUTTONDBLCLK
  • WM_NCLBUTTONDOWN
  • WM_NCLBUTTONUP

(left-button actions in non-client area)

  • WM_NCMBUTTONDBLCLK
  • WM_NCMBUTTONDOWN
  • WM_NCMBUTTONUP

(middle-button actions in non-client area)

  • WM_NCRBUTTONDBLCLK
  • WM_NCRBUTTONDOWN
  • WM_NCRBUTTONUP

(right-button actions in non-client area)

In addition, depending on your application, the following messages may be of interest as well.

  • WM_NCACTIVATE

(window activation has changed by user action and the non-client area needs to be updated)

  • WM_NCHITTEST

(window manager wants to know if the non-client area is tracking mouse activity)

  • WM_NCPAINT

(non-client area needs to be repainted)

A useful trick for determining the visual extent of a Non-Client area is to intercept the WM_NCPAINT message and just paint the non-client area in a color of your choice (red/pink or some other color that stands out). This is useful for debugging situations where you have multiple windows adjacent to each other with non-client areas that should appear seamless.

Finally, here is a link that has demo source code that may worth examining to see how Non-Client areas work.

Customizing the Non-client Area from CodeProject (VB)

meklarian
Thank you for your response ^_^But it isn't very helpful for my question :(My problem is, I create a window, and I want to track WM_NCMOUSELEAVE for some reason, so I add WM_NCMOUSELEAVE handler in the WINPROC. But I noticed that before I call TrackMouseEvent() to track WM_NCMOUSELEAVE, but after the window created, if I move the cursor over the non-client area, WINPROC will receive a WM_NCMOUSELEAVE, once and only once.I don't know why. So I post the question. I have tried to call TrackMouseEvent with TME_CANCEL to prevent the message, but it doesn't work. My system is WINXP with sp3.
cyberscorpio
When are you calling TrackMouseEvent()? According to the Documentation at MSDN, if the mouse is not in the relevant window area at the time it is called, it will post the message once and then exit. Try adding a handler for WM_NCMOUSEMOVE to your WndProc and setting up your call to TrackMouseEvent() there if it isn't already active. Once you have received a WM_NCMOUSELEAVE notification, you should call it again on the next WM_NCMOUSEMOVE message.
meklarian
Here's a link for TrackMouseEvent().http://msdn.microsoft.com/en-us/library/ms646265(VS.85).aspx
meklarian
yes, I call TrackMouseEvent() after some event happens, for example, when the user move the window, I call TrackMouseEvent(). But my question is, before TrackMouseEvent() and after the window is created, I 'll receive an unexpected WM_NCMOUSELEAVE once, only once. I don't know why, and I test it in two machine.
cyberscorpio
What is the window class name for your window? Are you creating a window based upon another party's window class?
meklarian