Click here to Skip to main content
15,881,757 members
Articles / Desktop Programming / MFC

Handling Enhanced Mouse Wheels in your Application

,
Rate me:
Please Sign up or sign in to vote.
4.91/5 (23 votes)
10 Feb 2011CPOL11 min read 60.9K   4K   45   4
How to give your users a smooth scrolling experience with High Resolution Mouse Wheels

Introduction

Enhanced mice wheels generate more scroll events than a standard mouse wheel for the same amount of wheel rotation. Today, many applications, when used with enhanced wheel mouse, don’t work properly or are not written to support the high resolution feature that takes advantage of the wheel movement granularity. This article shows how to make your applications enhanced mouse scroll wheel friendly. It provides tips for application developers to help them create applications that take advantage of enhanced wheel support in Windows Vista (and above).

We begin with some background information on standard and enhanced mouse wheels. We look into the benefits of adding enhanced mouse wheel support in applications. Then we look at the typical problems we see in applications that are not aware of enhanced scroll wheels and provide tips to improve user experience.

We also look into how one can test an application with real hardware that has enhanced mouse wheel to ensure that your application is compatible with enhanced scroll wheels. If hardware that has enhanced wheel is not available, then you can also test your application using the emulator I have written and provided along with this article.

Finally, we illustrate the improvements using an existing sample app. This will help developers create applications that are enhanced-wheel aware and are able to handle granular scroll events for smoother scrolling experience.

The Mouse Wheel

The mouse wheel combines the features of a wheel and a mouse button. The wheel has discrete, evenly-spaced notches. When you rotate the wheel, a wheel message is sent to your application as each notch is encountered.

Applications are notified of the mouse wheel scroll events through the WM_MOUSEWHEEL message. The message is sent to the focus window when the mouse wheel is rotated. The DefWindowProc function propagates the message to the window's parent. There should be no internal forwarding of the message, since DefWindowProc propagates it up the parent chain until a window that processes it is found.

The message contains information about the distance the wheel is rotated, and the horizontal and vertical position of the mouse pointer. The distance the wheel is rotated is expressed in multiples or fractions 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.

Background

The WM_MOUSEWHEEL message was introduced with Windows 98 and Windows NT 4.0. This message defined the distance the wheel is rotated as an arbitrary value of 120, namely the WHEEL_DELTA. 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 in the future, including perhaps a freely-rotating wheel with no notches. The expectation is that such a device would send more messages per rotation, but with a smaller value in each message. Basically Microsoft was providing itself room for implementing a smoother mouse wheel in the future. That future is here.

With the introduction of Vista, Microsoft rolled out support for enhanced mice wheels that generate more scroll events than a standard mouse wheel for the same amount of wheel rotation. Your standard mouse wheel (sometimes referred to as a low resolution wheel) generated vertical scroll wheel events with a delta of +/- WHEEL_DELTA (defined 120 in winuser.h). Mice with the enhanced scroll wheels are typically designed to send multiple events for the same scroll wheel rotation distance with the summation of the deltas from the events adding up to 120 or -120.

stan_enh_wheels.png

More information on the Microsoft’s Enhanced Wheel design can be found at this link.

Benefits of Enhanced Mouse Wheel Support in Applications

Enhanced mouse wheels can be used to support smooth animations in a user interface. When applications are written with enhanced mouse wheel support, the user can have a much smoother scrolling experience. Not only will this be more pleasing to the user, a number of studies have demonstrated measurable benefits from such an approach. The use of smooth animated transitions is believed to facilitate the understanding of changes in material being presented, and thus to reduce the user’s cognitive load [Chang, 1993]. Studies in a wide variety of application scenarios have confirmed benefits, both with respect to performance and subjective user satisfaction. Klein [Klein, 2005] demonstrated these benefits in reading tasks that require the user to scroll. Benefits of animated transitions have also been demonstrated in a variety on interfaces including zooming [Shanmugasundaram, 2008], panning [Bederson, 1999] and review of different versions of information and documents [Bezerianos, 2006; Chevalier, 2010].

Typical Application Problems with Enhanced Mouse Wheels

Windows Vista (and above) automatically enables smooth scrolling for any device that supports it. Today, many applications, when used with enhanced wheel mouse, don’t work properly or are not written to support the high resolution feature that takes advantage of the wheel movement granularity.

Here are some typical problems seen with many applications and tips on how to correct them:

  1. Application does not scroll at all. This may occur if the message delta value is not large enough for the application to visibly scroll. Tip: Simply add a variable to accumulate the delta until the minimum amount needed to scroll is reached.
  2. Application scrolls too fast. This may occur because the application ignores the delta value received with the WM_MOUSEWHEEL message. Tip: Do not assume that the wheel delta is always 120. Choose your scroll granularity and accumulate deltas until it is reached.
  3. If the direction of scrolling is reversed, the user may need to scroll the wheel further to get the contents to scroll. Tip: Be sure to reset your accumulated delta when the direction of the scroll wheel changes.
  4. The scrolling experience is not any smoother than with a standard mouse. This occurs because the application does no more than is necessary to give the user the same experience as he would with a low resolution (standard mouse). Typically such an application will accumulate the deltas until an absolute value of 120 is achieved. It then does what it does for a standard scroll event. Tip: Scroll with the minimum accumulated delta required.
  5. Zooming with the Ctrl key and mouse wheel results in the application zooming too fast. Tip: When the Ctrl key is down (it is included in the WM_MOUSEWHEEL message), simply accumulate the deltas until an absolute value of 120 is achieved and zoom accordingly. Alternatively, the application can zoom a smaller amount in proportion to the delta size included in the message.

How to Test your Application Compatibility with Enhanced Mouse Wheels

Note: Since Enhanced Wheel support is not available on XP, use Windows Vista and above.

  • How to test your application with real hardware that has enhanced mouse wheel
  • Check if your mouse has Enhanced Wheel Capability with your application running in the foreground.

    spy_msgs.png

    To do so, you will need a mouse with Enhanced Scroll Wheel capabilities with the appropriate drivers. You may find it necessary to contact the manufacturer to obtain drivers or directions as to how to turn ON this capability. To see if it is turned on, you’ll want to run Spy++ or similar Message snooping software to capture the WM_MOUSEWHEEL messages. What you want to see are multiple messages for a small turn of the mouse wheel and each message with an absolute delta value of less than 120. (In the example, we see a zDelta of -15).

  • How to test your application using the emulator provided in this article?

    If you do not have an enhanced wheel mouse, use the Enhanced Scroll Wheel Emulator included. This application emulates an enhanced wheel by sending smaller wheel deltas to your application. So you can still test your application by running the emulator application (HiResScrollWheel.exe) and create your own Hi-Res WM_MOUSEWHEEL messages.

    emulator_pic.png

    Launching HiResScrollWheel.exe and setting the parameters as follows emulates a Hi-Res mouse with 8 events per click and a delta of 15.

If your application behaves well, the scrolling behavior will be smoother with the Enhanced Mouse wheel. It will scroll the same distance for the amount the scroll wheel is turned but will be smoother and less choppy. You will also want to test how your application behaves when the Ctrl key is pressed and the scroll wheel is turned. If your application normally zooms with the Ctrl key pressed and the scroll wheeled turned, you should get the same behavior with the Enhanced Scroll Wheel. Your application should not zoom any more for the same distance moved of the scroll wheel. Ideally, your application would zoom more smoothly.

How To Make Your Application Enhanced Wheel Friendly

In order to support the enhanced wheel feature, you should either add the incoming delta values until WHEEL_DELTA is reached (so for a given delta- rotation you get the same response), or partial lines in response to the more frequent messages. You could also choose your scroll granularity and accumulate deltas until it is reached. Microsoft’s recommended best practices in software support for mice and keyboards including mouse wheel can be found at this link.

To illustrate the tips, I will be improving the Microsoft MFC sample application, Diblook. This program is shipped with Microsoft Visual Studio 2008. I found the application source in the following zip file on my machine:

Program Files\Microsoft Visual Studio9.0\Samples \1033\AllVCLanguageSamples.zip 

The subdirectory in the zipfile is C++\MFC\general\diblook.

The sample application when executed and loaded with a dib file looks as follows:

diblook_app.png

I used the Enhanced Scroll Wheel Emulator (HiResScrolLWheel.exe) to identify and help fix a number of problems I found in Diblook.

The changes made to get enhanced scrolling to work in the sample app was made in DoMouseWheel() which is shown below. DoMouseWheel() is called whenever the mouse wheel is moved and this function should perform any actions that should occur on the Mouse wheel event.

Application does not scroll at all

Tip: Accumulate Your Wheel Deltas

The first problem I found when I set the Wheel Delta to 1 using my emulator. The picture refused to scroll. The best way to deal with small delta values that do not result in any visible scrolling for the user is to accumulate the deltas until the wheel rotates enough to perform an action.

C++
BOOL CDibView::DoMouseWheel(UINT fFlags, short zDelta, CPoint point)
{
...
	// we keep a member variable m_nAccumulatedDelta 
	// which may be non-zero in the event the method 
	// is called with a delta too small to cause a 
	// visible scroll. If this occurs we accumulate the 
	// deltas until a visible scroll occurs.
	m_nAccumulatedDelta += zDelta ;
...
...
...
	return bResult;
}

If the direction of scrolling is reversed, the user may need to scroll the wheel further to get the contents to scroll.

Tip: Reset Your Accumulated Deltas When the Scroll Direction Changes.

Be sure to reset your accumulated deltas however if the direction of the scroll wheel changes. I combined the above two modifications into the following block of code.

C++
BOOL CDibView::DoMouseWheel(UINT fFlags, short zDelta, CPoint point)
{
...
	// we keep a member variable m_nAccumulatedDelta 
	// which may be non-zero in the event the method 
	// is called with a delta too small to cause a 
	// visible scroll. If this occurs we accumulate the 
	// deltas until a visible scroll occurs.
	if ((m_nAccumulatedDelta*zDelta) > 0 )  
        { 
		// we're scrolling in the same direction and 
		// there is a non-zero value in m_nAccumulatedDelta
		m_nAccumulatedDelta += zDelta ;
	}
	else 
	{
		// we've changed direction or 
		// m_nAccumulatedDelta is zero
		// So reset accumulated delta 
		// variable to the current new
		// delta.
		m_nAccumulatedDelta = zDelta ;
	}
...
...
...
	return bResult;
}

The scrolling experience is not any smoother than with a standard mouse.

Tip: Scroll With the Minimum Accumulated Delta Required.

Another improvement I made to the application was to make the minimum scrollable amount a pixel. In the sample code, the minimum amount the program would scroll was by the pixel height of a character as defined by the application’s font.

I replaced nScroll calculation…

C++
...
int nDisplacement;
...
...
int nToScroll = ::MulDiv(-zDelta, uWheelScrollLines, WHEEL_DELTA);
...
...
nDisplacement = nToScroll * m_lineDev.cy;
...

with the following…

C++
...
int nDisplacement;
...
...
int nToScroll = ::MulDiv(-m_nAccumulatedDelta,
                             (uWheelScrollLines*m_lineDev.cy), WHEEL_DELTA);
...
...
nDisplacement = nToScroll * m_lineDev.cy;
...

If you do not have control at the pixel level in your development domain, see if you have control at the line level. If so, then the minimum delta required to scroll for your application will be WHEEL_DELTA (120) divided by the number of lines the user has selected scroll in the Control Panel for his mouse. This value is available through Unmanaged C++ with the following system call.

C++
::SystemParmetersInfo(SPI_GETWHEELSCROLLLINES, 0, &nWheelScrollLines, 0) ;

Finally, if you cannot choose your scroll granularity, then you just keep on accumulating the incoming delta values until WHEEL_DELTA is reached (so that for a given delta rotation, you get the same response as a standard wheel mouse).

Conclusion

With few modifications, you can create applications that give users much smoother scrolling experience when used with an enhanced scroll wheel.

References

  • B. Bederson and A. Boltman. Does animation help users build mental maps of spatial information? In Proc. INFOVIS’99, Washington, DC, USA, 1999.
  • A. Bezerianos, P. Dragicevic, and R. Balakrishnan. Mnemonic rendering: an image-based approach for exposing hidden changes in dynamic displays. In Proc. UIST’06, 159–168, 2006.
  • B.W. Chang and D. Ungar. Animation: from cartoons to the user interface. In Proc. UIST’93, 45–55, 1993.
  • F. Chevalier, P. Dragicevic, A. Bezerianos, and JD. Fekete. 2010. Using text animated transitions to support navigation in document histories. In Proceedings of the 28th international conference on Human factors in computing systems (CHI '10).
  • C. Klein and B. B. Bederson. Benefits of animated scrolling. In Proc. CHI’05, 1965–1968, 2005.
  • M. Shanmugasundaram and P. Irani. The effect of animated transitions in zooming interfaces. In Proc. AVI’08, 396–399, 2008

Revision History

  • February 8th, 2011: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Logitech Corporation
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Written By
Software Developer (Senior) Logitech Corporation
United States United States
Steve lives in Fremont, CA with his wife and daughter and has programmed in C and C++ for a very long time.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Abhinav S9-Mar-11 18:10
Abhinav S9-Mar-11 18:10 
GeneralMy vote of 5 Pin
DrABELL11-Feb-11 3:12
DrABELL11-Feb-11 3:12 
GeneralMy vote of 5 Pin
Snorri Kristjansson9-Feb-11 22:09
professionalSnorri Kristjansson9-Feb-11 22:09 
GeneralMy vote of 5 Pin
Hans Dietrich9-Feb-11 10:13
mentorHans Dietrich9-Feb-11 10:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.