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. WM_MOUSEWHEEL message and the Touchpad : SOLVED thanks to Randor

WM_MOUSEWHEEL message and the Touchpad : SOLVED thanks to Randor

Scheduled Pinned Locked Moved C / C++ / MFC
c++cssvisual-studiodebuggingquestion
13 Posts 2 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.
  • L Offline
    L Offline
    Lost User
    wrote on last edited by
    #1

    I am processing the WM_MOUSEWHEEL messages in a C++ application,

    void CView::OnMouseWheel(
    HWND hWnd,
    int xPos,
    int yPos,
    int zDelta,
    UINT fwKeys
    )
    {
    zDelta /= WHEEL_DELTA; // calculate the number of lines to move
    if (zDelta != 0)
    {
    // line up or down once per delta
    OnVScroll(hWnd, NULL, zDelta > 0 ? SB_LINEUP : SB_LINEDOWN, 3);
    }
    }

    but when I use the touchpad nothing happens. Following the advice in the MSDN documentation I divide the zDelta value by 120 (WHEEL_DELTA) to calculate the (approximate) number of lines to scroll. The debugger shows that the resulting value is always zero. If I use my mouse and turn the wheel it scrolls correctly. The weird part is that using other applications (VS, Word, Chrome etc.) the touchpad works correctly. So I conclude that the code should somehow get some other information that identifies the touchpad, and adjusts the delta accordingly. Anyone else seen similar problems? [edit] Thanks to David D's sugestion I modified the code to accumulate deltas that are less than the value of WHEEL_DELTA, thus:

    static int myDelta = 0;
    if (abs(zDelta) < WHEEL_DELTA)
    {
    myDelta += zDelta;
    zDelta = myDelta;
    }
    zDelta /= WHEEL_DELTA; // this value works better than WHEEL_DELTA;
    if (zDelta != 0)
    {
    myDelta = myDelta % WHEEL_DELTA; // save the remainder for further movements
    // line up or down once per delta
    OnVScroll(hWnd, NULL, zDelta > 0 ? SB_LINEUP : SB_LINEDOWN, 3);
    }

    which works a treat. Note that I use the value 3 for the number of lines to scroll. In a proper commercial application the code should use the value of the system parameter: SPI_GETWHEELSCROLLLINES. [/edit]

    L D 3 Replies Last reply
    0
    • L Lost User

      I am processing the WM_MOUSEWHEEL messages in a C++ application,

      void CView::OnMouseWheel(
      HWND hWnd,
      int xPos,
      int yPos,
      int zDelta,
      UINT fwKeys
      )
      {
      zDelta /= WHEEL_DELTA; // calculate the number of lines to move
      if (zDelta != 0)
      {
      // line up or down once per delta
      OnVScroll(hWnd, NULL, zDelta > 0 ? SB_LINEUP : SB_LINEDOWN, 3);
      }
      }

      but when I use the touchpad nothing happens. Following the advice in the MSDN documentation I divide the zDelta value by 120 (WHEEL_DELTA) to calculate the (approximate) number of lines to scroll. The debugger shows that the resulting value is always zero. If I use my mouse and turn the wheel it scrolls correctly. The weird part is that using other applications (VS, Word, Chrome etc.) the touchpad works correctly. So I conclude that the code should somehow get some other information that identifies the touchpad, and adjusts the delta accordingly. Anyone else seen similar problems? [edit] Thanks to David D's sugestion I modified the code to accumulate deltas that are less than the value of WHEEL_DELTA, thus:

      static int myDelta = 0;
      if (abs(zDelta) < WHEEL_DELTA)
      {
      myDelta += zDelta;
      zDelta = myDelta;
      }
      zDelta /= WHEEL_DELTA; // this value works better than WHEEL_DELTA;
      if (zDelta != 0)
      {
      myDelta = myDelta % WHEEL_DELTA; // save the remainder for further movements
      // line up or down once per delta
      OnVScroll(hWnd, NULL, zDelta > 0 ? SB_LINEUP : SB_LINEDOWN, 3);
      }

      which works a treat. Note that I use the value 3 for the number of lines to scroll. In a proper commercial application the code should use the value of the system parameter: SPI_GETWHEELSCROLLLINES. [/edit]

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

      I found the mouse wheel events specific to the "mouse wheel". When using only touch (tablet swipe) I got the scrolling, but the "wheel event" that I used to detect "at bottom or top" no longer fires and I need to find something else. I think it now has to tie into a "view changing" and / or "view changed" event and / or manipulation started / ended. (And I think a touchpad is treated as a "pointer" in Windows 10).

      The Master said, 'Am I indeed possessed of knowledge? I am not knowing. But if a mean person, who appears quite empty-like, ask anything of me, I set it forth from one end to the other, and exhaust it.' ― Confucian Analects

      L 2 Replies Last reply
      0
      • L Lost User

        I am processing the WM_MOUSEWHEEL messages in a C++ application,

        void CView::OnMouseWheel(
        HWND hWnd,
        int xPos,
        int yPos,
        int zDelta,
        UINT fwKeys
        )
        {
        zDelta /= WHEEL_DELTA; // calculate the number of lines to move
        if (zDelta != 0)
        {
        // line up or down once per delta
        OnVScroll(hWnd, NULL, zDelta > 0 ? SB_LINEUP : SB_LINEDOWN, 3);
        }
        }

        but when I use the touchpad nothing happens. Following the advice in the MSDN documentation I divide the zDelta value by 120 (WHEEL_DELTA) to calculate the (approximate) number of lines to scroll. The debugger shows that the resulting value is always zero. If I use my mouse and turn the wheel it scrolls correctly. The weird part is that using other applications (VS, Word, Chrome etc.) the touchpad works correctly. So I conclude that the code should somehow get some other information that identifies the touchpad, and adjusts the delta accordingly. Anyone else seen similar problems? [edit] Thanks to David D's sugestion I modified the code to accumulate deltas that are less than the value of WHEEL_DELTA, thus:

        static int myDelta = 0;
        if (abs(zDelta) < WHEEL_DELTA)
        {
        myDelta += zDelta;
        zDelta = myDelta;
        }
        zDelta /= WHEEL_DELTA; // this value works better than WHEEL_DELTA;
        if (zDelta != 0)
        {
        myDelta = myDelta % WHEEL_DELTA; // save the remainder for further movements
        // line up or down once per delta
        OnVScroll(hWnd, NULL, zDelta > 0 ? SB_LINEUP : SB_LINEDOWN, 3);
        }

        which works a treat. Note that I use the value 3 for the number of lines to scroll. In a proper commercial application the code should use the value of the system parameter: SPI_GETWHEELSCROLLLINES. [/edit]

        D Offline
        D Offline
        David Crow
        wrote on last edited by
        #3

        Is your message loop receiving any other messages (e.g., WM_TOUCH) when the touch pad is being interacted with?

        "One man's wage rise is another man's price increase." - Harold Wilson

        "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

        "You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles

        L 2 Replies Last reply
        0
        • L Lost User

          I found the mouse wheel events specific to the "mouse wheel". When using only touch (tablet swipe) I got the scrolling, but the "wheel event" that I used to detect "at bottom or top" no longer fires and I need to find something else. I think it now has to tie into a "view changing" and / or "view changed" event and / or manipulation started / ended. (And I think a touchpad is treated as a "pointer" in Windows 10).

          The Master said, 'Am I indeed possessed of knowledge? I am not knowing. But if a mean person, who appears quite empty-like, ask anything of me, I set it forth from one end to the other, and exhaust it.' ― Confucian Analects

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

          The messages are coming through correctly, but the delta value is always less than 120. That is unless I give a fast swipe from top to bottom of the pad. I have checked the parameters sent with the message and, apart from the delta value, they are the same for the mouse or the touchpad. More debugging required I expect.

          1 Reply Last reply
          0
          • D David Crow

            Is your message loop receiving any other messages (e.g., WM_TOUCH) when the touch pad is being interacted with?

            "One man's wage rise is another man's price increase." - Harold Wilson

            "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

            "You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles

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

            Not sure about that, but thanks I will definitely check.

            1 Reply Last reply
            0
            • L Lost User

              I am processing the WM_MOUSEWHEEL messages in a C++ application,

              void CView::OnMouseWheel(
              HWND hWnd,
              int xPos,
              int yPos,
              int zDelta,
              UINT fwKeys
              )
              {
              zDelta /= WHEEL_DELTA; // calculate the number of lines to move
              if (zDelta != 0)
              {
              // line up or down once per delta
              OnVScroll(hWnd, NULL, zDelta > 0 ? SB_LINEUP : SB_LINEDOWN, 3);
              }
              }

              but when I use the touchpad nothing happens. Following the advice in the MSDN documentation I divide the zDelta value by 120 (WHEEL_DELTA) to calculate the (approximate) number of lines to scroll. The debugger shows that the resulting value is always zero. If I use my mouse and turn the wheel it scrolls correctly. The weird part is that using other applications (VS, Word, Chrome etc.) the touchpad works correctly. So I conclude that the code should somehow get some other information that identifies the touchpad, and adjusts the delta accordingly. Anyone else seen similar problems? [edit] Thanks to David D's sugestion I modified the code to accumulate deltas that are less than the value of WHEEL_DELTA, thus:

              static int myDelta = 0;
              if (abs(zDelta) < WHEEL_DELTA)
              {
              myDelta += zDelta;
              zDelta = myDelta;
              }
              zDelta /= WHEEL_DELTA; // this value works better than WHEEL_DELTA;
              if (zDelta != 0)
              {
              myDelta = myDelta % WHEEL_DELTA; // save the remainder for further movements
              // line up or down once per delta
              OnVScroll(hWnd, NULL, zDelta > 0 ? SB_LINEUP : SB_LINEDOWN, 3);
              }

              which works a treat. Note that I use the value 3 for the number of lines to scroll. In a proper commercial application the code should use the value of the system parameter: SPI_GETWHEELSCROLLLINES. [/edit]

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

              Hi,

              Richard MacCutchan wrote:

              I divide the zDelta value by 120 (WHEEL_DELTA) to calculate the (approximate) number of lines to scroll.

              While it is true that the many of the old mouse drivers sent WHEEL_DELTA in multiples of 120 that is not always the case for high-precision mice and touchpads. You are probably getting values much smaller than 120. To fix your code you need to keep track of the delta modulo of +/- 120 in a static local or class variable and add/subtract the latest delta from the previous value. I also observe that you are hard-coding the line count rather than retrieving the user preference via SystemParametersInfo with SPI_GETWHEELSCROLLLINES. Best Wishes, -David Delaune

              L 1 Reply Last reply
              0
              • L Lost User

                Hi,

                Richard MacCutchan wrote:

                I divide the zDelta value by 120 (WHEEL_DELTA) to calculate the (approximate) number of lines to scroll.

                While it is true that the many of the old mouse drivers sent WHEEL_DELTA in multiples of 120 that is not always the case for high-precision mice and touchpads. You are probably getting values much smaller than 120. To fix your code you need to keep track of the delta modulo of +/- 120 in a static local or class variable and add/subtract the latest delta from the previous value. I also observe that you are hard-coding the line count rather than retrieving the user preference via SystemParametersInfo with SPI_GETWHEELSCROLLLINES. Best Wishes, -David Delaune

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

                Randor wrote:

                you need to keep track of the delta

                Thanks David, that works perfectly - simple when you know how. As to the fixed value, this is purely for personal use so I am not too concerned with system settings; although I notice that 3 is the default value.

                L 1 Reply Last reply
                0
                • D David Crow

                  Is your message loop receiving any other messages (e.g., WM_TOUCH) when the touch pad is being interacted with?

                  "One man's wage rise is another man's price increase." - Harold Wilson

                  "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                  "You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles

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

                  No, it never gets WM_TOUCH. But see my update and solution.

                  1 Reply Last reply
                  0
                  • L Lost User

                    I found the mouse wheel events specific to the "mouse wheel". When using only touch (tablet swipe) I got the scrolling, but the "wheel event" that I used to detect "at bottom or top" no longer fires and I need to find something else. I think it now has to tie into a "view changing" and / or "view changed" event and / or manipulation started / ended. (And I think a touchpad is treated as a "pointer" in Windows 10).

                    The Master said, 'Am I indeed possessed of knowledge? I am not knowing. But if a mean person, who appears quite empty-like, ask anything of me, I set it forth from one end to the other, and exhaust it.' ― Confucian Analects

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

                    The touchpad is just a mouse to the system, but it sends WM_MOUSEWHEEL messages somewhat differently. I have added the solution to my original post.

                    L 1 Reply Last reply
                    0
                    • L Lost User

                      Randor wrote:

                      you need to keep track of the delta

                      Thanks David, that works perfectly - simple when you know how. As to the fixed value, this is purely for personal use so I am not too concerned with system settings; although I notice that 3 is the default value.

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

                      Richard MacCutchan wrote:

                      Thanks David, that works perfectly

                      Looks good, although I do see a minor issue with your latest code. You are dropping the remainder without the modulo operation. Rather than setting your delta to zero you should keep the remainder after scrolling with:

                      myDelta = myDelta % WHEEL_DELTA;

                      Such a precision loss is probably not a big deal for simply scrolling a text window. But let's make our code samples more correct. Best Wishes, -David Delaune

                      L 1 Reply Last reply
                      0
                      • L Lost User

                        Richard MacCutchan wrote:

                        Thanks David, that works perfectly

                        Looks good, although I do see a minor issue with your latest code. You are dropping the remainder without the modulo operation. Rather than setting your delta to zero you should keep the remainder after scrolling with:

                        myDelta = myDelta % WHEEL_DELTA;

                        Such a precision loss is probably not a big deal for simply scrolling a text window. But let's make our code samples more correct. Best Wishes, -David Delaune

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

                        Thanks again, I will certainly update my code (and the original question).

                        1 Reply Last reply
                        0
                        • L Lost User

                          The touchpad is just a mouse to the system, but it sends WM_MOUSEWHEEL messages somewhat differently. I have added the solution to my original post.

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

                          Glad you got it working. Yes, "delta" is a double, so it has quite a range. I needed the "Manipulation events" which give scroll direction and distance.

                          The Master said, 'Am I indeed possessed of knowledge? I am not knowing. But if a mean person, who appears quite empty-like, ask anything of me, I set it forth from one end to the other, and exhaust it.' ― Confucian Analects

                          L 1 Reply Last reply
                          0
                          • L Lost User

                            Glad you got it working. Yes, "delta" is a double, so it has quite a range. I needed the "Manipulation events" which give scroll direction and distance.

                            The Master said, 'Am I indeed possessed of knowledge? I am not knowing. But if a mean person, who appears quite empty-like, ask anything of me, I set it forth from one end to the other, and exhaust it.' ― Confucian Analects

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

                            The strange thing was that using both the debugger and Spy++, I could not 'see' the multiple messages coming in. In both cases after a scroll gesture on the touchpad, they both showed just one message and then went back to the application window. So it as if the delta values were just too small. BTW, thanks for your interest.

                            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