Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Custom Slider control messages cannot be caught

Custom Slider control messages cannot be caught

Scheduled Pinned Locked Moved C / C++ / MFC
13 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    AlbertB
    wrote on last edited by
    #1

    I have a custom rotary slider control inheriting from CSliderCtrl. Its own behaviour is fine, it displays as I want, responds to mouse dragging and rotates just as it should. Then I want to interact with it from its parent dialog and the problems start. I had imagined that I would just have to trap the ON_VSCROLL message to obtain its value as it changes. (It is set up with Orientation: Vertical though I have tried Horizontal too.) I can't trap ON_VSCROLL or ON_HSCROLL with either setting. I have tried catching NM_RELEASEDCAPTURE and can't get that either. I have:

    BEGIN_MESSAGE_MAP(CNewPatchDlg, CDialog)
    ON_WM_HSCROLL()
    ON_WM_VSCROLL()
    ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_VOLUME, OnReleasedCapture)
    END_MESSAGE_MAP()

    in my dialog message map and

    void CNewPatchDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    void CNewPatchDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    void CGm36NewPatchDlg::OnReleasedCapture(NMHDR* pNMHDR, LRESULT* pResult)

    declared and defined in my dialog .h and .cpp files. They exist as temporary function stubs with a little junk code in there to just see whether I can hit breakpoints in the functions. None get hit. In the dialog editor the wizard shows only four control events available for the control, NM_CUSTOMDRAW, NM_OUTOFMEMORY, NM_RELEASEDCAPTURE, NM_THEMECHANGED. I expected to see more than that! I would have thought at least I could have accessed ON_VSCROLL via the wizard though a standard CSliderCtrl shows the same four options. I know sometimes these controls can be a little eccentric but I thought this would be pretty plain sailing. I've dug around and found a couple of suggestions that I'm not the only person to have this issue with a Custom slider but no one seems to have a solution, only to use ON_HSCROLL or ON_VSCROLL which I can't seem to do. This must be something very simple I am seeing wrong. Can anyone suggest what I am missing?

    L S 2 Replies Last reply
    0
    • A AlbertB

      I have a custom rotary slider control inheriting from CSliderCtrl. Its own behaviour is fine, it displays as I want, responds to mouse dragging and rotates just as it should. Then I want to interact with it from its parent dialog and the problems start. I had imagined that I would just have to trap the ON_VSCROLL message to obtain its value as it changes. (It is set up with Orientation: Vertical though I have tried Horizontal too.) I can't trap ON_VSCROLL or ON_HSCROLL with either setting. I have tried catching NM_RELEASEDCAPTURE and can't get that either. I have:

      BEGIN_MESSAGE_MAP(CNewPatchDlg, CDialog)
      ON_WM_HSCROLL()
      ON_WM_VSCROLL()
      ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_VOLUME, OnReleasedCapture)
      END_MESSAGE_MAP()

      in my dialog message map and

      void CNewPatchDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
      void CNewPatchDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
      void CGm36NewPatchDlg::OnReleasedCapture(NMHDR* pNMHDR, LRESULT* pResult)

      declared and defined in my dialog .h and .cpp files. They exist as temporary function stubs with a little junk code in there to just see whether I can hit breakpoints in the functions. None get hit. In the dialog editor the wizard shows only four control events available for the control, NM_CUSTOMDRAW, NM_OUTOFMEMORY, NM_RELEASEDCAPTURE, NM_THEMECHANGED. I expected to see more than that! I would have thought at least I could have accessed ON_VSCROLL via the wizard though a standard CSliderCtrl shows the same four options. I know sometimes these controls can be a little eccentric but I thought this would be pretty plain sailing. I've dug around and found a couple of suggestions that I'm not the only person to have this issue with a Custom slider but no one seems to have a solution, only to use ON_HSCROLL or ON_VSCROLL which I can't seem to do. This must be something very simple I am seeing wrong. Can anyone suggest what I am missing?

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      See Slider Notification Messages[^].

      A 1 Reply Last reply
      0
      • L Lost User

        See Slider Notification Messages[^].

        A Offline
        A Offline
        AlbertB
        wrote on last edited by
        #3

        I found that Richard, MSDN is the first thing I go to. There is a wealth of stuff with examples (that actually are only part complete) in there. None of it seems to work! From your link:

        Quote:

        A slider control notifies its parent window of user actions by sending the parent WM_HSCROLL or WM_VSCROLL messages, depending on the orientation of the slider control. To handle these messages, add handlers for the WM_HSCROLL and WM_VSCROLL messages to the parent window. The OnHScroll and OnVScroll member functions will be passed a notification code, the position of the slider, and a pointer to the CSliderCtrl object.

        It just seems to back up everything I have done so far. I am trying unsuccessfully to catch the ON_HSCROLL and ON_VSCROLL messages in the parent wiondow just as MS says. I know I can parse out the info once I have caught the message, it's getting the message to land that I can't do even though I seem to be doing exactly what they say.

        L 1 Reply Last reply
        0
        • A AlbertB

          I found that Richard, MSDN is the first thing I go to. There is a wealth of stuff with examples (that actually are only part complete) in there. None of it seems to work! From your link:

          Quote:

          A slider control notifies its parent window of user actions by sending the parent WM_HSCROLL or WM_VSCROLL messages, depending on the orientation of the slider control. To handle these messages, add handlers for the WM_HSCROLL and WM_VSCROLL messages to the parent window. The OnHScroll and OnVScroll member functions will be passed a notification code, the position of the slider, and a pointer to the CSliderCtrl object.

          It just seems to back up everything I have done so far. I am trying unsuccessfully to catch the ON_HSCROLL and ON_VSCROLL messages in the parent wiondow just as MS says. I know I can parse out the info once I have caught the message, it's getting the message to land that I can't do even though I seem to be doing exactly what they say.

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          AlbertB wrote:

          MSDN is the first thing I go to

          Unfortunately so many of our posters do not. Looking at CDialog, it does not look like it implements the OnXScroll methods, so one wonders whether it just ignores scroll messages. I'm not sure quite how to get round that (years since I did MFC), but in Win32 I would probably subclass the Dialog control and use my own message handler.

          A 1 Reply Last reply
          0
          • L Lost User

            AlbertB wrote:

            MSDN is the first thing I go to

            Unfortunately so many of our posters do not. Looking at CDialog, it does not look like it implements the OnXScroll methods, so one wonders whether it just ignores scroll messages. I'm not sure quite how to get round that (years since I did MFC), but in Win32 I would probably subclass the Dialog control and use my own message handler.

            A Offline
            A Offline
            AlbertB
            wrote on last edited by
            #5

            I seem to have at least found a way of doing what I want, even though it does not explain to me what I am really doing wrong here. I have defined a custom message and can send this on to the dialog from within the custom slider at an opportune point. I pass the ID and the value I want as its parameters. I can then catch the custom message in my dialog message handler just as I should be able to and process it from there. I would still like to know why I can't get to grips with the ON_VSCROLL way of doing this as every link I find tells me I should be able to do this as the standard method. I take your point that CDialog doesn't seem to support OnXScroll, but it's a mystery as to why everyone seems to tell you that is the way to do it. Thanks for your time and efforts Richard, even though we still seem to have only half a picture it's greatly appreciated.

            B 1 Reply Last reply
            0
            • A AlbertB

              I have a custom rotary slider control inheriting from CSliderCtrl. Its own behaviour is fine, it displays as I want, responds to mouse dragging and rotates just as it should. Then I want to interact with it from its parent dialog and the problems start. I had imagined that I would just have to trap the ON_VSCROLL message to obtain its value as it changes. (It is set up with Orientation: Vertical though I have tried Horizontal too.) I can't trap ON_VSCROLL or ON_HSCROLL with either setting. I have tried catching NM_RELEASEDCAPTURE and can't get that either. I have:

              BEGIN_MESSAGE_MAP(CNewPatchDlg, CDialog)
              ON_WM_HSCROLL()
              ON_WM_VSCROLL()
              ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_VOLUME, OnReleasedCapture)
              END_MESSAGE_MAP()

              in my dialog message map and

              void CNewPatchDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
              void CNewPatchDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
              void CGm36NewPatchDlg::OnReleasedCapture(NMHDR* pNMHDR, LRESULT* pResult)

              declared and defined in my dialog .h and .cpp files. They exist as temporary function stubs with a little junk code in there to just see whether I can hit breakpoints in the functions. None get hit. In the dialog editor the wizard shows only four control events available for the control, NM_CUSTOMDRAW, NM_OUTOFMEMORY, NM_RELEASEDCAPTURE, NM_THEMECHANGED. I expected to see more than that! I would have thought at least I could have accessed ON_VSCROLL via the wizard though a standard CSliderCtrl shows the same four options. I know sometimes these controls can be a little eccentric but I thought this would be pretty plain sailing. I've dug around and found a couple of suggestions that I'm not the only person to have this issue with a Custom slider but no one seems to have a solution, only to use ON_HSCROLL or ON_VSCROLL which I can't seem to do. This must be something very simple I am seeing wrong. Can anyone suggest what I am missing?

              S Offline
              S Offline
              Stephen Hewitt
              wrote on last edited by
              #6

              I'd use spy and verify the window hierarchy is as you expect. Perhaps the dialog is not a direct parent of the slider.

              Steve

              B 2 Replies Last reply
              0
              • S Stephen Hewitt

                I'd use spy and verify the window hierarchy is as you expect. Perhaps the dialog is not a direct parent of the slider.

                Steve

                B Offline
                B Offline
                Bram van Kampen
                wrote on last edited by
                #7

                Agree with Steve. I use VS98 with MFC42, which is badly documented on advance features. However, it gets me trough most issues. Spy can show you which function dumps your message into the 'BitBin' underneath your Desk. You are apparently of a generation that is un-aware of the Windows SDK. In the SDK, messages were handled in the Actual Window Procedure, or, bounced to the Parent or Child Window Procedure. This was reflected in that Unhandled Messages were referred to the 'DefaultWndProc(...)' That Parent-Child relation is Similar To, but Incompatible with, the CPP Inheritance Model. MFC Simplifies all this with thin but, powerful wrappers. These Wrappers do as much of the hard work, as can be expected. Now, when things go wrong, VS98 was provided with Powerful Tools.'Spy' is just One of them. Do Not forget, At One stage these compilers and Tools were used by Microsoft to develop code for the various Windows Versions. In order to use MFC correctly, I suggest reading books about the Windows SDK. Regards, and Success, :)

                Bram van Kampen

                1 Reply Last reply
                0
                • S Stephen Hewitt

                  I'd use spy and verify the window hierarchy is as you expect. Perhaps the dialog is not a direct parent of the slider.

                  Steve

                  B Offline
                  B Offline
                  Bram van Kampen
                  wrote on last edited by
                  #8

                  Sorry Steve, The Other Message was intended for the Original person Asking the Question. Cannot Delete or Move It. Sorry.

                  Bram van Kampen

                  1 Reply Last reply
                  0
                  • A AlbertB

                    I seem to have at least found a way of doing what I want, even though it does not explain to me what I am really doing wrong here. I have defined a custom message and can send this on to the dialog from within the custom slider at an opportune point. I pass the ID and the value I want as its parameters. I can then catch the custom message in my dialog message handler just as I should be able to and process it from there. I would still like to know why I can't get to grips with the ON_VSCROLL way of doing this as every link I find tells me I should be able to do this as the standard method. I take your point that CDialog doesn't seem to support OnXScroll, but it's a mystery as to why everyone seems to tell you that is the way to do it. Thanks for your time and efforts Richard, even though we still seem to have only half a picture it's greatly appreciated.

                    B Offline
                    B Offline
                    Bram van Kampen
                    wrote on last edited by
                    #9

                    Interesting, Can you give us fragments of the Code that resolved it, so that we all may learn? Regards, :)

                    Bram van Kampen

                    A 1 Reply Last reply
                    0
                    • B Bram van Kampen

                      Interesting, Can you give us fragments of the Code that resolved it, so that we all may learn? Regards, :)

                      Bram van Kampen

                      A Offline
                      A Offline
                      AlbertB
                      wrote on last edited by
                      #10

                      In stdafx.h:

                      #define IDM_SLIDER_CHANGE WM_USER+8

                      In the derived CRotarySlider class at a relevant point in my positioning calculation:

                      int iID = ::GetDlgCtrlID(::GetFocus());
                      GetParent()->SendMessage(IDM_SLIDER_CHANGE, iID, nPos);

                      In the Dialog class that the control is used in: Added to the message map:

                      ON_MESSAGE(IDM_SLIDER_CHANGE, OnSliderChange)

                      And handler function:

                      LRESULT CGm36NewPatchDlg::OnSliderChange(WPARAM wParam, LPARAM lParam)
                      {
                      switch (wParam)
                      {

                      	case IDC\_VOLUME:
                      	{
                      

                      // DO WHAT IS NEEDED
                      break;
                      }
                      case IDC_GAIN:
                      {
                      // DO WHAT IS NEEDED
                      break;
                      }

                      // ADD MORE AS REQUIRED

                      }
                      
                      LRESULT lr = 0;
                      return lr;
                      

                      }

                      There are still aspects to tidy up which may not be best coding practice but that works at the moment.

                      L 1 Reply Last reply
                      0
                      • A AlbertB

                        In stdafx.h:

                        #define IDM_SLIDER_CHANGE WM_USER+8

                        In the derived CRotarySlider class at a relevant point in my positioning calculation:

                        int iID = ::GetDlgCtrlID(::GetFocus());
                        GetParent()->SendMessage(IDM_SLIDER_CHANGE, iID, nPos);

                        In the Dialog class that the control is used in: Added to the message map:

                        ON_MESSAGE(IDM_SLIDER_CHANGE, OnSliderChange)

                        And handler function:

                        LRESULT CGm36NewPatchDlg::OnSliderChange(WPARAM wParam, LPARAM lParam)
                        {
                        switch (wParam)
                        {

                        	case IDC\_VOLUME:
                        	{
                        

                        // DO WHAT IS NEEDED
                        break;
                        }
                        case IDC_GAIN:
                        {
                        // DO WHAT IS NEEDED
                        break;
                        }

                        // ADD MORE AS REQUIRED

                        }
                        
                        LRESULT lr = 0;
                        return lr;
                        

                        }

                        There are still aspects to tidy up which may not be best coding practice but that works at the moment.

                        L Offline
                        L Offline
                        leon de boer
                        wrote on last edited by
                        #11

                        As you are getting right down and dirty and away from the MFC framework there are more possibilities inside the Win32 API. If you look at the WM_PARENTNOTIFY message WM_PARENTNOTIFY message (Windows)[^] If you are compiling for windows > VISTA you can actually stop the message going to the dialog at all and directly handle it within the slider using the extended flag WS_EX_NOPARENTNOTIFY style. Useful for making owner draw (skinned) sliders. It isn't clear to me if you are trying to get the slider to change something directly on it's control (owner draw skin) or if you are changing something in the dialog viewport so it may or may not be useful depending what you are doing. I know for example that WinTweaks has its thumb part of it's scrollbar animated, I used to love the flame one :-) A basic example of owner draw in MFC is on the site and it isn't simple (How to skin CListCtrl including scrollbars and column headers[^])

                        In vino veritas

                        A 1 Reply Last reply
                        0
                        • L leon de boer

                          As you are getting right down and dirty and away from the MFC framework there are more possibilities inside the Win32 API. If you look at the WM_PARENTNOTIFY message WM_PARENTNOTIFY message (Windows)[^] If you are compiling for windows > VISTA you can actually stop the message going to the dialog at all and directly handle it within the slider using the extended flag WS_EX_NOPARENTNOTIFY style. Useful for making owner draw (skinned) sliders. It isn't clear to me if you are trying to get the slider to change something directly on it's control (owner draw skin) or if you are changing something in the dialog viewport so it may or may not be useful depending what you are doing. I know for example that WinTweaks has its thumb part of it's scrollbar animated, I used to love the flame one :-) A basic example of owner draw in MFC is on the site and it isn't simple (How to skin CListCtrl including scrollbars and column headers[^])

                          In vino veritas

                          A Offline
                          A Offline
                          AlbertB
                          wrote on last edited by
                          #12

                          Thanks Leon that's great advice. What I'm actually doing is to replace the linear slider appearance with a custom rotary knob within my CRotarySlider class (inheriting from CSliderCtrl and based on simple bitmaps for the background, knob and marker dot). As usual, the user grabs and drags to reposition the knob. That part works absolutely fine. I then needed to handle the change of knob position in the dialog class so was trying to catch the VSCROLL, which as you know I can't seem to do. As I now have it, the calculations to do with conversion from mouse position to control value are taken care of in the CRotarySlider class itself and the finalised control value needs to be passed out to the Dialog class. As I said I have managed to do this with a custom message. I have used the basic DDX setup in the past but it was so long ago I couldn't accurately remember the ins and outs of it but it does occur to me that I may be missing something glaringly obvious in that direction. I'll certainly look into your suggestions, thanks for the heads up, they are greatly appreciated.

                          L 1 Reply Last reply
                          0
                          • A AlbertB

                            Thanks Leon that's great advice. What I'm actually doing is to replace the linear slider appearance with a custom rotary knob within my CRotarySlider class (inheriting from CSliderCtrl and based on simple bitmaps for the background, knob and marker dot). As usual, the user grabs and drags to reposition the knob. That part works absolutely fine. I then needed to handle the change of knob position in the dialog class so was trying to catch the VSCROLL, which as you know I can't seem to do. As I now have it, the calculations to do with conversion from mouse position to control value are taken care of in the CRotarySlider class itself and the finalised control value needs to be passed out to the Dialog class. As I said I have managed to do this with a custom message. I have used the basic DDX setup in the past but it was so long ago I couldn't accurately remember the ins and outs of it but it does occur to me that I may be missing something glaringly obvious in that direction. I'll certainly look into your suggestions, thanks for the heads up, they are greatly appreciated.

                            L Offline
                            L Offline
                            leon de boer
                            wrote on last edited by
                            #13

                            Okay so the thing you are trying to make is a Radial Control or sometimes called a radial gauge (although gauge tends to imply display only) Can't you just push out the messages as standard scrollbar messages using PostMessage with the handle being your parent window. I mean in standard native Win32 I would do this if I wanted to FAKE a WM_VSCROLL or WM_HSCROLL lets assume your dial is handle is hwnd and a position pos.

                            HWND myParent = GetParent(hwnd); // Standard API call to get a windows parent
                            PostMessage(myParent, WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, pos), (LPARAM)hwnd); // Standard scrollbar fake message posted to my parent

                            As we are faking it I wouldn't use SendMessage as it might go re-entrant (you post off to the dialog and it posts back and around in circles it would go). I can't see how MFC could get that wrong as there message pump is still using PeekMessage from the standard windows queue.

                            In vino veritas

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups