Problems when subclassing controls

By Stephen Kellett
19 November, 2010

I’m developing a graph control for use in our Memory Validator software tool.

Graph Custom Control

Tracking a mouse
One of the requirements was that we need to monitor mouse move messages on the control so that we can update some on-the-fly statistics related to where the mouse cursor is in the graph. No problem, add a ON_WM_MOUSEMOVE() message map entry and an OnMouseMove() method to the class (I’m using MFC) and that should be it. Easy.

Transparent hit tests
That’s what I thought until it didn’t work. Very confusing. Checked some other controls we’ve written and they all work OK. What is different about this control? After some head scratching and testing I decided to run Spy++ to monitor the windows messages being sent to our custom control. What a surprise that was. The only messages the custom control was generating were WM_NCHITTEST messages to see if the mouse cursor was in the control. Rather than return HTCLIENT or something similar the control was returning HTTRANSPARENT. Why would it do that?

Why is it transparent?
The reason the control is returning HTTRANSPARENT is because I’ve used a CStatic frame control to place my control in the resource editor and then I subclass that CStatic with my custom control. If I don’t override OnNcHitTest() method and add WM_ON_NCHITTEST() to the message map then I get the hit testing functionality from the CStatic. The CStatic’s job is to display a frame and let other control be displayed inside it (even though they are not child controls). For CStatic to do that it needs to return HTTRANSPARENT.

Getting mouse move messages
To fix this problem is straightforward.

  • Add a WM_ON_NCHITTEST() entry to the custom control message map.
  • Add a OnNcHitTest() method to the custom control and make it return HTCLIENT;

Once these are in place, the hit test works and then mouse move messages are sent to the custom control.

Sometimes the reason you are not getting messages is because something else is setup incorrectly. In this case the lack of correct hit testing was affecting many other messages, of which the mouse move message was one. I hope this article will help prevent you wasting any time on a bug like this.

Fully functional, free for 30 days