Results 1 to 16 of 16

Thread: [RESOLVED] Working with the mouse wheel

  1. #1

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Resolved [RESOLVED] Working with the mouse wheel

    I was getting some slightly unusual behavior when using the mouse wheel for some zooming/scaling work (only vaguely related to the earlier thread, for those who remember it). Frankly, it is likely that I have a bug in some code, but that wasn't quite enough to explain what I was seeing. Therefore, I used a error logging feature in my app to note the delta being passed in each Mouse Wheel event. I then ran the app and gave the wheel one good spin, which was about the maximum that I would normally ever spin the wheel in one steady, continuous motion. I wasn't going slow, I wasn't going fast, and I rotated it about as much as my finger comfortably could in a single roll. The result was this:

    There were four wheel events raised. The deltas are listed below:

    Event 1: 120
    Event 2: 364
    Event 3: 4119
    Event 4: 202

    I then rolled it back the other way using the same motion, and got 8 events, mostly under 200, but one of them was -331 and the other was -7940.

    After a handful of tests, it appears that the wheel event is raised often, which is no surprise, but that the values fluctuate all over the place. With a continuous rotation, or as nearly continuous as I can make it, I can see a series of events with one of them easily being ten times the rest.

    The problem this presents is that the scaling I am using is not smooth (nor is it standard mathematical scaling, but that's a different story). Each zoom level doubles the size of the objects relative to the previous level, though the distance between them stays the same. I would like to do this by dividing the delta by some factor, and if that is above a threshold, increase the zoom level. That won't work smoothly, in this case. If I make the factor something small enough that I pick up a small rotation, then any larger rotation is likely to include a delta that takes the screen through all zoom levels in a single step. Alternatively, if I make the factor large, then all smaller rotations are simply ignored.

    One option would be to filter out rotation values below 200 and above 800, or so. I am looking for other alternatives.
    My usual boring signature: Nothing

  2. #2
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Working with the mouse wheel

    Have you tried it with another mouse? Or on another machine?
    I've never seen any value other than 120 for Delta.

    MSDN:
    When handling the MouseWheel event it is important to follow the user interface (UI) standards associated with the mouse wheel. The MouseEventArgs.Delta property value indicates the amount the mouse wheel has been moved. The UI should scroll when the accumulated delta is plus or minus 120. The UI should scroll the number of logical lines returned by the SystemInformation.MouseWheelScrollLines property for every delta value reached. You can also scroll more smoothly in smaller that 120 unit increments, however the ratio should remain constant, that is SystemInformation.MouseWheelScrollLines lines scrolled per 120 delta units of wheel movement.
    Anyway, MouseWheel event is fired every wheel notch (though I don't know whether this is universal - I experimented), so if you simply declare a static variable which counts how many MouseWheel events are fired and then see the sign of e.Delta you'll be able to figure out how many notches have passed since the last time and in which direction. You don't even need the actual value of e.Delta.

    I tested on a new project with this code:
    Code:
     Private Sub Form1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
            Static count As Integer
            count += 1
            Me.Text = String.Format("Delta: {0}, count {1}", e.Delta, count)
        End Sub
    Also you can try to intercept WM_MOUSEWHEEL message.

    MSDN states that:

    wParam
    The high-order word indicates the distance the wheel is rotated, expressed in multiples or divisions of WHEEL_DELTA, which is 120. A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, toward the user.

    The wheel rotation will be a multiple of WHEEL_DELTA, which is set at 120. This is the threshold for action to be taken, and one such action (for example, scrolling one increment) should occur for each delta.

    The delta was set to 120 to allow Microsoft or other vendors to build finer-resolution wheels (a freely-rotating wheel with no notches) to send more messages per rotation, but with a smaller value in each message. To use this feature, you can either add the incoming delta values until WHEEL_DELTA is reached (so for a delta-rotation you get the same response), or scroll partial lines in response to the more frequent messages. You can also choose your scroll granularity and accumulate deltas until it is reached.

  3. #3
    PowerPoster stanav's Avatar
    Join Date
    Jul 2006
    Location
    Providence, RI - USA
    Posts
    9,290

    Re: Working with the mouse wheel

    It seems like your mouse is not working correctly because with mine, e.delta always +/- 120 for each wheel step (depending on the direction). For example, if I give it a full spin in either direction, I receive 8 mousewheel events with e.delta = 120 0r - 120 each time... In other words, the value of e.Delta is very consistent and I don't see it jumping all over as yours.
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

  4. #4
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,255

    Re: Working with the mouse wheel

    If I spin it really really fast I see it return 240, if I simulate a heavy load on the same thread and spin it fast its all over the place, even returns 0.

    Code:
    sim heavy load result...(spin wheel forwards and backwards)
    120
    1200
    -360
    -480
    960
    -600
    600
    360
    -720
    840
    0
    -840
    
    
    Private Sub Button1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseWheel
        Console.WriteLine(e.Delta.ToString)
        Threading.Thread.Sleep(100)
    End Sub

  5. #5

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Working with the mouse wheel

    That's both great information, and highly disturbing information. What gives me some comfort is the fact that both of you are seeing the same thing. What bothers me is that I am not. No, I have not tried different mice, but now I shall have to.

    Well doggone it!! Took a mouse off my number 3 computer and it works just as you reported. Every event was 120. That's an older Dell wheel mouse with very tangible notches. I then went back to the MS Lazer mouse which has less tangible notches and tried rolling it through four notches. It showed only a single event, though that was for 120. I then rolled it more swiftly through 5-8 notches, as I had with the Dell mouse. The Dell mouse gave me a series of events with the delta being 120 for each. The MS mouse gave be a series of events with the delta ranging from a bit below 120 up to a few hundred. Totally inconsistent.

    So I have been fighting with a defective mouse wheel this whole time. That has caused so much aggravation I can hardly believe it.
    My usual boring signature: Nothing

  6. #6

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Working with the mouse wheel

    And then Edgemeal weighs in while I was writing that (and testing the other mouse), and comes up with results more in line with my MS mouse. That makes me feel even worse.

    Edgemeal: What mouse brand are you using?
    My usual boring signature: Nothing

  7. #7
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Working with the mouse wheel

    If you look closely at Edgemeal's results you'll see that all his results are multipliers of 120, so this is not your case.

    If your mouse is not faulty and happens to be one of those 'high precision' mice then e.Delta should be smaller than 120 if you rotate your mouse wheel 'between notches' (if there are any).

  8. #8
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,255

    Re: Working with the mouse wheel

    Quote Originally Posted by Shaggy Hiker View Post
    And then Edgemeal weighs in while I was writing that (and testing the other mouse), and comes up with results more in line with my MS mouse. That makes me feel even worse.

    Edgemeal: What mouse brand are you using?
    Some cheap Logitech wireless.

    When I do wheel stuff I just check to see if the delta is > 0 then else endif type of thing. Never bothered to count how many notches it was rotated. I've never seen the results you got tho, mine are always dividable by 120, I guess the zero I got was from the delta adding and subtracting while in the sleep state?

  9. #9

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Working with the mouse wheel

    Took the time for an excellent lunch, during which I thought the situation over and realized something totally obvious: The results in the first post were not from the MS Lazer, but from an MS BlueWave wireless mouse. I then did further testing on both the Lazer and the Dell. The Dell always returns multiples of 120. The Lazer rarely returns multiples of 120, though the first move when the value is negative is generally -120. The other values are not random, but I see no real connection between them. They are a mix of 127, 183, 331, and 448. Only those values, but in no particular order. When the values are positive, the first value is 120, but subsequent values are a mix of 140 and 202, though I have seen values as high as 846. Those high numbers are not multiples of anything in particular other than 2, since they all appear to be positive.

    So, of the three mice I have tested:

    Older Dell: Always a multiple of 120, almost always exactly 120.
    MS BlueWave: Anything at all without discernible pattern.
    MS Lazer: A set of values that are not obvious multiples of anything. Different set of values for positive and negative.

    Therefore, if I were to use a window, such as I suggested in the first post, when using any mouse other than the BlueWave, I would hit that window....like a bird.

    I currently don't want to test with the last mouse I have available, since it is such a pain to take that mouse off the system it is on. However, it appears that MS mouse, at least, do not really behave the way the documentation states. Worse, there isn't consistent behavior between mice. I simply can't get values above 1000 with either of the other two mice, though I could do so easily with the BlueWave, and Edgemeal managed it with a Logitech, though it was a nice multiple of 120.
    My usual boring signature: Nothing

  10. #10
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Working with the mouse wheel

    I wouldn't be surprised if you aren't able to repeat the results of your experiment with two identical mice which only differ by 1 digit in their serial number. Welcome to the wonderful world of the Chinese circuitry.
    I would also advise to test all three mice on another machine. I suspect that this is a hardware issue either with the machine or with the mice.
    At any rate, you can use what I suggested initially - count hits of WM_MOUSEWHEEL and don't bother with Delta value at all, except for its sign. If should fit your purpose just as well.

  11. #11

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Working with the mouse wheel

    How would the WM_MOUSEWHEEL message differ from just using the MouseWheel event. I would have thought that one event was raised for each WM_MOUSEWHEEL message. I was rather leaning towards a combination of what you posted in #2 (counting the mouse wheel messages) coupled with a timer that would clear the count after a certain amount of time (very little time).
    My usual boring signature: Nothing

  12. #12
    PowerPoster stanav's Avatar
    Join Date
    Jul 2006
    Location
    Providence, RI - USA
    Posts
    9,290

    Re: Working with the mouse wheel

    There you go... At least now you know that each mouse wheel notch delta value is somewhere around 120. So this should be a fairly safe assumption:
    Code:
    Dim zoomFactor As Integer = e.Delta \ 120
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

  13. #13
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Working with the mouse wheel

    Quote Originally Posted by Shaggy Hiker View Post
    How would the WM_MOUSEWHEEL message differ from just using the MouseWheel event. I would have thought that one event was raised for each WM_MOUSEWHEEL message. I was rather leaning towards a combination of what you posted in #2 (counting the mouse wheel messages) coupled with a timer that would clear the count after a certain amount of time (very little time).
    I wouldn't bother with timer. Simply remember the last count and get the difference.

  14. #14

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Working with the mouse wheel

    Quote Originally Posted by stanav View Post
    There you go... At least now you know that each mouse wheel notch delta value is somewhere around 120. So this should be a fairly safe assumption:
    Code:
    Dim zoomFactor As Integer = e.Delta \ 120
    It isn't safe on that BlueWave. I was getting values above 4000. While I would be willing to believe that I had spun the wheel through as many as 10 notches, that single event would have covered a whopping 34 notches, and I simply can't do that kind of a move in one motion. Better yet, there were six more notches covered in that one scroll, for a total of 40. Interestingly, I use this computer with three different mice, depending on where I am at any given time, so if I make any use of the Delta, the program won't behave the same in different environments.

    @Cicatrix: I must be misunderstanding you. I was thinking of counting one for every mousewheel event, but I don't actually want to zoom once for every mousewheel event. In fact, after testing, I think I want to scroll once for every three or four events. This is because the zooming is not smooth. The objects double in size with every step. The reason for the timer was that I would be counting events, and zoom whenever that count exceeded a threshold.....oh, nevermind. Under that design, it really doesn't matter if there was a timer, or not. The point for the timer would be to clear the count if nothing had happened for a time, but that's quite pointless.
    My usual boring signature: Nothing

  15. #15
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Working with the mouse wheel

    Quote Originally Posted by Shaggy Hiker View Post
    The point for the timer would be to clear the count if nothing had happened for a time, but that's quite pointless.
    Exactly. Unless you exceed the Integer.MaxValue which is unlikely without an electric screwdriver attached to the mouse wheel :)

  16. #16

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: [RESOLVED] Working with the mouse wheel

    On to the next bug, then.

    Thanks to all, it cleared this issue up quite well, while teaching me something about the hardware. I may test this further with yet another mouse, but it's not a high priority. Clearly, there is considerable variability between different mice. I also noticed the unusually large number of mice I had available to test this, which just illustrates another often observed fact about mice: They reproduce.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width