• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4145
  • Last Modified:

Receiving CSliderCtrl notify messages - TB_THUMBTRACK

I'm trying to get TB_THUMBTRACK messages from a CSliderCtrl in VC++ 6.0.  

In my parent window (a subclass of CView) I have overridden OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult ).  I have a number of CSliderCtrls in the view.  My code goes something like this:  

OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult ) {
   CWnd* pWnd = GetDlgItem( wParam );

    if ( pWnd->IsKindOf( RUNTIME_CLASS( CSliderCtrl ) ) {
        CSliderCtrl* pSlider = (CSliderCtrl*)pWnd;
        NMHDR pNMHDR = (NMHDR)lParam;

        switch ( pNMHDR->code ) {
        case TB_THUMBTRACK:
            // Should be here when user drags slider thumb but never get here
            break;
        }
    }
}

I've managed to work out that lParam->code never equals TB_THUMBTRACK only ever the values -12 or -16.  I can't find these values in CommCtrl.h which is where the majority of the notify defines are so I'm not totally sure what message is being received.  It certainly isn't the one I want, TB_ messages go from 0-8.  

What am I doing wrong here?  How can I receive the correct notify messages from the slider?  

Thanks for your help.  
0
rubinho
Asked:
rubinho
  • 3
  • 2
  • 2
  • +1
1 Solution
 
Jaime OlivaresSoftware ArchitectCommented:
Inside your CView derived implementation (.cpp) you will find a message map section. Insert a handler there, specifying control ID (1000 in this example, and handling function):

BEGIN_MESSAGE_MAP(CYourView, CView)
      //{{AFX_MSG_MAP(CYourView)
      ON_WM_SIZE()
      ON_WM_CREATE()
      //}}AFX_MSG_MAP
      ON_NOTIFY(TB_THUMBTRACK, 1000, OnThumbTrack)      <---------------------
END_MESSAGE_MAP()

After that, implement your handler function (and declare in your view class definition, of course):

void CYourView::OnThumbTrack(NMHDR* pNMHDR, LRESULT* pResult)
{
     // your handling code here
}

Read more about CSliderCtrl notification handler here:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/trackbar/trackbar.asp
0
 
vijay_visanaCommented:
try OnHScroll

afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);


void CClientDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
 {
     if (m_pPosition != NULL) {
         switch (nSBCode) {
 
         case TB_THUMBTRACK:
0
 
rubinhoAuthor Commented:
Jaime:

I am dynamically creating my controls and generating the control IDs at runtime because there are an unknown number of controls this means I cannot use the message map macros.  Is there any way of adding message handlers like this at runtime?  

Vijay:

I am trying to avoid using OnHScroll as the parent view also has a horizontal scrollbar and I feel this would make this area of code more complicated than it need be.  I am already handling messages from a CComboBox in my OnNotify handler and CEdit messages in an OnCommand handler, I don't want to be doing things in three places.  Any other suggestions?  
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

 
Jaime OlivaresSoftware ArchitectCommented:
Try to capture all WM_NOTIFY events in view's PreTranslateMessage(), it's a hard work because you have to discriminate your desired notification correctly.
0
 
nonubikCommented:
>I am dynamically creating my controls and generating the control IDs at runtime because there are an unknown number of controls this means I cannot use the
>message map macros.  Is there any way of adding message handlers like this at runtime?

You can use ON_NOTIFY_RANGE macro instead of ON_NOTIFY. You must assign a large enough range and make sure no other kind of control gets in that range.

ON_NOTIFY_RANGE(TB_THUMBTRACK, ID_FIRST, ID_FIRST + MAX_RANGE, OnThumbTrack) //define your own ID_FIRST and MAX_RANGE
0
 
rubinhoAuthor Commented:
nonubik:

Have a look at what I tried (irrelavant code snipped):  

const int CTRL_BASE_CONTROL = 14000;
const int CTRL_INCREMENT = 999; // Gives range of 1000 unique control IDs

afx_msg void MyView::DoControl( UINT id, NMHDR* pNotifyStruct, LRESULT* result ) {
    TRACE( "MyView::DoControl() entered!\n" );

    TRACE( "MyView::DoControl() exited!\n" );
}

ON_NOTIFY_RANGE( TB_THUMBTRACK, CTRL_BASE_CONTROL, CTRL_BASE_CONTROL + CTRL_INCREMENT, DoControl )

Still no joy.  I also tried substituting ON_COMMAND_RANGE for ON_NOTIFY_RANGE as this works for CComboBoxes and the CBN_SELENDOK notification message, still nothing.  

Any tips?
0
 
nonubikCommented:
Seems that the slider notification messages are received through WM_VSCROLL and WM_HSCROLL messages.

ON_WM_HSCROLL( )
ON_WM_VSCROLL( )

void MyView::HScroll ( UINT nSBCode, UINT /*nPos*/ )
{
      if( nSBCode == TB_THUMBTRACK )
      {
            //
      }
}

idem for VScroll
0
 
rubinhoAuthor Commented:
Wow, it works!  

I'm fairly new to MFC and I've picked (well it was chosen for me) a fairly complex project.  Has to be said that I think its message handling leaves a lot to be desired.  I personally think there should be an alternative to message map macros or even a way to successfully bypass the default message handling (OnCommand and OnNotify should allow you to define your own behaviour).  

Well done on the solution, I thought I'd tried everything (and that I could avoid using the ON_WM_HSCROLL messages) but seemingly I hadn't tried the only thing that actually works.  I just hope that this doesn't screw up the horizontal scrolling of the actual view itself rather than the slider bars inside it.  The docs for CSliderCtrl do not make the behaviour at all obvious.  

I must say that I thought I went through a fairly logical thought process but this is MSFT so who knows!  Hell, I'm using WTL next time, it's free, slimmer and more expressive.  
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

  • 3
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now