winapitrackbar

Trackbar not sending TRBN_THUMBPOSCHANGING notification


I have a programmatically created trackbar control (TRACKBAR_CLASS). I would like to be notified of scrolling changes using TRBN_THUMBPOSCHANGING. However, I am currently not receiving that notification. I have monitored all the WM_NOTIFY messages sent by the control, and I have only seen the other two: NM_CUSTOMDRAW (-12) and NM_RELEASEDCAPTURE (-16).

The pertinent excerpts of the code (which I inherited) are these:

// this code creates the window

HWND hwndControl = CreateWindowEx(
          0,
          TRACKBAR_CLASS,
          NULL,
          TBS_AUTOTICKS | TBS_TOP | TBS_HORZ | TBS_RIGHT | WS_CHILD | WS_OVERLAPPED | WS_VISIBLE | WS_TABSTOP,
          0,
          0,
          width,
          height,
          parentWindow,
          dlgID,
          hInstance,        
          NULL);

//and the WM_NOTIFY routine:

bool HandleWMNotify(WPARAM wparam, LPARAM lparam)
{
   if (! controlIsMyTrackBar) return false; // abbreviated pseudocode

   switch(((LPNMHDR) lparam)->code)
   {
      case NM_CUSTOMDRAW:
          break; //This case hits whenever the control draws itself.

      case NM_RELEASEDCAPTURE:
          break; //This case hits whenever I release the mouse on the control.
 
      case TRBN_THUMBPOSCHANGING:
          break; //This case never hits. :-(

      default:
          break; //This case never hits either (which is expected behavior).
   }

The documentation for the Trackbar offers TRBN_THUMBPOSCHANGING as an option for monitoring trackbar changes. But weirdly, this overview page does not mention any of the WM_NOTIFY events in its Trackbar Notification Messages section.

I have found a number of other questions similar to this one, but the answers basically just point back to one of these two documentation pages that seem not exactly to be in agreement with each other.

If I have to, I will use WM_HSCROLL, but TRBN_THUMBPOSCHANGING would be preferable.


Solution

  • The TRBN_THUMBPOSCHANGING notification is sent before the thumb control moves; it seems intended to allow for snapping to custom positions, and presumably lets you block and/or modify the position the thumb moves to.

    The documentation on this notification message is not especially clear, but the note about the return value does imply that it is sent before the control changes value:

    Return TRUE to prevent the thumb from moving to the specified position.

    Obviously this would not make sense if it was sent after the control had already moved.

    Another clue is in the name of the message; if you look at the listview control, for example, it has LVN_ITEMCHANGING and LVN_ITEMCHANGED notification messages. the "changing" message is sent before the change occurs, and the "changed" message is sent afterwards. Of course the trackbar seems to have no such "changed" message - that function being, presumably, filled by WM_HSCROLL and WM_VSCROLL.

    Once we know that the message is sent before the thumb moves, the name of the TBS_NOTIFYBEFOREMOVE style makes sense - and indeed, this style needs to be set in order to receive these notifications.

    The line in the remarks section of the documentation is quite confusing:

    Send this notification to clients that do not listen for WM_HSCROLL or WM_VSCROLL messages

    To me this reads as an internal comment that wasn't intended for public documentation.